0

I'm trying to add HTML content to DOCX file using OpenXML altchunk approach using C#. The below sample code works fine and appends the HTML content to the end of the document. My requirement is to add HTML content at a specific place in the document, like inside a table cell or inside a paragraph, or search and replace a specific string with an HTML string or placeholders marked using content controls. Can you please point me to some sample example or share few suggestions. Please let me know if you need more info.

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;
        }
    }
}
4

1 回答 1

3

稍微扩展一下我的评论:您真的不应该自己操作文档 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在文档中的任何元素之后、之前或内部插入您的元素,只要您能找到该元素即可。那部分将取决于您要搜索的内容。

如果您正在搜索特定表格,则搜索DocumentFormat.OpenXml.Wordprocessing.Table等。以下是如何在文档中搜索特定表格的一个示例:在打开的 xml 中查找特定表格(在书签之后)

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

于 2017-12-28T18:55:33.233 回答