Шаблон Microsoft Word для отчета с использованием ASP.NET C # - PullRequest
0 голосов
/ 31 августа 2011

Когда я запускаю с режимом отладки на моем локальном компьютере, это нормально, но на сервере я получаю такую ​​ошибку.

Получение фабрики класса COM для компонента с CLSID {00020906-0000-0000-C000-000000000046} не удалось из-за следующих ошибка: 80080005.

Мой сервер 64-разрядный Windows 2008, 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 ]

1 голос
/ 02 сентября 2011

Обычно очень плохая идея использовать полнофункциональный офисный пакет для подобных процессов в серверной среде.

Office в первую очередь разработан как клиентское приложение для запуска на интерактивном рабочем столе.При работе на стороне сервера вам реально нужен непредусмотренный способ действий.

Вы можете получить компоненты на стороне офисного сервера, но я не уверен на 100% во всех плюсах и минусах этого.

Если вы создаете документы, совместимые с Word 2007, тогда вам может понадобиться использовать формат «Open XML» (который используется в Word 2007 и далее), Microsoft предоставляет Open XML SDK для выполнения таких задач

, что выЗдесь вы можете найти документы: http://msdn.microsoft.com/en-us/library/bb226703.aspx

Если вам необходимо использовать полнофункциональный офисный пакет, я мог бы предложить вам попробовать вручную открыть слово на сервере, как пользователь, которым будет запускаться ваше веб-приложение.Затем вы можете закрыть окно инициалов и установить, чтобы оно больше никогда не появлялось, что должно (теоретически) предотвратить возникновение проблемы, которую вы видите.Это, однако, не означает, что с этого момента вы получите 100% беспроблемное использование, благодаря взаимодействию Office com можно решить множество проблем в серверной среде.

Более подробную информацию о собственном подходе Microsoft можно найтиздесь: http://support.microsoft.com/kb/257757

0 голосов
/ 02 сентября 2011

У меня была точная ошибка на сайте ASP.NET с использованием COM-объекта в Windows 2008 64-bit. Решение, которое я наконец нашел, состояло в том, чтобы заново зарегистрировать COM-DLL в regsvr32, а также установить для свойства пула приложений IIS «Включить 32-разрядные приложения» значение true. После этого все работало нормально. Я не работал с MS Word, поэтому не могу сказать со 100% уверенностью, что это сработает для вас, но, по крайней мере, стоит попробовать.

0 голосов
/ 31 августа 2011

Короткий ответ: Microsoft не поддерживает эту функцию, поэтому не ожидайте, что она будет работать или работать надежно.

Длинный ответ заключается в том, что проблема заключается в разрешениях и в том, как работает Word. Ссылка, которую вы разместили, показывает, как обойти это для Excel, но это не сработает для Word. Проблема в том, что когда Word вызывается впервые, он хочет отобразить диалоговое окно приветствия, в котором пользователь может вводить инициалы и другие элементы. Когда он запускается через IIS, диалоговое окно не отображается и объект COM не может быть создан. Предполагается, что есть несколько способов отключить это диалоговое окно, но Microsoft, кажется, только делает их доступными для корпоративных лицензий. Кроме этого, способ сделать это состоит в том, чтобы попытаться запустить Word на сервере, используя встроенную учетную запись IIS, и таким образом избавиться от первого пользовательского диалога.

Другой способ, которым я занимался в классические дни ASP, - это использование объекта COM + с собственным пространством обработки и разрешениями пользователя. Это работало хорошо, но я не пробовал это с ASP.NET. Это хороший вариант, если ваш сетевой администратор не хочет давать разрешения встроенному IIS напрямую.

Последнее решение - полностью отказаться от использования Word и использовать другой метод для создания ваших документов. В этом направлении я пошел, потому что проблемы с использованием памяти между Word и IIS продолжали вызывать сбои сервера во время нагрузочного тестирования, которые были неприемлемы.

Дополнительная информация:

Что касается альтернативных методов динамического создания документов Word, вы можете использовать файл шаблона RTF. Просто создайте свои собственные токены в тексте, где вы можете найти / заменить поля данных. Word читает / записывает RTF-файлы, поэтому иногда нужно просто обучать пользователей. Доступны также сторонние инструменты, которые будут создавать документы Word, но они дорогие, и я не использовал ни одного из них.

...