【发布时间】:2016-01-04 13:16:28
【问题描述】:
我正在通过组合一系列不同 Excel 工作簿的第一张工作表在 c# 中构建一个新的 Excel 工作簿;随后我将新工作簿导出为 PDF。我完成了这项工作,但在方法结束时总是有一个 Excel 实例在运行。
我遇到了与here 讨论过的相同问题,设置更简单,Excel 对象更少,我可以使用 GC.Collect 命令解决这些问题。现在,这些都不起作用。
public void CombineWorkBooks()
{
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp.DisplayAlerts = false;
xlApp.Visible = false;
Workbooks newBooks = null;
Workbook newBook = null;
Sheets newBookWorksheets = null;
Worksheet defaultWorksheet = null;
// Create a new workbook, comes with an empty default worksheet");
newBooks = xlApp.Workbooks;
newBook = newBooks.Add(XlWBATemplate.xlWBATWorksheet);
newBookWorksheets = newBook.Worksheets;
// get the reference for the empty default worksheet
if (newBookWorksheets.Count > 0)
{
defaultWorksheet = newBookWorksheets[1] as Worksheet;
}
// loop through every line in Gridview and get the path' to each Workbook
foreach (GridViewRow row in CertificadosPresion.Rows)
{
string path = row.Cells[0].Text;
string CertName = CertificadosPresion.DataKeys[row.RowIndex].Value.ToString();
Workbook childBook = null;
Sheets childSheets = null;
// Excel of each line in Gridview
childBook = newBooks.Open(path,Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
childSheets = childBook.Worksheets;
if (childSheets != null)
{
// Build a new Worksheet
Worksheet sheetToCopy = null;
// Only first Worksheet of the Workbook belonging to that line
sheetToCopy = childSheets[1] as Worksheet;
if (sheetToCopy != null)
{
// Assign the Certificate Name to the new Worksheet
sheetToCopy.Name = CertName;
// set PageSetup for the new Worksheet to be copied
sheetToCopy.PageSetup.Zoom = false;
sheetToCopy.PageSetup.FitToPagesWide = 1;
sheetToCopy.PageSetup.FitToPagesTall = 1;
sheetToCopy.PageSetup.PaperSize = Microsoft.Office.Interop.Excel.XlPaperSize.xlPaperA4;
// Copy that new Worksheet to the defaultWorksheet
sheetToCopy.Copy(defaultWorksheet, Type.Missing);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(sheetToCopy);
childBook.Close(false, Type.Missing, Type.Missing);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(childSheets);
System.Runtime.InteropServices.Marshal.ReleaseComObject(childBook);
}
//Delete the empty default worksheet
if (defaultWorksheet != null) defaultWorksheet.Delete();
//Export to PDF
newBook.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF, @"C:\pdf\" + SALESID.Text + "_CertPres.pdf", 0, false, true);
newBook.Close();
newBooks.Close();
xlApp.DisplayAlerts = true;
DownloadFile(SALESID.Text);
System.Runtime.InteropServices.Marshal.ReleaseComObject(defaultWorksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(newBookWorksheets);
System.Runtime.InteropServices.Marshal.ReleaseComObject(newBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(newBooks);
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
GC.Collect();
GC.WaitForPendingFinalizers();
}
protected void DownloadFile(string Salesid)
{
string path = @"c:\\pdf\" + Salesid + "_CertPres.pdf";
byte[] bts = System.IO.File.ReadAllBytes(path);
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Type", "Application/octet-stream");
Response.AddHeader("Content-Length", bts.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + Salesid + "_CertPres.pdf");
Response.BinaryWrite(bts);
Response.Flush();
Response.End();
}
该问题一定与 DownloadFile 方法的调用有关。我取消了那个调用,并且 Excel 进程被正确关闭。其中一些操作必须保持对其中一个 COM 对象的引用处于打开状态,因此它们无法关闭。通过在 GarbageCollect 之后的最后调用“DownloadFile”,问题得到解决。 (我不太清楚为什么)
【问题讨论】:
-
你试过杀死那个excel进程msdn.microsoft.com/en-us/library/…
-
您是否阅读过stackoverflow.com/questions/158706/… 并尝试了那里的所有方法?如果是,请创建minimal reproducible example 来重现该问题(您的代码很短,但显然还不是最小的)。
-
@Ali Hasan:杀死进程应该是最后的资源;我正在与可能的当代用户一起运行一个 Web 应用程序,因此杀死任何 excel 实例都不是一个好的解决方案。
-
@Heinzi:我仔细检查了该链接中已详细解释的 2 点规则。构建一个最小的示例使我找到了解决方案,也非常感谢您:删除 DownloadFile 调用使 Excel 进程消失!
-
@Barnabeck:是的,极少的例子有时会对你产生影响。 ;-) 下载文件?但是为什么...啊,现在我明白了为什么会发生这种情况。我会写一个关于它的答案。