Asp.net下自動呼叫Word的例項

iDotNetSpace發表於2009-12-29

  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 Template = Server.MapPath(strTemp);
  Document WordDoc = WordApp.Documents.Add(ref oTemplate, ref Missing,ref Missing, ref Missing);
  WordDoc.Activate();
  //對標籤"Title"進行填充
  string strBM = "Title";
  object bjBM = strBM;
  if(WordApp.ActiveDocument.Bookmarks.Exists(strBM) == true)
  {
  WordApp.ActiveDocument.Bookmarks.get_Item(ref objBM).Select();
  WordApp.Selection.TypeText("公文標題");
  }
  //儲存為新檔案
  object NewFileName = 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("", "");
  }

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

  此程式碼在 VS.Net2003+WinXP+Office2007 下執行通過。

  如果你在執行時出現下面的除錯錯誤:

  拒絕訪問。

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

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

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

  若要授予 ASP.NET 對檔案的寫訪問權,請在資源管理器中右擊該檔案,選擇“屬性”,然後選擇“安全”選項卡。單擊“新增”新增適當的使用者或組。突出顯示 ASP.NET 帳戶,選中所需訪問許可權對應的框。

  出現以上錯誤時,表明ASP.NET程式無法對具有使用者介面的Word進行自動化呼叫,必須由一個擁有桌面的使用者角色來啟動ASP.NET程式。解決方法:在Web.config檔案的System.Web節裡新增,其中userName和password是你電腦裡的Windows登入賬戶。

  3. 方案總結

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

  一、 開發難易度:Word自動化中的呼叫都基於VBA語法,需要開發者對VBA很熟悉。VBA中Word物件眾多、邏輯複雜,COM呼叫方式難於理解。一般開發者很少接觸VBA和COM,因此開發起來比較麻煩。

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

  三、 執行穩定性:微軟Office是主要針對普通使用者開發的桌面辦公應用軟體,它具有豐富的UI(使用者介面)元素,是一套純粹的本地執行軟體或者說是客戶端軟體。Word自動化介面主要是為了方便視窗應用程式呼叫而設計的。例如Delphi、VB、C# Winform等開發的本地應用程式。雖然可以強制Visible為false,Word可以執行在伺服器端程式碼裡,但畢竟還是會帶來許多棘手問題。1. ASP.NET是基於B/S架構的。B/S架構下使用者訪問都是併發的,也就是說經常會出現同時N個使用者對一個伺服器頁面發出請求。在這種情況下Word自動化呼叫會時常出現死程式。2. 由於隱藏介面執行,一些涉及介面的可以在視窗程式裡成功呼叫的介面,在伺服器端呼叫就會失敗,甚至崩潰,這種情況也會經常導致死程式。3. 由於Word是複雜的桌面程式,並不符合一般Web服務程式簡潔高效的標準,所以在伺服器端執行時速度慢,並且還會消耗大量資源(CPU、記憶體),尤其不能支援大量使用者同時訪問,資源會很快耗盡。4. 絕大部分開發者對COM技術比較陌生,在程式設計呼叫Word介面時經常存在一些程式碼錯誤,而又很難檢查到問題所在,這又是導致死程式的經常因素。Word死程式不僅會消耗伺服器資源,還經常會導致伺服器頁面不能建立新的Word自動化物件而無法繼續工作。有網友提出死程式解決方法:程式設計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");
  }

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-623874/,如需轉載,請註明出處,否則將追究法律責任。

相關文章