2011-08-31 53 views
0

當我在本地機器上使用調試模式運行時,沒關係,但在服務器上出現了這樣的錯誤。用於報告的Microsoft Word模板使用ASP.NET C#

Retrieving the COM class factory for component with CLSID {00020906-0000-0000-C000-000000000046} failed due to the following error: 80080005.

我的服務器是Windows 2008 64位,Office 2007和我的代碼是這樣的

private void GenerateWords(string sPO, string sSup) 
    { 
     Object oMissing = System.Reflection.Missing.Value; 
     Object oTrue = true; 
     Object oFalse = false; 
     Object savechanges = true; 

     Word.ApplicationClass oWord = new Word.ApplicationClass(); 
     Word.Document oWordDoc = new Word.Document(); 
     oWord.Visible = true; 
     Object oTemplatePath = Server.MapPath("Reports/Word/PurchaseOrder.docx");    

     oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);    
     oWordDoc.Activate(); 

     foreach (Word.Field myMergeField in oWordDoc.Fields) 
     { 
      iTotalFields++; 
      Word.Range rngFieldCode = myMergeField.Code; 
      String fieldText = rngFieldCode.Text; 

      // Start filling information in Word file 
      if (fieldText.StartsWith(" MERGEFIELD")) 
      { 
       Int32 endMerge = fieldText.IndexOf("\\"); 
       Int32 fieldNameLength = fieldText.Length - endMerge; 
       String fieldName = fieldText.Substring(11, endMerge - 11); 

       fieldName = fieldName.Trim(); 

       if (fieldName == "PONo") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(sPO); 
       } 

       if (fieldName == "SupNo") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(sSup); 
       } 

       if (fieldName == "VendorID") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["VendorID"].ToString().Trim()); 
       } 

       if (fieldName == "VName") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Name"].ToString().Trim()); 
       } 

       if (fieldName == "Contact") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Contact"].ToString().Trim()); 
       } 

       if (fieldName == "Designation") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Designation"].ToString().Trim()); 
       } 

       if (fieldName == "Tel") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Tel"].ToString().Trim()); 
       } 

       if (fieldName == "Fax") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Fax"].ToString().Trim()); 
       } 

       if (fieldName == "PODate") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["PODate"].ToString().Trim()); 
       } 

       if (fieldName == "ClientName") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["ClientName"].ToString().Trim()); 
       } 

       if (fieldName == "JobDescription") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["JobDescription"].ToString().Trim()); 
       } 

       if (fieldName == "JobNo") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["JobNo"].ToString().Trim()); 
       } 

       if (fieldName == "CostCode") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["CostCode"].ToString().Trim()); 
       } 

       if (fieldName == "SchDlvy") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["SchDlvy"].ToString().Trim()); 
       } 

       if (fieldName == "DlvyPoint") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["DlvyPoint"].ToString().Trim()); 
       } 

       if (fieldName == "Amount") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Amount"].ToString().Trim()); 
       } 

       if (fieldName == "tbl") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeParagraph(); 
        Word.Table tbl = oWordDoc.Tables.Add(rngFieldCode, 1, 5, ref oMissing, ref oMissing); 
        //oWordDoc.Tables.Add(rngFieldCode, dtItems(sPO, sSup).Rows.Count, 5, ref oMissing, ref oMissing); 

        //SET HEADER 
        SetHeadings(tbl.Cell(1, 1), "Item No."); 
        SetHeadings(tbl.Cell(1, 2), "Description"); 
        SetHeadings(tbl.Cell(1, 3), "Unit"); 
        SetHeadings(tbl.Cell(1, 4), "Unit Price"); 
        SetHeadings(tbl.Cell(1, 5), "Amount"); 
        //END SET HEADER 

        //Add Row 
        for (int i = 0; i < dtItems(sPO, sSup).Rows.Count; i++) 
        { 
         Word.Row newRow = tbl.Rows.Add(ref oMissing); 
         newRow.Range.Font.Bold = 0; 
         newRow.Range.Underline = 0; 
         newRow.Range.ParagraphFormat.Alignment = 
         Word.WdParagraphAlignment.wdAlignParagraphCenter; 

         newRow.Cells[1].Range.Text = dtItems(sPO, sSup).Rows[i][3].ToString(); 
         newRow.Cells[2].Range.Text = dtItems(sPO, sSup).Rows[i][4].ToString(); 
         newRow.Cells[3].Range.Text = dtItems(sPO, sSup).Rows[i][8].ToString(); 
         newRow.Cells[4].Range.Text = dtItems(sPO, sSup).Rows[i][10].ToString(); 
         newRow.Cells[5].Range.Text = dtItems(sPO, sSup).Rows[i][11].ToString(); 
        } 
        //END ROW 

        oWord.Selection.TypeParagraph(); 
       } 

       if (fieldName == "TItems") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtTotal(sPO, sSup).Rows[0]["Unit"].ToString().Trim()); 
       } 

       if (fieldName == "Discount") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtTotal(sPO, sSup).Rows[0]["Discount"].ToString().Trim()); 
       } 

       if (fieldName == "TAmount") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtTotal(sPO, sSup).Rows[0]["Amount"].ToString().Trim()); 
       } 

       if (fieldName == "Summary") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["Amount"].ToString().Trim()); 
       } 

       if (fieldName == "ReqNo") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["ReqNo"].ToString().Trim()); 
       } 

       if (fieldName == "RevNo") 
       { 
        myMergeField.Select(); 
        oWord.Selection.Font.Color = Word.WdColor.wdColorBlue; 
        oWord.Selection.TypeText(dtPOSup(sPO, sSup).Rows[0]["RevNo"].ToString().Trim()); 
       } 
      } 
     } 
     // End filling information in Word file 

     Object oSaveAsFile = (Object)Server.MapPath("Reports/Word/tmp2.docx"); 
     oWordDoc.SaveAs(ref oSaveAsFile, ref oMissing, ref oMissing, ref oMissing, 
      ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, 
      ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, 
      ref oMissing, ref oMissing); 

     oWordDoc.Close(ref savechanges, ref oMissing, ref oMissing); 
     oWord.Application.Quit(ref savechanges, ref oMissing, ref oMissing); 

     //foreach (Process p in System.Diagnostics.Process.GetProcessesByName("winword")) 
     //{ 
     // try 
     // { 
     //  if (p.ProcessName == "WINWORD") 
     //  { 
     //   if (!p.HasExited) 
     //   { 
     //    p.Kill(); 
     //    p.WaitForExit(); // possibly with a timeout 
     //   } 
     //  } 
     //  else 
     //  { 
     //   lblMessage.Text = "cannot kill. try again!"; 
     //  } 
     // } 
     // catch (Win32Exception winException) 
     // { 
     //  //process was terminating or can't be terminated - deal with it  
     //  Session["error"] = winException.Message; 
     //  Response.Redirect("MessageBoard.aspx"); 
     // } 
     // catch (InvalidOperationException invalidException) 
     // { 
     //  //process has already exited - might be able to let this one go 
     //  Session["error"] = invalidException.Message; 
     //  Response.Redirect("MessageBoard.aspx"); 
     // } 
     //} 

     Response.ClearContent(); 
     Response.ClearHeaders(); 
     Response.ContentType = "application/msword"; 
     Response.WriteFile(Server.MapPath("Reports/Word/tmp2.docx"), false); 
     Response.Flush(); 
     Response.Close(); 
    } 

