如果您使用的是 .NET 3.5,则不能使用dynamic
关键字。您唯一的选择是使用@Francesco 所述的一系列代理类(手动编写或自动生成)。但是如果您需要访问大量 Excel 类/函数/属性,手动方法确实很麻烦。您必须为您需要的每个成员编写一个函数/属性代理。
管理这一点的关键是,您无需编写大量代理函数,而是将所有处理 Excel 的代码放在一个单独的软件层(类似于数据访问层,DAL)中,放在不同的库项目中。该层只是为应用程序提供了一些高级接口(只有几个成员函数),因此应用程序甚至不知道 MS Excel 自动化的使用。
请注意,即使您不想动态加载程序集,Excel 访问代码的这种封装也是一种很好的做法。例如,如果您觉得 Office 自动化令人沮丧,您可以很容易地用另一种技术(如 ADO.NET)替换它,该技术带有Microsoft.ACE.OLEDB.12.0
用于读取/写入 Excel 文件的提供程序,您也会发现在 x64 平台中也令人沮丧!
例如,如果您想从 Excel 文件中获取工作表和数据,您可以在名为的项目中提供以下接口,例如Utils.OfficeAutomation
(不引用Microsoft.Office.Interop.Excel.dll
):
interface IExcelLayer {
...
bool ImportFrom(string fileName, string sheetName, out object[,] cells, bool skipHeaderRow = true);
// a few other members...
...
}
然后在一个名为 say 的单独项目中实现它,该项目Utils.OfficeAutomation.Impl
同时引用Utils.OfficeAutomation
和 real Microsoft.Office.Interop.Excel.dll
:
class ExcelMagician : IExcelLayer {
...
bool ImportFrom(string fileName, string sheetName, out object[,] cells, bool skipHeaderRow = true)
{
Excel.Application excelApp = new Excel.Application()
...
}
...
}
主应用程序仅对Utils.OfficeAutomation
. 作为回报,Utils.OfficeAutomation
它以某种方式负责动态查找和加载Utils.OfficeAutomation.Impl
,或者在出现问题时生成错误:
IExcelLayer m_instance = null;
...
try
{
Assembly assembly = Assembly.Load("Utils.OfficeAutomation.Impl");
Type excelType = assembly.GetType("Utils.OfficeAutomation.Impl.ExcelMagician");
m_instance = (IExcelLayer) Activator.CreateInstance(excelType);
}
catch (Exception e)
{
throw new Exception("Couldn't load Excel assembly.")
}
如果未安装适当版本的 Microsoft Excel,则加载程序集会Utils.OfficeAutomation.Impl
失败,或者调用类似的成员会ImportFrom
生成异常。
您最终需要在内部编写包装类Utils.OfficeAutomation
作为 Excel 访问层或 Excel 功能的网关。