Заполните данные шаблона слова с помощью openXML SDK

У меня есть шаблон файла Word и файл XML для данных. Я хочу найти элемент управления содержимым в слове и получить данные из xml, а затем заменить текст в шаблоне слова. Я использую следующий код, но он не обновляет файл 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();
}

person farrukh aziz    schedule 20.01.2019    source источник


Ответы (3)


Я думаю, вам стоит записывать изменения во временный файл. См. Сохранить измененный документ WordprocessingDocument в новый файл или мой код из рабочего проекта:

    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();
    }
person anechaev    schedule 20.01.2019


Базовый подход, который вы используете, работает нормально, но я удивлен, что вы не получаете ошибок во время компиляции, потому что

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

не совместим с

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

block, поскольку IEnumerable не имеет свойства 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();
}
person Cindy Meister    schedule 21.01.2019