C# 和 Excel 互操作

标签 c# excel interop

我的一位用户在尝试通过我的 C# 应用程序打开 Excel 文件时遇到问题。

当我从我的机器上运行它时,一切正常,它对其他用户也有效。我不是 Excel 互操作专家,所以希望你们能帮助我。

这是它的设置方式:

我在 Microsoft.Office.Interop.Excel.dll 版本 10.0.4504.0(我认为是 Excel 2002)中添加了对我的应用程序的引用。我的机器上安装了 Excel 2007。 在我的代码中,我尝试像这样打开一个工作表:

using Microsoft.Office.Interop
...
Microsoft.Office.Interop.Excel.ApplicationClass _excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = _excelApp.Workbooks.Open(workbookPath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", false, false, 0, true, false, false);
Microsoft.Office.Interop.Excel.Sheets excelSheets = excelWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item(1);

我将用户版本记录为 Excel 9.0(即 2000)。用户得到的错误是:

Exception='System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)

看起来无法打开工作簿。该文件已确认存在,只是松散地存在于用户 PC 的 C: 位置。我认为通过使用 PIA,我不必担心 Excel 版本问题。我知道还有其他用户在使用 Excel 2000,它可以在我的开发机器上运行。

有什么想法吗?也许我打开 Excel 文件的调用应该更改?不幸的是我无法重现它。

最佳答案

"I thought by using the PIA I wouldn't have to worry about Excel version issues. I know there are other users using Excel 2000, and it works on my dev machine."

几乎正确,但不完全正确。

通过针对 Excel 2002 的 PIA 进行开发,您的程序将兼容所有版本的 Excel 2002 (10.0) 及更高版本。然而,发生故障的机器运行的是 Excel 2000 (9.0),该版本低于您开发时所针对的版本。

在 Excel 2002 下没有官方支持的 PIA,因此如果您需要您的程序在 Excel 2000 (9.0) 上运行,那么您将必须创建自己的自定义互操作程序集。您可以使用 TlbImp.exe 为 Excel 9.0 创建互操作程序集,如文章 Achieving Backward Compatibility with .NET Interop: Excel as Case Study 中所述.

如果您的程序集具有强名称,那么您需要创建一个具有强名称的互操作程序集。这可以通过/keyfile 开关提供 .pfx 或 .snk 文件的名称来完成,如文章 How to create a Primary Interop Assembly (PIA) 中所示。 .该文章还利用/primary 开关来创建“主互操作程序集”。在您的情况下并不是真正需要使互操作程序集成为主要程序集,但不会造成伤害。但是,本文省略的是/sysarray 开关的使用,您应该使用它。

但是,制作强名称互操作程序集确实需要考虑一些复杂性。有关更多详细信息,请阅读 Using TLBIMP.exe to create Strong Named Interop Assemblies . (除其他事项外,本文还解释了/sysarray 开关的必要性。)

简而言之,如果您的程序集不是强命名的,则制作自定义互操作程序集非常简单。如果您的程序集具有强名称,则情况会更加复杂,因此您需要创建一个具有强名称的互操作程序集。但希望这些文章能让您继续前进。

-- 迈克

关于C# 和 Excel 互操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1111935/

相关文章:

vba - Excel VBA - 编译错误 - 需要对象

Java 应用程序窗口在 C# InterOp 中未被识别为 java 窗口

c# - 从 asp.net 中的代码隐藏函数调用 Javascript

c# - 我们可以在类中声明时初始化集合属性吗

c# - 如何在调用重方法之前使标签可见

xml - 用于商业文件交换(发票、采购订单等)的最佳标准是什么?

c# - Win32 类型如何在 C# P/Invoke 中表示?

c# - 设置 MVC 应用程序后访问被拒绝错误

python - 如何对 pandas 数据框列进行分组并将不同的组保存到同一 excel 文件中的多个工作表?

java - 使用poi读取Excel文件并将其转换为二维数组