使用ASP.NET C的报告的Microsoft Word模板#

时间:2011-08-31 07:01:39

标签: asp.net c#-4.0 com ms-word windows-server-2008

当我在本地机器上运行调试模式时,它没关系,但在服务器上我收到了这样的错误。

  

使用CLSID检索组件的COM类工厂   {00020906-0000-0000-C000-000000000046}由于以下原因而失败   错误: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的许可 但是还是有问题,自上个月以来我无法解决这个问题。如果你有可能,请帮助我。感谢

3 个答案:

答案 0 :(得分:1)

在服务器环境中使用完整的办公套件进行此类处理通常是一个非常糟糕的主意。

Office主要设计为可在交互式桌面上运行的客户端应用程序。在运行服务器端时,您实际上需要一种无法实现的方式。

您可以获得办公室服务器端组件,但我并非100%确定这样做的所有优缺点。

如果您创建单词2007兼容文档,那么您可能希望查看使用“Open XML”格式(这是2007年以后使用的单词),Microsoft提供了用于执行此类任务的Open XML SDK

您可以在此处找到文档:http://msdn.microsoft.com/en-us/library/bb226703.aspx

如果您必须使用完整的办公套件,那么我建议您尝试在服务器上手动打开文字,就像您的网络应用程序将运行的用户一样。然后,您可以关闭初始化框并将其设置为永远不会再次出现,这应该(理论上)防止您再次出现的问题。但是,这并不意味着从那时起你就可以100%免费使用,使用Office com互操作可以解决服务器环境中的许多问题。

有关Microsoft自己的方法的更多详细信息,请访问:http://support.microsoft.com/kb/257757

答案 1 :(得分:0)

简短的回答是微软不支持这一点,所以不要指望它可以正常工作或工作。

答案很长,问题是权限以及Word的工作原理。您发布的链接显示了如何解决这个问题,但这不适用于Word。问题是,当第一次调用Word时,它想要显示一个欢迎对话框,用户可以在其中输入首字母和其他内容。当它通过IIS运行时,对话框不会显示,并且无法创建COM对象。应该有一些方法可以禁用此对话框,但Microsoft似乎只能使它们可用于批量许可证。除此之外,这样做的方法是尝试使用IIS内置用户帐户在服务器上运行Word,并以这种方式摆脱第一次用户对话。

我在经典ASP时代的另一种方式是使用具有自己的处理空间和用户权限的COM +对象。这很好用,但我还没有尝试过ASP.NET。如果您的网络管理员不想直接授予内置IIS的权限,这是一个不错的选择。

最后一个解决方案是完全使用Word废弃并使用不同的方法生成文档。这是我的方向,因为Word和IIS之间的内存使用问题在负载测试期间导致服务器崩溃是不可接受的。

其他信息:

对于动态生成Word文档的替代方法,您可以使用RTF模板文件。只需在文本中创建自己的令牌,您就可以在数据字段中进行查找/替换。 Word读取/写入RTF文件,因此您有时需要培训用户。还有第三方工具可用于创建Word文档,但它们价格昂贵且我没有使用过它们。

答案 2 :(得分:0)

我在使用Windows 2008 64位上的COM对象的ASP.NET站点上遇到了这个错误。我最终找到的解决方案是使用regsvr32重新注册COM dll,并将IIS应用程序池的“启用32位应用程序”属性设置为true。之后它运作良好。我没有使用MS Word,所以我不能100%肯定地说这对你有用,但它至少应该值得一试。