2012-09-27 102 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功能的網關。