本文转自:http://www.cnblogs.com/zhaojunqi/archive/2009/04/23/1442124.html
最近使用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);

}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)