【发布时间】:2020-04-15 23:06:50
【问题描述】:
我目前在 .NET 中使用 COM Interop 将 DataTable 的内容导出到 Excel。这是我多年来一直使用的一种方法,但问题是 COM 是粗略的,并且会引发随机、间歇性、无法追踪的异常。这不是一个大问题,因为它一直只是专门用于此目的的机器上的代码,并且异常很少见,但最近我为数据仓库编写了一个前端,我有 200 多个用户它,并且问题(如您所料)呈指数级增长。
问题是要找到一种方法来完成 COM 所做的工作,而不会出现 COM 带来的问题。即,在内存中创建一个 Excel 文件(不写入磁盘),它是一个新工作簿,这样当用户第一次点击“保存”时,它会询问他们要将文件保存在哪里以及他们想要什么调用它。
我知道我可以使用 OpenXML 将 DataTable 导出到 Excel 文件:Export DataTable to Excel with Open Xml SDK in c#
而且我知道我可以在内存中创建一个 OpenXML Excel 对象,而无需写入磁盘上的文件:How to create Excel file using OpenXML without creating a local file?
问题是最后一步:在 Excel 中打开内存中的文件(不使用 COM)
让它发挥作用将是我的理想选择。
现在,我不希望写入文件,但如果没有其他选项,这不会破坏交易,因此作为备份选项,我还考虑使用 OpenXML 创建 Excel 模板,然后打开模板(使用 Process.Start)。
这种方法的问题在于,一些用户报告说,模板有时会在编辑模式下默认打开为 xltx 文件,而不是作为新的 xlsx 文件打开:https://answers.microsoft.com/en-us/office/forum/office_2007-customize/is-there-a-way-to-get-my-excel-template-xltx-file/ab36cd4d-f6b0-46e0-8f15-533a4acb357f?page=1
这将是一个比我使用 COM 得到的随机错误更大的问题。
感谢任何想法。
编辑 - 这些是我得到的 COM 错误:
无法创建 ActiveX 组件。
COM 目标没有实现 IDispatch。
HRESULT 异常:0x800AC472
Range类的Select方法失败
操作不可用(HRESULT 异常:0x800401E3 (MK_E_UNAVAILABLE))
消息过滤器指示应用程序正忙。 (来自 HRESULT 的异常:0x8001010A (RPC_E_SERVERCALL_RETRYLATER))
远程过程调用失败。 (HRESULT 异常:0x800706BE)
无法将“System.__ComObject”类型的 COM 对象转换为接口类型“System.Collections.IEnumerable”。此操作失败,因为 IID 为“{496B0ABE-CDEE-11D3-88E8-00902754C43A}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:“请求的对象不存在。 (来自 HRESULT 的异常:0x80010114)'并且 COM 组件不支持对 DISPID_NEWENUM 的 IDispatch::Invoke 调用。
无法获取 Workbooks 类的 Add 属性
Workbook 类的激活方法失败
在几个月的时间里,我收到了 107 个错误,但最近我收到了更多错误,因为我更新了该功能以附加到用户可能已经打开的任何现有 Excel 实例,而不是创建一个新实例.以前,当我每次都创建一个新的 Excel 实例时,错误要少得多(在我做幕后工作时,通过使 Excel 不可见在很大程度上得到了解决)。
【问题讨论】:
-
这并不能真正回答您的问题,但您可以尝试将文件保存到临时位置并在文件系统中将其设置为只读。这将迫使您的用户执行 SaveAs 而不是 Save。您可能可以在启动应用程序时玩“当前工作目录”游戏,这样当他们去保存它时,它们就在正确的位置(我不知道这是否可行)。
-
我不确定你的架构到底是什么,但我会咬 - 什么是 COM 错误?
-
COM 本身不会引发随机错误,您说这就像生活中的事实一样。也许您可以先尝试解决此问题,或者了解为什么会出现错误。
-
我多年来一直使用 Office.Interop.Excel 没有问题。您应该尝试找出为什么会出现异常。也就是说,这些天我更喜欢 EPPlus(v4 仍可免费用于商业用途)。
-
当您启动 Excel 时,您可以传入一个 xlsx 文件名并通过设置适当的命令行参数说“将其用作模板”:support.office.com/en-us/article/…
标签: c# excel vb.net openxml com-interop