最近使用VSTO做了一個小項目,其中有一個需求是將一個Excel工作表中的很多個帶格式的區域,分別另存到單獨的Excel文件中,要求保留源格式。
雖然需求很簡單,但也有幾個技術點要搞明白:
1.帶格式復制,但只復制值和格式,不復制公式,引用,校驗等等。
2.另存為Excel
第一個問題,開始我以為很簡單,直接使用選擇性粘貼,粘貼所有就行了,其實不是那麼簡單。開始使用如下代碼:
PasteSpecial
ws.get_Range(beginCell, pasteRange).PasteSpecial
(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteAll,
Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
Type.Missing, Type.Missing);
但發現復制出來的只是所有的值,格式都未復制出來。於是對Microsoft.Office.Interop.Excel.XlPasteType進行研究,發現有十幾個選項,逐個試驗,發現單獨使用任何一個枚舉都不能滿足我的要求。後來靈機一動,使用了兩次復制解決問題,一次復制值,一次復制格式!代碼如下:
PasteSpecial2
ws.get_Range(beginCell, pasteRange).PasteSpecial
(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteValues,
Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
Type.Missing, Type.Missing);
ws.get_Range(beginCell, pasteRange).PasteSpecial
(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats,
Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone,
Type.Missing, Type.Missing);
再說第二個問題,也不難,主要是不同的對象模型使用的保存方法不同(前面的wb對象是Microsoft.Office.Interop.Excel.Workbook對象,之前實驗過使用Microsoft.Office.Interop.Excel.ApplicationClass),經試驗,Workbook對象的SaveCopyAs方法非常理想,因為它不會彈出任何對話框,自動覆蓋之前存在的同名文件。
下面列出完整代碼:
CommandBarButton
void creatCommand_Click(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool
CancelDefault)
{
//開啟一個新的Excel進程,但不顯示
Clipboard.Clear();
Globals.Sheet1.Application.ScreenUpdating = false;
Microsoft.Office.Interop.Excel.Application app = new
Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
//循環復制並另存為
for (int i = 1; i < 14; i++)
{
//獲得保存文件名和復制區域
Globals.Sheet10.Range["O1", Type.Missing].Value2 = i;
string fileName = Globals.ThisWorkbook.Path + Utility.CreatFileName
(Globals.Sheet1.Range["B5", Type.Missing].Value2.ToString(), Globals.Sheet3.Range["B2",
Type.Missing].Value2.ToString(), Globals.Sheet1.Range["C5", Type.Missing].Value2.ToString
());
string strpasterange= Utility.SelectAndCopyRange("B",5,9,"N",22);
//另存為方法
Utility.CreatAndPaste(app,strpasterange,"B5",fileName);
}
//關閉Excel進程
Globals.Sheet1.Application.ScreenUpdating = true;
app.Quit();
MessageBox.Show("Success!");
}
Utility.SelectAndCopyRange方法是復制指定區域,代碼很簡單,核心代碼就一句:
Globals.Sheet1.Range[beginCell+beginCellNamber.ToString(), strPasteRange].Copy
(Type.Missing);
Utility.CreatAndPaste方法是另存為的:
CreatAndPaste
public static void CreatAndPaste(Excel.Application app,string pasteRange,string beginCell,string fileName)
{
//使用新的Excel進程添加一個新的工作簿
Microsoft.Office.Interop.Excel.Workbook wb = app.Workbooks.Add(Type.Missing);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets[1];
//粘貼
ws.get_Range(beginCell, pasteRange).PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteValues, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, Type.Missing, Type.Missing);
ws.get_Range(beginCell, pasteRange).PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, Type.Missing, Type.Missing);
ws.get_Range(beginCell, pasteRange).Columns.AutoFit();
//保存
wb.SaveCopyAs(fileName);
//關閉工作簿
Clipboard.Clear();
wb.Close(false, Type.Missing, Type.Missing);
}