【发布时间】:2019-05-03 20:52:04
【问题描述】:
我正在创建一个网页来选择数据以下载 Excel 工作簿(包含宏),并将该数据填充到相应的单元格中。
我得到了一个 .vbs 作为填写 Excel 工作簿的起点。
.vbs中,原程序员调用
Set objExcel = CreateObject("Excel.Application")
set ObjWorkbook =objExcel.Workbooks.Open(blankFile)
`...
objWorkbook.Saveas(outputFile)
objExcel.Quit
我正在尝试使用 C# 和 MVC 制作网页,因此我查看了 Excel.Application 并找到了 this 和 this。我开发了一个动作,只是为了测试一下:
public FileResult filledOutWorkbook()
{
Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet oSheet;
Excel.Range oRng;
oXL = new Excel.Application();
oXL.Visible = false;
oWB = oXL.Workbooks.Open(Server.MapPath("~/Content/Worksheet2.xlsm"));
oSheet = oWB.Sheets["Information Sheet"];
oSheet.Range["V2"].Value2 = "customer test lol";
if (!Directory.Exists(Server.MapPath("~/App_Data/temp")))
{
Directory.CreateDirectory(Server.MapPath("~/App_Data/temp"));
}
var filename = Server.MapPath("~/App_Data/temp/") + DateTime.Now.ToString("o").Replace(":", "") + ".xlsm";
oWB.SaveCopyAs(filename);
oXL.Visible = false;
oXL.Quit();
return File(filename, "application/vnd.ms-excel.sheet.macroEnabled.12", "Worksheet.xlsm");
}
(我将执行计划任务或其他事情来清除这些,因为我很确定我不能只获取文件的字节流。)
问题是,这不会关闭 Excel。显然 C# 没有与理解 Excel 工作簿格式的库进行交互,您正在自动化 Excel。我会在生产服务器上安装 Excel,但是当我告诉它退出 Excel 时,它并没有退出。它询问用户是否要保存对模板文档的更改。我不知道这个页面会被使用多少次,但我认为在服务器上多次单击“否”以释放内存是一种不好的做法。
我可以绕过这个吗?有没有比 COM 对象 Microsoft.Office.Interop.Excel 更好的库?我可以强制 Excel 关闭还是最好的办法是在 VB 中编写所有 Excel 交互并从控制器操作中调用它?
【问题讨论】:
-
您是否尝试过强制关闭而不保存?在
oXL.Quit();之前尝试WB.Close(false); -
你从未释放你获得的 COM 对象。除非您这样做,否则 excel 将永远不会完全退出
-
@Steve 设置对
null的引用,使用GC.Collect,并调用Quit就足以清理Excel。 -
@DaveCousineau 并非总是如此。你可能会以这种方式遇到内存损坏。过去有过这种经历
-
@Steve“内存损坏”?我有几十个应用程序可以毫无问题地执行此操作。