You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将动态替换内容的HTML转换为带页码与分页的.docx文件的实现方法

Convert Dynamic HTML to Paginated Word Document (.docx)

Great question! Since ASP.NET doesn't have built-in tools for generating paginated Word docs from HTML, you have two solid options—using a third-party library for simplicity, or Microsoft's official OpenXML SDK for full control without dependencies. Let's break both down for your specific setup:

Option 1: Xceed DocX (Simplest Approach)

This library wraps the OpenXML SDK and cuts down on boilerplate code, making it easy to add HTML content and page numbers.

Step 1: Install the NuGet Package

First, add the Xceed.Document.NET package to your project via NuGet Package Manager or the Package Manager Console:

Install-Package Xceed.Document.NET

Step 2: Update Your Code to Generate the Word Doc

Replace your existing code (after replacing placeholders in the HTML) with this:

using Xceed.Document.NET;
using Xceed.Words.NET;
using System.IO;

// ... your existing code to read the HTML template and replace placeholders ...

try
{
    // Create a new Word document in memory
    using (DocX document = DocX.Create(new MemoryStream()))
    {
        // Insert your dynamically populated HTML into the document
        document.InsertHtml(result);

        // Add a footer with automatic page numbers (e.g., "Page 1 of 3")
        var footer = document.AddFooter();
        footer.Paragraphs.Add(
            document.CreateParagraph()
                .Append("Page ")
                .AppendPageNumber(PageNumberFormat.numeric)
                .Append(" of ")
                .AppendPageCount(PageNumberFormat.numeric)
        );

        // Prepare the document for download
        document.Save();
        document.Stream.Position = 0;

        // Set response headers to trigger download
        Response.Clear();
        Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        Response.AddHeader("Content-Disposition", "attachment; filename=Quotation.docx");
        document.Stream.CopyTo(Response.OutputStream);
        Response.End();
    }
}
catch (Exception ex)
{
    Response.Write($"Error generating quotation document: {ex.Message}");
}

Quick Notes:

  • The InsertHtml method handles your table and inline styles well—just make sure your HTML uses inline style attributes (Word doesn't play nice with external CSS).
  • Page numbers are automatically added to every page, and Word will update them if the content changes later.
  • If you need manual page breaks, add <br style="page-break-after: always;"> in your HTML where you want the break.

Option 2: Microsoft OpenXML SDK (No Third-Party Dependencies)

If you prefer to avoid external libraries, use the official OpenXML SDK. It's more verbose but gives you complete control over the document structure.

Step 1: Install the NuGet Packages

Add the core OpenXML SDK package:

Install-Package DocumentFormat.OpenXml

For better HTML parsing (to avoid manual conversion of elements), also add HtmlToOpenXml:

Install-Package HtmlToOpenXml

Step 2: Code to Generate the Paginated Doc

Here's how to convert your HTML to a Word doc with page numbers:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using HtmlToOpenXml;
using System.IO;

// ... your existing code to read and replace HTML content ...

try
{
    using (MemoryStream ms = new MemoryStream())
    {
        // Create a new Word document
        using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(ms, WordprocessingDocumentType.Document))
        {
            MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
            mainPart.Document = new Document();
            Body body = mainPart.Document.AppendChild(new Body());

            // Convert your HTML to Word-compatible elements
            var converter = new HtmlConverter(mainPart);
            var paragraphs = converter.Parse(result);
            foreach (var para in paragraphs)
            {
                body.AppendChild(para);
            }

            // Add a footer with dynamic page numbers
            FooterPart footerPart = mainPart.AddNewPart<FooterPart>();
            Footer footer = new Footer();

            // Create the page number paragraph using Word field codes
            Paragraph footerPara = new Paragraph();
            Run run = new Run();
            
            // Add "Page X"
            run.Append(new Text("Page "));
            run.Append(new FieldChar { FieldCharType = FieldCharValues.Begin });
            run.Append(new Run(new Text("PAGE \\* MERGEFORMAT")) { RunProperties = new RunProperties(new NoProof()) });
            run.Append(new FieldChar { FieldCharType = FieldCharValues.Separator });
            run.Append(new Run(new Text()) { RunProperties = new RunProperties(new NoProof()) });
            run.Append(new FieldChar { FieldCharType = FieldCharValues.End });
            
            // Add " of Y"
            run.Append(new Text(" of "));
            run.Append(new FieldChar { FieldCharType = FieldCharValues.Begin });
            run.Append(new Run(new Text("NUMPAGES \\* MERGEFORMAT")) { RunProperties = new RunProperties(new NoProof()) });
            run.Append(new FieldChar { FieldCharType = FieldCharValues.Separator });
            run.Append(new Run(new Text()) { RunProperties = new RunProperties(new NoProof()) });
            run.Append(new FieldChar { FieldCharType = FieldCharValues.End });

            footerPara.Append(run);
            footer.Append(footerPara);
            footerPart.Footer = footer;

            // Link the footer to the document so it appears on all pages
            SectionProperties sectionProps = body.AppendChild(new SectionProperties());
            sectionProps.Append(new FooterReference { Id = mainPart.GetIdOfPart(footerPart), Type = HeaderFooterValues.Default });

            // Save the document
            mainPart.Document.Save();
        }

        // Trigger the download
        ms.Position = 0;
        Response.Clear();
        Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        Response.AddHeader("Content-Disposition", "attachment; filename=Quotation.docx");
        ms.CopyTo(Response.OutputStream);
        Response.End();
    }
}
catch (Exception ex)
{
    Response.Write($"Error generating document: {ex.Message}");
}

Key Tips:

  • The HtmlToOpenXml library saves you from manually converting every HTML element to OpenXML tags—highly recommended unless you need custom parsing logic.
  • The page number field codes (PAGE and NUMPAGES) will automatically update in Word when the document is opened or edited.

General Best Practices

  • Inline Styles: Stick to inline style attributes in your HTML template—Word doesn't support external CSS files.
  • Memory Management: Using MemoryStream avoids writing temp files to the server, which is better for performance and cleanup.
  • Testing: Always test your template with real data to ensure pagination and styling look correct in Word.

内容的提问来源于stack exchange,提问作者Ashita Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:31:12