我正在为excel写一个VSTO。我有以下问题:所有这一切都在excel应用程序中
我需要以编程方式添加一个必须与模板相同的新工作表。我有一个模板,我可以从中复制单元格和格式化到新添加的单元格。
我怎样才能做到这一点?
我尝试了以下方法,打开一个excel应用程序,使其对用户不可见,并在该应用程序中打开必要的模板。我正在浏览已使用的范围行并尝试逐行复制。但是,我在打开模板时遇到问题。一旦它被打开,另一次它抛出COM异常(不知道是什么类型)。
var activeExcel = (Workbook)Globals.ThisAddIn.Application.ActiveWorkbook;
Sheet = (Worksheet) activeExcel.Worksheets.Add();
Sheet.Name = "Счёт-фактура";
var sourcePath = LocationHelperTool.GetTemplatePathByName("SystemInvoice.xlsx");
try
{
var excelApp = new Application() { Visible = false };
var workbook = excelApp.Workbooks.Open(sourcePath);
var workSheets = workbook.Worksheets;
const string sourceSheetName = "Счёт-фактура";
var sourceSheet = (Worksheet)workSheets.Item[sourceSheetName];
var sourceRange = sourceSheet.UsedRange;
for (var i = 1; i <= sourceRange.Rows.Count; i++)
{
var soRange = sourceRange.Rows[i];
var deRange = Sheet.Rows[i];
soRange.Copy(Type.Missing);
deRange.pasteSpecial(XlPasteType.xlPasteFormats);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Clipboard.Clear();
excelApp.Quit();
}
我想在用户正在进行交互的excel实例中打开一个新工作表,该工作表应该是模板的精确克隆
代码只运行一次的原因似乎是因为它实例化的COM对象没有被释放 - 所以它们不能被重用:
var excelApp = new Application() { Visible = false };
var workbook = excelApp.Workbooks.Open(sourcePath);
var workSheets = workbook.Worksheets;
const string sourceSheetName = "Счёт-фактура";
var sourceSheet = (Worksheet)workSheets.Item[sourceSheetName];
在清理这段代码时,你需要沿着这些方面的东西,其中对象以它们被实例化的相反顺序释放(当后者依赖于前面的时候)。然后需要对释放的对象进行垃圾收集,以确保代码不再“看到”它们。
sourceRange = null;
soRange = null;
deRange = null;
workbook.Close(false); //do not save changes
sourceSheet = null;
workSheets = null;
workbook = null;
excelApp.Quit();
excelApp = null;
GC.Collect();
GC.AwaitPendingFinalizers();
GC.Collect();
GC.AwaitPendingFinalizers();