陳端迎 劉寶華 張桂平
摘要:為了方便快捷使用COM組件技術進行基于ASP.NET程序構架的軟件開發(fā),使ASP.NET無縫結合COM組件,研究了ASP. NET引用COM組件的原理和方法,并且介紹了ASP.NET程序如何引用COM組件、配置COM組件的權限以及使用EXCEL的COM組件操作EXCEL表格的具體方法,最后使用實例來說明常用操作的實現(xiàn)方法。
關鍵詞:COM組件;ASP.NET;公共語言運行庫;EXCEL;權限設置
中圖分類號:TP311文獻標識碼:A文章編號:1009-3044(2012)22-5334-03
ASP.NET Using Com Components Processing Excel Form
CHEN Duan-ying, LIU Bao-hua, ZHANG Gui-ping
(Lianyungang Jari DeepSoft, Lianyungang 222006, China)
Abstract: To use convenient COM components technology based on ASP asp.net application architecture of the software development, make the asp.net seamless combined with COM components, the ASP.NET quoted the principle and method of COM components, and introduces the ASP.NET application of how to reference COM components, the configuration of the access and use COM components of the excel COM components excel the concrete method of operation form and finally with examples to illustrate the implementation method of the common operations.
Key words: com components; ASP.NET; common language runtime;EXCEL; permission settings
COM對象一直是Windows編程的基礎,隨著技術的進步和發(fā)展,微軟推出了更加出色的.NET。.NET Framework提供了一個稱為公共語言運行庫的運行時環(huán)境(CLR),它的托管執(zhí)行過程,自動的內存管理,以及在版本的控制上都較COM技術有很大的提高。在向.NET過渡時,還需要繼續(xù)使用現(xiàn)有的COM對象。
1 ASP.NET引用COM組件的原理
.NET Framework的核心是公共語言運行庫。公共語言運行庫通過名為運行庫可調用包裝(RCW)的代理來公開COM對象[1],如圖1所示。雖然RCW在.NET客戶端看來是普通的對象,但它的主要功能是封送在.NET客戶端和COM對象之間傳遞的調用。同時. NET提供Interop程序集,它用作托管和非托管代碼之間的橋梁,將COM對象成員映射為等價的.NET托管成員。
圖1通過運行庫可調用包裝來訪問COM對象
操作Excel表格最直接的方法就是利用Excel提供的Excel Object Library COM組件,并將包裝后的程序集叫做“互操作程序集”(Primary Interop Assembly, PIA)。
下面介紹ASP.NET引用COM組件,設置權限和處理Excel表格的各種典型操作,如編輯表格、保存表格等,以及從二維數(shù)組中向Excel表格快速導入數(shù)據(jù)的實現(xiàn)方法。
2 ASP.NET引用COM組件的方法
建立ASP.NET工程,添加引用COM組件“Microsoft Excel 11.0 Object Library”,如圖2所示。前提是計算機上安裝了Microsoft Office的Excel軟件,該文例子所使用的是Office2003。引用過程就是RCW的打包過程,.NET自動創(chuàng)建PIA,也可以通過.NET提供的工具Tlbimp.exe手動創(chuàng)建PIA。
圖2引用COM組件
3 COM組件的權限設置
在ASP.NET中使用EXCEL需要對COM組件的權限進行設置,如果未設置權限,則會報訪問拒絕的錯誤。ASP.NET有一個在應用程序沒有模擬時使用的基進程標識(通常,在IIS 5上為{MACHINE}ASPNET,在IIS 6上為網(wǎng)絡服務)。如果應用程序正在通過< identity impersonate="true"/>模擬,則標識將為匿名用戶(通常為IUSR_MACHINENAME)或經(jīng)過身份驗證的請求用戶。若要授予ASP.NET對文件的寫訪問權,需要在資源管理器中右擊該文件,選擇“屬性”,然后選擇“安全”選項卡。單擊“添加”按鈕添加ASP. NET帳戶,選中所需訪問權限對應的選擇框。
設置Excel的COM組件權限的方法是先啟動組件服務,找到并打開DCOM配置,在“Microsoft Excel應用程序”組件屬性的“安全”標簽中,在“啟動和激活權限”區(qū)域點擊“自定義”,然后點擊對應的“編輯”按鈕,在彈出的“安全性”對話框中添加一個“NETWORK SERVICE”用戶,并給它賦予“本地啟動”和“本地激活”權限;在“訪問權限”區(qū)域點擊“自定義”,然后點擊“編輯”,在彈出的“安全性”對話框中也添加一個“NETWORK SERVICE”用戶,然后賦予“本地訪問”權限;在“配置權限”區(qū)域點擊“自定義”,分別添加ASPNET、IUSR、IWAM等用戶的讀取和完全控制權限;在“標識”標簽中,選擇“交互式用戶”,至此,COM組件的權限設置操作完成。
4 ASP.NET處理Excel表格的基本操作及其實現(xiàn)方法
通過下列例子介紹ASP.NET處理Excel表格的方法。本例的流程是這樣的:先建立ASP.NET工程,在其工程根目錄下手動創(chuàng)建EXCEL模板即excel.xls文件,客戶端請求后,服務器端程序打開模板并根據(jù)需要進行賦值,本例將會在excel表格的第一行填寫單元格的位置坐標,合并從第二行到第六行,從第一列到第五列的這部分區(qū)域,給其賦值為“圖片”,根據(jù)值為“圖片”的區(qū)域加載一張圖片,然后將其以時間戳為名稱進行另存后關閉Excel進程,最后客戶端顯示生成的Excel表格。實現(xiàn)步驟如下:
1)打開EXCEL模板文檔
string excelFilePath = HostingEnvironment.MapPath(@"~/") + "excel.xls";
Excel.Application myExcel = new Excel.ApplicationClass();
object oMissing = System.Reflection.Missing.Value;
myExcel.Application.Workbooks.Open(excelFilePath, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMiss? ing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);
Excel.Workbooks myBooks = myExcel.Workbooks;
Excel.Workbook myBook = myBooks.Add(oMissing);
Excel.Worksheet mySheet = (Excel.Worksheet)myBook.Worksheets[1];
2)合并第二行到第六行,第一列到第五列的區(qū)域單元格,并賦值“圖片”字符
int x = mySheet.UsedRange.Rows.Count;
int y = mySheet.UsedRange.Columns.Count;
Excel.Range m_objRange = mySheet.get_Range(mySheet.Cells[2, 1], mySheet.Cells[6, 5]);
m_objRange.Merge(oMissing);
m_objRange.Value2 = "圖片";
在實際使用中需要合并的區(qū)域可以靈活設置。
3)給第一行的一至五列單元格賦值
for (int n = 1; n <= 5; n++)
{mySheet.Cells[1, n] = "1," + Convert.ToString(n);}
4)給內容為“圖片”的區(qū)域加載一張圖片
如果不知道加載圖片的區(qū)域在哪里,就需要使用循環(huán)語句遍歷每個單元格查找,直至“mySheet.get_Range(mySheet.Cells[m, n],mySheet.Cells[m, n]) .Value2.ToString()=="圖片"”,EXCEL表格的Worksheets最多有65536行255列。圖片所在的位置為[2,1],[6,5],使用如下代碼加載圖片:
string excelFilePath = HostingEnvironment.MapPath(@"~/") + "excel.xls";
Excel.Range ss = mySheet.get_Range(mySheet.Cells[2, 1], mySheet.Cells[6, 5]);
ss.Select();
float PicLeft, PicTop, MyWidth, MyHeight;
PicLeft = Convert.ToSingle(ss.MergeArea.Left) + 3;
PicTop = Convert.ToSingle(ss.MergeArea.Top) + 3;
MyWidth = Convert.ToSingle(ss.MergeArea.Width) - 3;
MyHeight = Convert.ToSingle(ss.MergeArea.Height) - 3;
ss.MergeArea.Borders.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
mySheet.Shapes.AddPicture(MyFileName, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoTrue, PicLeft, PicTop, MyWidth, MyHeight);
5)另存EXCEL文件
將已經(jīng)編輯過的模板文件以時間戳作為新的文件名另存到服務器硬盤,客戶端對文件進行下載查看,代碼如下:
string pathstr = HostingEnvironment.MapPath(@"~/public/");
string tempfilenname = DateTime.Now.Ticks.ToString() + ".xls";
myBook.SaveAs(pathstr + tempfilenname, oMissing, oMissing, oMissing, oMissing, oMissing,Excel.XlSaveAsAccessMode.xlExclusive, oMissing, oMissing, oMissing, oMissing, oMissing);
myBook.Close(true, pathstr + tempfilenname, oMissing);
myExcel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(myBook);
myBook = null;
6)關閉Excel進程,回收內存
Process[] pProcess;
pProcess = System.Diagnostics.Process.GetProcessesByName("EXCEL");
pProcess[0].Kill();
GC.Collect();
7)客戶端顯示生成的Excel文件
以文件流的方式下載并顯示生成的Excel文件,下面是函數(shù)代碼:
public static void OUTEXCEL(HttpResponse response, string designerFile, string filename, HttpRequest request)
{
FileStream fileStream = File.Open(designerFile, FileMode.Open);
byte[] mydata = new byte[fileStream.Length];
fileStream.Read(mydata, 0, (int)fileStream.Length);
response.Clear();
response.Buffer = false;
response.CacheControl = "Private";
response.AppendHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(filename) + ".xls");
response.ContentType = "ms-excel";
response.BinaryWrite(mydata);
response.Flush();
response.Close();
}
5 ASP.NET導入數(shù)據(jù)到Excel表格
使用二維數(shù)據(jù)組可以批量將其中所有的數(shù)據(jù)一次性導入到Excel表格[2],這樣可以加快數(shù)據(jù)的導入速度。例如先定義一個十行十列的數(shù)組對象object[,] arrData = new object[10, 10],數(shù)據(jù)已經(jīng)讀入到數(shù)組中,下面代碼為將數(shù)組中數(shù)據(jù)導入到Excel表格:
Excel.Range range = mySheet.get_Range("A1", oMissing);
range = range.get_Resize(10, 10);
range.Value2 = arrData;
range.EntireColumn.AutoFit();
Excel表格的CELL中的插入的字符長度不應超過911個,否則會出現(xiàn)“用戶代碼未處理comException異常來自HRESULT: 0x800A03EC”的錯誤,這是使用此種方法的一個弊端。在實際使用中需要對大數(shù)據(jù)進行特殊處理,后期單獨賦值,但這樣會降低數(shù)據(jù)的導入效率。
6結束語
COM組件是一種現(xiàn)成的豐富資源,當.Net FrameWork SDK無法有效解決問題時,借助COM可能就是一條捷徑。文章通過實用的示例介紹了ASP.NET處理Excel表格的各種典型操作的實現(xiàn),并能夠完成將二維數(shù)組中的數(shù)據(jù)快速導入到Excel表格。希望該文能夠對讀者掌握在ASP.NET中COM組件的使用方法有所幫助。
參考文獻:
[1]微軟公司.MSDN Library For Visual Studio[Z].2005.
[2]羅斌,羅順文. VisualC#2005編程技巧與大全[M].北京:中國水利水電出版社,2007.