而且我也跟着從Blog.Crowe.co.nz 賦予權限,但仍然有問題,我解決不了這是自上個月以來的一次。如果可能的話,請幫助我。謝謝

回答

0

簡單的答案是,這不是微軟支持的,所以不要指望它能夠工作或工作可靠。

長的答案是問題是權限以及Word如何工作。您發佈的鏈接顯示如何解決這個問題,但這不適用於Word。問題是,當第一次調用Word時,它想要顯示一個歡迎對話框,用戶可以在其中輸入姓名縮寫和其他內容。當它通過IIS運行時,對話框不顯示,並且無法創建COM對象。應該有一些方法來禁用這個對話框,但是微軟似乎只能使它們可用於批量許可證。除此之外,實現它的方法是嘗試使用IIS內置用戶帳戶在服務器上運行Word,並以此方式擺脫第一次用戶對話框。

我在經典的ASP日子裏做的另一種方式是使用帶有自己的處理空間和用戶權限的COM +對象。這工作得很好,但我沒有用ASP.NET試過。如果您的網絡管理員不想直接向內置的IIS授予權限,這是一個不錯的選擇。

最後的解決方案是完全使用Word進行報廢,並使用其他方法生成文檔。這是我前進的方向,因爲Word和IIS之間的內存使用問題在加載測試期間不斷導致服務器崩潰,這是不可接受的。

附加信息:

至於替代方法動態生成的Word文檔,可以使用RTF模板文件。只需在文本中創建您自己的令牌,您可以在數據字段上進行查找/替換。 Word讀取/寫入RTF文件,因此您只需要有時訓練用戶。還有第三方工具可用來創建Word文檔,但價格昂貴,我沒有使用過它們中的任何一個。

+0

如果我可能會問,你如何生成文檔? – TweeZz

+0

so!單詞報告不適合web應用程序?所以有時我們需要使用單詞報告,我們應該怎麼做?以及爲什麼有些開發人員顯示他們的教程和示例代碼,如[Codeproject](http://www.codeproject.com/KB/aspnet/wordapplication.aspx)[C#Corner](http://www.c-sharpcorner.com/ UploadFile/amrish_deep/WordAutomation05102007223934PM/WordAutomation.aspx#ReadAndPostComment) – CMMaung

+1

@CMMaung - 它可以工作,這就是代碼示例所顯示的內容,但是在部署和解決方案的整體可靠性方面會非常令人沮喪。讓它在一個開發箱上運行是一回事,而在生產環境中運行並穩定運行它是一回事。 – jfrankcarr

1

在服務器環境中使用這種完整的辦公套件來處理這樣的流程通常是一個非常糟糕的主意。

Office主要是作爲客戶端應用程序設計的,可以在交互式桌面上運行。在運行服務器端時,您實際上需要一種無所作爲的方式。

您可以獲得辦公服務器端組件,但我並非100%確定這樣做的所有利弊。

如果您創建的Word 2007兼容的文件,那麼你可能想看看使用「開放XML」格式(這是什麼字2007年開始使用),微軟提供了一個開放的XML SDK用於執行此類任務

你可以在這裏找到文檔:http://msdn.microsoft.com/en-us/library/bb226703.aspx

如果您必須使用完整的辦公套件,那麼我可以建議您嘗試在服務器上手動打開單詞,作爲您的網絡應用運行的用戶。然後,您可以關閉啓動框並將它永遠不再出現,應該(理論上)防止您再次發生問題。然而,這並不意味着您將從此時起獲得100%無問題的使用,使用Office com互操作性可以解決服務器環境中的許多問題。

微軟自己的方法的更多細節可以在這裏找到:http://support.microsoft.com/kb/257757

0

我有這個確切的錯誤使用Windows 2008上的64位COM對象的ASP.NET網站。我終於找到的解決方案是用regsvr32重新註冊COM DLL,並將IIS應用程序池的「啓用32位應用程序」屬性設置爲true。那之後它運行良好。我沒有使用MS Word,所以我不能100%肯定地說這對您有用,但至少應該值得一試。

相關問題