将 html 嵌入 table 或 docx 文档中的特定位置

Embed html within a table or at specific location in a docx document

我正在尝试使用 C# 使用 OpenXML altchunk 方法将 HTML 内容添加到 DOCX 文件。下面的示例代码工作正常,并将 HTML 内容附加到文档的末尾。我的要求是在文档中的特定位置添加 HTML 内容,例如 table 单元格内或段落内,或者搜索特定字符串并将其替换为 HTML 字符串或占位符使用内容控件标记。你能给我指出一些示例或分享一些建议吗?如果您需要更多信息,请告诉我。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;
using OpenXmlPowerTools;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using System.Xml;

namespace Docg2
{
    class Program
    {
        static void Main(string[] args)
        {
            testaltchunk();
        }

        public static void testaltchunk()
        {
            XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
            XNamespace r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
            using (WordprocessingDocument myDoc = WordprocessingDocument.Open("../../Test3.docx", true))
            {
                string html =
                @"<html>
                    <head/>
                    <body>
                        <h1>Html Heading</h1>
                        <p>This is an html document in a string literal.</p>
                    </body>
                </html>";

                string altChunkId = "AltChunkId1";
                MainDocumentPart mainPart = myDoc.MainDocumentPart;
                AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart("application/xhtml+xml", altChunkId);

                using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
                using (StreamWriter stringStream = new StreamWriter(chunkStream))
                    stringStream.Write(html);

                XElement altChunk = new XElement(w + "altChunk", new XAttribute(r + "id", altChunkId));
                XDocument mainDocumentXDoc = GetXDocument(myDoc);
                mainDocumentXDoc.Root
                    .Element(w + "body")
                    .Elements(w + "p")
                    .Last()
                    .AddAfterSelf(altChunk);

                SaveXDocument(myDoc, mainDocumentXDoc);
            }
        }

        private static void SaveXDocument(WordprocessingDocument myDoc, XDocument mainDocumentXDoc)
        {
            // Serialize the XDocument back into the part
            using (var str = myDoc.MainDocumentPart.GetStream(FileMode.Create, FileAccess.Write))
            using (var xw = XmlWriter.Create(str))
                mainDocumentXDoc.Save(xw);
        }

        private static XDocument GetXDocument(WordprocessingDocument myDoc)
        {
            // Load the main document part into an XDocument
            XDocument mainDocumentXDoc;
            using (var str = myDoc.MainDocumentPart.GetStream())
            using (var xr = XmlReader.Create(str))
                mainDocumentXDoc = XDocument.Load(xr);

            return mainDocumentXDoc;
        }
    }
}

稍微扩展一下我的评论:您真的不应该自己操纵文档 XML。您首先失去了使用 OpenXML 的所有好处。因此,您的代码可以这样重写:

static void Main(string[] args)
{
    using (WordprocessingDocument myDoc = WordprocessingDocument.Open("../../Test3.docx", true))
    {
        string html =
        @"<html>
            <head/>
            <body>
                <h1>Html Heading</h1>
                <p>This is an html document in a string literal.</p>
            </body>
        </html>";

        string altChunkId = "AltChunkId1";
        MainDocumentPart mainPart = myDoc.MainDocumentPart;
        AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart("application/xhtml+xml", altChunkId);

        using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))
        using (StreamWriter stringStream = new StreamWriter(chunkStream))
            stringStream.Write(html);

        AltChunk altChunk = new AltChunk();
        altChunk.Id = altChunkId;

        // this inserts altChunk after the last Paragraph
        mainPart.Document.Body
            .InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());

        mainPart.Document.Save();
    }
}

现在,很明显您可以在文档中的任何元素之后、之前或内部插入 AltChunk,只要您能找到该元素即可。该部分将取决于您要搜索的内容。

如果您要搜索特定的 table,则搜索 DocumentFormat.OpenXml.Wordprocessing.Table 等。以下是如何在文档中搜索特定的 table 的示例: Find a specific Table (after a bookmark) in open xml

下面是替换内容控件的示例https://msdn.microsoft.com/en-us/library/cc197932(v=office.12).aspx