2012-09-27 106 views
1

我需要动态加载程序集。目前我正在使用“Microsoft.Office.Microsoft.Office.Interop.dll”。我需要打开一个excel文件并获取表单和数据。谁能告诉我,我该怎么做?动态加载程序集

Assembly SampleAssembly = Assembly 
      .Load("Microsoft.Office.Interop.Excel, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); 

if (SampleAssembly != null) 
{ 
    Type type = SampleAssembly.GetType("Microsoft.Office.Interop.Excel.ApplicationClass"); 
    Object AppClass = Activator.CreateInstance(type); 

    //How will I get ApplicationClass object and Workbooks objects here? 
} 
+1

似乎你使用.NET 3.5而不是.net 4? –

+0

此外,请检查此解决方法:http://www.codeproject.com/Articles/10888/SafeCOMWrapper-Managed-Disposable-Strongly-Typed-s –

回答

0

这里是你如何做到这一点在C#中的dynamic

using Microsoft.Office.Interop.Excel; 
Type type = SampleAssembly.GetType("Microsoft.Office.Interop.Excel.ApplicationClass"); 
var application = Activator.CreateInstance(type); 
var workbook = application.Workbooks.Open(fileName); 
var worksheet = workbook.Worksheets[1] as Microsoft.Office.Interop.Excel.Worksheet; 
+0

我需要动态加载程序集并调用方法。 – sharmila

+0

是的,我在运行时加载了程序集。现在我需要访问程序集的属性 – sharmila

+0

我对代码进行了编辑,看看它是否工作 –

3

利用:

Type type = SampleAssembly.GetTypes().Single(t => t.Name == "ApplicationClass"); 
dynamic appClass = Activator.CreateInstance(type); 

var workbook = appClass.Workbooks.Open("C:\\test.csv"); 
var worksheet = workbook.Worksheets[1]; 
+0

嗨,我收到以下错误:错误预定义类型'Microsoft.CSharp.RuntimeBinder.Binder'未定义或进口。和2.编译动态表达式所需的一个或多个类型无法找到。您是否缺少对Microsoft.CSharp.dll和System.Core.dll的引用? – sharmila

+0

@sharmila:奇怪,您使用的是哪个版本的.NET?和异常抛出哪一行? –

+0

我正在与asp.net应用程序和错误是因为缺少microsoft.csharp dll。我不能在.net程序集中找到这个DLL(添加引用) – sharmila

2

如果你不能/不想使用动态,我会定义一个带有一个接口(或一组接口)的项目,暴露你需要使用的excel方法/对象,并且你可以在你的代码中引用,而不需要任何实际的excel dll。然后在一个不同的项目中实现它,这个项目引用了excel并且将被动态加载。

事情是这样的:

public interface IExcelApp 
{ 
    IExcelWorkbook OpenWbk(string aPath); 
    // other stuff 
} 

public interface IExcelWorkbook 
{ 
    //the stuff you need 
} 

的实现(一个项目,我叫比如ExcelBridge):

public class ExcelApp : IExcelApp 
{ 
    private ApplicationClass _app; 

    public ExcelApp() 
    { 
    } 

    public IExcelWorkbook OpenWbk(string aPath) 
    { 
     return new ExcelWorkbook(_app.Workbooks.Open(aPath)); 
    } 
} 

public class ExcelWorkbook : IExcelWorkbook 
{ 
    private Workbook _wbk; 

    public ExcelWorkbook(Workbook aWbk) 
    { 
     _wbk = aWbk; 
    } 
} 

那么你的代码可能是这样的:

Assembly SampleAssembly = Assembly.Load("ExcelBridge", Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"); 

if (SampleAssembly != null) 
{ 
    Assembly YourExcelAssembly = Assembly.Load("ExcelBridge.dll"); 
    Type type = YourExcelAssembly .GetType("ExcelApp"); 
    IExcel AppClass = Activator.CreateInstance(type) as IExcelApp; 

    //now you can write: 
    IExcelWorkBook aWbk = AppClass.Open("your xls path"); 
} 
0

如果您使用.NET 3.5,则不能使用dynamic关键字。您唯一的选择是使用@Francesco所描述的一系列代理类(手动编写或自动生成)。但是,如果您需要访问大量Excel类/函数/属性,手动方法非常麻烦。你必须为你需要的每个成员编写一个函数/属性代理。

管理这一点的关键在于,不是编写大量的代理函数,而是将处理Excel的所有代码放在放置在不同库项目中的单独软件层(如数据访问层,DAL)中。该层仅向应用程序提供一些高级接口(只有少数成员函数),以至于应用程序甚至不知道MS Excel自动化的用法。

请注意,即使您不想动态加载程序集,此封装的Excel访问代码也是一种很好的做法。例如,如果您发现令人沮丧,您可以使用另一种技术(如ADO.NET)轻松替换Office Automation,并使用Microsoft.ACE.OLEDB.12.0提供商reading from/writing to Excel files,这在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... 
    ... 
} 

然后实现它命名为一个单独的项目,说Utils.OfficeAutomation.Impl,其中引用了两个Utils.OfficeAutomation和真实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() 
     ... 
    } 
    ... 
} 

迈n应用程序仅提供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 Access Layer或Excel功能的网关。