【问题标题】:Generating a TOC in Word filled with html source in ASP.NET用 ASP.NET 中的 html 源代码在 Word 中生成 TOC
【发布时间】:2013-04-03 08:21:23
【问题描述】:

我被指派为 Word 文档创建一个 TOC(目录),它根据从数据库中获得的一些信息和特定的设计动态地填充 HTML 代码,最后这个操作必须在一个ASP。 NET 服务器端使用用 C# 编程的 3.5 .NET Framework,它必须使用生成的 TOC 和 Word 格式发送到客户端。

我也可以告诉你,服务器的操作系统是 Windows 2008 Server,并且安装了 Microsoft Office 2010。

所以,首先我尝试使用 Microsoft.Interoffice.Word 将它集成到服务器端代码中,但后来我意识到微软不支持这种东西,因为security matters。然后我尝试创建一个控制台应用程序来实现此功能(使用 Microsoft.Office.Interop.Word)并将 HTML 代码导出到 doc 文档,它们都位于同一个文件夹中,并且 IIS_USERS 组可以完全访问该位置。但是,当我尝试启动在网站代码中创建目录的控制台应用程序时,它会显示与控制台应用程序相关的错误。

我已经使用生成的包含 HTML 代码的 doc 测试了控制台应用程序,它运行流畅,所以我不明白发生了什么...... IIS 是否检测到控制台应用程序使用 Microsoft.Office.Interop.Word,并且它不允许它执行?这个想法是,当控制台应用程序完成时,我会将整个文档再次带回网站并生成一个 HTTP 响应到客户端,这样它就会显示典型的打开/保存弹出对话框。

我也一直在尝试使用外部库,但没有结果,例如 GemBox(HTML 代码的文件格式问题)、NPOI(它的 HWPF 库处于 alpha 版本)、OpenSDK(无法评估分页,因此无法使用doc 充满信息),AsPosed Words(相当昂贵的库,我无法在免费许可中尝试这种功能)

我告诉你知道控制台应用程序代码:

    ArrayList arrValoresIndices = new ArrayList();
Application wordApp = new Application();
object missing = System.Type.Missing;
    
try {
    Document wordDocument = wordApp.Documents.Open(docFileSource);
    //Applying style to headers
    System.Drawing.Color colorNecesario = System.Drawing.ColorTranslator.FromHtml("#1F497D");
    WdColor coloraplicado = (Microsoft.Office.Interop.Word.WdColor)(colorNecesario.R + 0x100 * colorNecesario.G + 0x10000 * colorNecesario.B);
    wordApp.ActiveDocument.Styles[WdBuiltinStyle.wdStyleHeading1].Font.Name = "Calibri";
    wordApp.ActiveDocument.Styles[WdBuiltinStyle.wdStyleHeading1].Font.Size = 14;
    wordApp.ActiveDocument.Styles[WdBuiltinStyle.wdStyleHeading1].Font.Bold = -1;
    wordApp.ActiveDocument.Styles[WdBuiltinStyle.wdStyleHeading1].Font.Color = coloraplicado;
    
    int numPalabras = wordDocument.Words.Count;

    for (int i = 1; i < numPalabras; i++)
    {

        string texto = wordDocument.Words[i].Text;

        if (texto.Equals("") == false && wordDocument.Words[i].Font.Size == 14 &&
             wordDocument.Words[i].Font.Name == "Calibri" &&
             wordDocument.Words[i].Font.Bold == -1 &&
             wordDocument.Words[i].Font.Color == coloraplicado)
        {
            wordDocument.Words[i].set_Style(WdBuiltinStyle.wdStyleHeading1);
        }

    }

    object gotoPage = WdGoToItem.wdGoToPage;
    object gotoNext = WdGoToDirection.wdGoToNext;
    object gotoCount = null;
    object gotoName = "2";
    wordApp.Selection.GoTo(ref gotoPage, ref gotoNext, ref gotoCount, ref gotoName);
    wordApp.Selection.InsertBreak(WdBreakType.wdPageBreak);
    gotoName = "2";
    Range indexPage= wordApp.Selection.GoTo(ref gotoPage, ref gotoNext, ref gotoCount, ref gotoName);
    object oTrue = true;
    TableOfContents toc = wordDocument.TablesOfContents.Add(indexPage, ref oTrue, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref oTrue);

    wordDocument.TablesOfContents.Format = WdTocFormat.wdTOCModern;
    toc.Update();
    wordDocument.SaveAs2(docFileSource,WdSaveFormat.wdFormatFilteredHTML);
    wordDocument.Close();
    wordApp.Quit();
}
catch (COMException ce)
{
    wordApp.Application.Quit(ref missing, ref missing, ref missing);
    throw new COMException("Process has failed ...\n");
    }
}

启动代码的网站代码:

String nombreDoc = "C:\\tempDocs\\JGA.doc"; //i will store the doc in this folder, in this folder IIS_USRS have full access
File.WriteAllText(nombreDoc, strCabecera.ToString()); //strCabecera contains the whole html code
Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = @"C:\\tempDocs\\TOCIndexer\\TOCIndexer.exe -nombreDoc";
p.StartInfo.UseShellExecute = false;
p.StartInfo.Verb = "runas";

using (Process exeProcess = Process.Start(p))
{
     exeProcess.WaitForExit();
}

//When the process has finished I import againg the content to a new string builder
StringBuilder strCabeceraVolcado = new StringBuilder();
using (var sr = new StreamReader(nombreDoc))
{
    strCabeceraVolcado.Append(sr.ReadToEnd());
}
if (File.Exists(@nombreDoc))
{
    File.Delete(@nombreDoc);
}
strCabecera = strCabeceraVolcado;

HttpContext.Current.Response.Write(strCabecera);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();

你能给我一些建议吗?

谢谢

【问题讨论】:

    标签: asp.net ms-word windows-server-2008 office-interop tableofcontents


    【解决方案1】:

    经过研究,我意识到整个应用程序是正确的,问题在于服务器设置。

    此解决方案仅适用于 Windows Server 2008 64 位,如果遇到 Microsoft.Office.Interop.Word 问题,您必须按照以下步骤操作:

    1º 您必须在服务器中安装 Microsoft.Office.Word。

    2º 您必须将生成文档的文件夹中的“完全控制”权限分配给“IIS 用户组”和“匿名登录”用户。

    3º 您必须修改组件服务 (C:\Windows\System32\comexp.msc) 并将 Identity 值“The Interactive User”设置为“Office Licensing COM Server 14 Properties”(可以是 12 而不是 14,具体取决于您安装的 Office 版本)

    4º 在位于 C:\Windows\SysWOW64\config\systemprofile\ 的路径中创建文件夹“Desktop”

    如果您按照这些步骤操作,ASP.NET 将允许您使用 Microsof.Office.Interop.Word 库修改文档。

    【讨论】:

      猜你喜欢
      • 2011-08-14
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多