Asp.net下C#自動化調用Word的執行個體與總結

來源:互聯網
上載者:User

摘 要:本文通過一個實用例子完整示範了如何使用C#在ASP.NET裡調用Word、自動化Word,並且總結了實際應用中發現的問題,最後提出了有效解決方案。

關鍵詞:ASP.NET; C#; Word; 自動化; VBA; COM; 死進程;

原文地址:http://hi.baidu.com/officeworkspace/blog/item/3a673109582badd763d98667.html

1. 建立工程

在ASP.NET裡操作Word的第一步就是添加COM引用到你的工程裡,通過右鍵點擊“方案總管”的“引用”,添加引用。選擇COM選項卡,添加Microsoft Word 12.0 Object Library(其中12.0是Word版本號碼,根據當前電腦上安裝的Word版本確定)。 ASP.Net會自動產生Word的COM封裝類程式集添加到應用程式目錄裡。

2. 代碼邏輯

在伺服器端訪問本地存在的Word檔案,並根據他建立一個檔案,利用Word的標籤定位賦值。用戶端瀏覽器通過檔案連結訪問到這個新產生的Word檔案。

具體代碼如下:

private void Page_Load(object sender, System.EventArgs e)

{

// 在此處放置使用者代碼以初始化頁面

object Missing = Type.Missing;

//取得Word檔案路徑

string strTemp = "doc/test.doc";

//新Word檔案儲存路徑

string newFileName = "doc/test2.doc";

//建立一個名為WordApp的組件對象

Application WordApp = new ApplicationClass();

//必須設定為不可見

WordApp.Visible = false;

try

{

//建立以strTemp為模板的文檔

object oTemplate = Server.MapPath(strTemp);

Document WordDoc = WordApp.Documents.Add(ref oTemplate, ref Missing,ref Missing, ref Missing);

WordDoc.Activate();

//對標籤"Title"進行填充

string strBM = "Title";

object objBM = strBM;

if(WordApp.ActiveDocument.Bookmarks.Exists(strBM) == true)

{

WordApp.ActiveDocument.Bookmarks.get_Item(ref objBM).Select();

WordApp.Selection.TypeText("公文標題");

}

//儲存為新檔案

object oNewFileName = Server.MapPath(newFileName);

WordDoc.SaveAs(ref oNewFileName, ref Missing,ref Missing, ref Missing,ref Missing,ref Missing,ref Missing,

ref Missing,ref Missing,ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing);

WordDoc.Close(ref Missing, ref Missing, ref Missing);

WordApp.Quit(ref Missing, ref Missing, ref Missing);

}

catch(Exception Ex)

{

throw new Exception(Ex.Message);

}

//瀏覽器彈出下載框

Page.RegisterStartupScript("", "<script>window.open('"+newFileName+"')</script>");

}

運行前,工程目錄下建檔案夾doc, doc裡建立一個test.doc,內容自己定,手動插入一個名為“Title”的標籤。

此代碼在 VS.Net2003+WinXP+Office2007 下運行通過。

如果你在運行時出現下面的調試錯誤:

拒絕訪問。

說明: 執行當前 Web 請求期間,出現未處理的異常。請檢查堆疊追蹤資訊,以瞭解有關該錯誤以及代碼中導致錯誤的出處的詳細資料。

異常詳細資料: System.UnauthorizedAccessException: 拒絕訪問。

ASP.NET 未被授權訪問所請求的資源。請考慮授予 ASP.NET 請求標識訪問此資源的許可權。ASP.NET 有一個在應用程式沒有類比時使用的基進程標識(通常,在 IIS 5 上為 {MACHINE}\ASPNET,在 IIS 6 上為網路服務)。如果應用程式正在通過 <identity impersonate="true"/> 類比,則標識將為匿名使用者(通常為 IUSR_MACHINENAME)或經過身分識別驗證的請求使用者。

若要授予 ASP.NET 對檔案的寫訪問權,請在資源管理員中右擊該檔案,選擇“屬性”,然後選擇“安全”選項卡。單擊“添加”添加適當的使用者或組。反白 ASP.NET 帳戶,選中所需存取權限對應的框。

出現以上錯誤時,表明ASP.NET進程無法對具有使用者介面的Word進行自動化調用,必須由一個擁有案頭的使用者角色來啟動ASP.NET進程。解決方案:在Web.config檔案的System.Web節裡添加<identity impersonate="true" userName="*" password="*" />,其中userName和password是你電腦裡的Windows登入賬戶。

3. 方案總結

Web伺服器端自動化調用Word在實際應用中發現的問題:

l 開發難易度:

Word自動化中的調用都基於VBA文法,需要開發人員對VBA很熟悉。VBA中Word對象眾多、邏輯複雜,COM調用方式難於理解。一般開發人員很少接觸VBA和COM,因此開發起來比較麻煩。

l 代碼安全性:

上述運行錯誤“拒絕訪問”的最佳解決方案就是添加<identity impersonate="true" userName="*" password="*" />,不過缺點是在Web.config裡可以看到你的賬戶密碼,儘管Web.config不會輕易被人下載到,但還是具有一定的危險性。另外也可以運行Dcomcnfg.exe工具提升ASPNET賬戶許可權為互動式使用者,當然這樣也會增加伺服器的風險。網上搜尋發現有網友的解決方案是:在.net 安裝根目錄下找到config檔案夾下的machine.config檔案將processModel 中的username屬性改為SYSTEM。還有網友的解決方案是:將IIS預設的賬戶改為管理員賬戶。這兩個方法更加危險,一旦駭客獲得了ASP.Net進程的許可權,他就能完全控制你的伺服器。

