使用openXML SDK填充单词模板数据

时间:2019-01-20 12:40:38

标签: c# ms-word openxml-sdk word-contentcontrol

我有一个word文件模板和xml文件来存储数据。我想在Word中找到Content控件,并从xml中获取数据,然后替换Word模板中的文本。我正在使用以下代码,但未更新Word文件。

using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))       
{
           MainDocumentPart mainPart = document.MainDocumentPart;
            IEnumerable<SdtBlock> block = mainPart.Document.Body.Descendants<SdtBlock>().Where
                (r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");
            Text t = block.Descendants<Text>().Single();
             t.Text = "13,450,542";
            mainPart.Document.Save();
}

3 个答案:

答案 0 :(得分:0)

我认为您应该将更改写入临时文件。 请参见Save modified WordprocessingDocument to new file或工作项目中的代码:

    MemoryStream yourDocStream = new MemoryStream();
    ... // populate yourDocStream with .docx bytes
    using (Package package = Package.Open(yourDocStream, FileMode.Open, FileAccess.ReadWrite))
    {
        //  Load the document XML in the part into an XDocument instance.  
        PackagePart packagePart = LoadXmlPackagePart(package);
        XDocument xDocument = XDocument.Load(XmlReader.Create(packagePart.GetStream()));

        // making changes

        //  Save the XML into the package  
        using (XmlWriter xw = XmlWriter.Create(packagePart.GetStream(FileMode.Create, FileAccess.Write)))
        {
            xDocument.Save(xw);
        }

        var resultDocumentBytes = yourDocStream.ToArray();
    }

答案 1 :(得分:0)

您使用的基本方法可以正常工作,但是令您惊讶的是您没有得到任何编译时错误,因为

IEnumerable<SdtBlock> block = mainPart.Document.Body.Descendants<SdtBlock>().Where
            (r => r.SdtProperties.GetFirstChild<Tag>().Val == "TotalClose");

不兼容
Text t = block.Descendants<Text>().Single();

block,因为IEnumberable没有Descendants属性。您要么需要遍历IEnumerable中的所有项目,然后对每个项目执行此操作,要么需要定义和实例化单个项目,例如:

    using (WordprocessingDocument document = WordprocessingDocument.CreateFromTemplate(txtWordFile.Text))
    {
        MainDocumentPart mainPart = pkgDoc.MainDocumentPart;
        SdtBlock block = mainPart.Document.Body.Descendants<SdtBlock>().Where
            (r => r.SdtProperties.GetFirstChild<Tag>().Val == "test1").FirstOrDefault();
        Text t = block.Descendants<Text>().Single();
        t.Text = "13,450,542";
        mainPart.Document.Save();
     }

答案 2 :(得分:0)

对于仍在为此苦苦挣扎的任何人-您可以签出该库GitHub issue

有了它,您可以基于JSON对象(或基本的C#词典)替换文档的所有内容控件中的文本,而无需编写特定代码,而是在内容控件的标签中指定变量名。

(注意-我是该库的制造商,但该库是开源的,并根据LGPLv3许可)