是否有办法填写一个Excel工作簿,而不涉及Excel本身? 或者我可以强迫excel退出?

我最近的任务是创build一个网页,允许用户select一些数据,然后允许他们下载一个复杂的Excel工作簿(用macros完成),并将数据填入适当的单元格。 我给了一个.vbs作为填写excel工作簿的起点。 在.vbs中,原程序员调用

Set objExcel = CreateObject("Excel.Application") set ObjWorkbook =objExcel.Workbooks.Open(blankFile) `... objWorkbook.Saveas(outputFile) objExcel.Quit 

这对他来说工作得很好。 我试图使用C#和MVC做一个网页,所以我看着Excel.Application ,发现了一些半有用的东西,就像这个和这个 。 所以我开发了一个动作,只是为了testing一下,看起来像这样:

 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"); } 

(是的,我将不得不做一个计划的任务或东西来清除这些,因为我敢肯定,我不能只是得到一个字节stream的文件)

问题是,这不closuresexcel。 你明显在C#中做什么不是与一个理解excel工作簿格式的库进行交互,而是使excel自动化。 我将描述asinine。 我可以容忍它,只需要吸取它并在生产服务器上安装excel,但问题是,当我告诉它退出excel它不会退出。 它会询问用户是否要将更改保存到模板文档中。 这太糟糕了,我不知道这个页面有多less次会被使用,但是我认为这是不好的做法,不得不在服务器上多次点击“否”来释放内存。 那么我能绕过这一切吗? 有没有比COM对象更好的库Microsoft.Office.Interop.Excel? 或者我可以强迫excelclosures? 或者,我最好的办法就是写出所有在vb中的excel交互,并从控制器动作中调用它。

作为使用过Microsoft Excel互操作性库的用户,我很高兴您正在寻找替代scheme。

不要误解我的意思 互操作性库是非常有用的,如果你试图用less量的数据自动化一些简单的任务。 但是当涉及大量数据的时候,它的速度很慢。 如果你想要在Web服务器上使用,你也需要在服务器上安装Excel。

我build议你使用ClosedXML。 这是开源的,麻省理工学院许可。 这基本上是OpenXML的一个包装。 这也很容易使用,更快,并不需要在服务器上安装Excel

https://github.com/ClosedXML/ClosedXML

如果它要求您保存,那么这意味着它认为工作簿有未保存的更改。 只需closures工作簿,不要在退出之前保存更改:

 oWB.Close(false); 

您可能还需要closures第一个默认工作簿,实际上可能实际上是导致保存消息的工作簿。 查找另一个工作簿并closures它,而不保存。 就像是:

 oXL.Workbooks[0].Close(false); 

或者只是列举收集并closures所有这些。

这取决于Excel所处的实际状态。如果您不确定如何操作,请显示Excel而不是closures它,并尝试查看它认为未保存的内容,并决定是否要保存它,或者丢弃它。

这里有两个很好的答案,但是作为一个select,你也可以告诉Excel暂停警告。 每当你做一些通常会提示对话框的东西时,这很有帮助,比如在一个已经存在的文件上“另存为”。

Excel对象上的DisplayAlerts属性控制着这个属性,默认情况下是true。 将其更改为false将暂停警报,所以这也应该工作:

 application.DisplayAlerts = false; application.Quit(); application.DisplayAlerts = true; 

我build议你在这里采取不同的方法。 我将在Excel工作簿中创build一个选项卡,用户在其中input驱动数据select的选项。 然后编写一些脚本来使用这些设置从Web服务中提取数据。 以本文为例: https : //atinkerersnotebook.com/2012/12/28/creating-consuming-web-services-with-excel/

现在,您只需编写Web服务即可返回请求的数据。

我想build议一些不同的方式来生成一个Excel文件。 对于中等复杂的工作表,使用报表devise器来devise报表,然后将其导出到Excel文件更为容易。 它可以生成一个stream,你甚至不必生成一个文件。