l 運行穩定性:

微軟Office是主要針對普通使用者開發的案頭辦公應用軟體,它具有豐富的UI(使用者介面)元素,是一套純粹的本地運行軟體或者說是用戶端軟體。Word自動化介面主要是為了方便視窗應用程式調用而設計的。例如Delphi、VB、C# Winform等開發的本地應用程式。雖然可以強制Visible為false,Word可以運行在伺服器端代碼裡,但畢竟還是會帶來許多棘手問題。1. ASP.NET是基於B/S架構的。B/S架構下使用者訪問都是並發的,也就是說經常會出現同時N個使用者對一個伺服器頁面發出請求。在這種情況下Word自動化調用會時常出現死進程。2. 由於隱藏介面運行,一些涉及介面的可以在視窗程序裡成功調用的介面,在伺服器端調用就會失敗,甚至崩潰,這種情況也會經常導致死進程。3. 由於Word是複雜的傳統型程式,並不符合一般Web服務程式簡潔高效的標準,所以在伺服器端運行時速度慢,並且還會消耗大量資源(CPU、記憶體),尤其不能支援大量使用者同時訪問,資源會很快耗盡。

l 絕大部分開發人員對COM技術比較陌生,在編程調用Word介面時經常存在一些代碼錯誤,而又很難檢查到問題所在,這又是導致死進程的經常因素。

Word死進程不僅會消耗伺服器資源,還經常會導致伺服器頁面不能建立新的WordAutomation 物件而無法繼續工作。有網友提出死進程解決方案:編程Kill掉Word死進程,這樣是治標不治本的做法,Word死進程是不在了,可是Word非正常關閉會導致很多資源無法及時釋放。這樣的Web伺服器能持續工作多久恐怕就很難說了。

既然在Web伺服器端自動化調用Word存在這麼多問題,那麼能不能在用戶端瀏覽器裡調用Word呢?用JavaScript肯定可以,不過要想運行就得把瀏覽器的安全性降到最低,呵呵,恐怕沒有幾個使用者願意這麼做啊。即使不存在安全問題,本來寫在伺服器端的代碼邏輯要寫在JavaScript裡,由此帶來的大量麻煩(開啟、傳值、取值、儲存到伺服器等)也會讓人難以容忍。

4. 解決方案

為瞭解決這些問題,筆者經過全面研究比較,發現網上有一款軟體SOAOffice(微軟Office專用Web中介軟體),完全消除了以上問題,推薦給大家分享。

經研究發現,SOAOffice是一套由伺服器端組件和用戶端控制項構成的中介軟體系統。伺服器端組件是標準.NET組件,提供簡潔高效的Word、Excel簡化介面;用戶端控制項在瀏覽器網頁裡運行。伺服器端調用SOAWord.WebOpen開啟文檔後,瀏覽器頁面裡用戶端控制項會啟動客戶機上的Word並且運行在網頁裡而不是本地開啟。伺服器端無需安裝Office軟體。

SOAOffice的架構很巧妙,開發人員只需關注伺服器端編程邏輯,用戶端如何工作都交由控制項自動完成。SOAOffice充分利用了分散式運算的思想,把本來要在伺服器端啟動並執行Word運算量交給了客戶機。也就是說,原來採用伺服器端自動化技術的網頁同時要處理N個Word任務現在交給了N個客戶機,每個客戶機運行一個Word。伺服器只需處理需要伺服器處理的商務邏輯,一切與介面有關、與Word程式本身有關的工作由客戶機運行,當然這也是客戶機的強項。

SOAOffice的架構消除了伺服器端運行Word、Excel的風險,又充分利用了客戶機閑置的計算資源,這種架構不但解決了ASP、ASP.NET等Windows web服務調用Word、Excel的問題,而且還給Java寫的Web服務調用Word、Excel提供瞭解決方案(Unix、linux等無法自動化Word、Excel)。

SOAOffice能夠讓使用者直接在網頁裡看到word檔案內容,並且可以直接編輯、儲存回Web伺服器,給使用者省去了先下載下來,修改完後再上傳的麻煩。

SOAOffice還有其他更多自動化調用Word無法做到的強悍功能,比如唯讀、防下載、防複製等,你就下載一個慢慢琢磨吧。

附上利用 SOAOffice 完成本執行個體相同功能 + 唯讀防下載功能的代碼:

private void Page_Load(object sender, System.EventArgs e)

{

// 在此處放置使用者代碼以初始化頁面

SOAOfficeX.WordResponse SOAWord = new SOAOfficeX.WordResponse();

//對資料區域"Title"進行填充

SOAWord.OpenDataRegion("Title").Value = "公文標題";

SOAOfficeX.SOAOfficeCtrl SOACtrl = new SOAOfficeX.SOAOfficeCtrl();

// 設定介面樣式

SOACtrl.MainStyle = SOAOfficeX.soaMainStyle.VistaBlue;

SOACtrl.Caption = "動態產生文檔";

SOACtrl.Menubar = false;

SOACtrl.Toolbars = false;

SOACtrl.CanCopy = false;//禁止下載、複製粘貼等

SOACtrl.Assign(SOAWord);// 綁定資料

// 唯讀開啟產生的文檔

SOACtrl.WebOpen("doc/test.doc", SOAOfficeX.soaWorkMode.docReadOnly, "SomeBody", "Word.Document");

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.