How to keep style on open xml documents

隐身守侯 提交于 2019-12-19 03:58:10

问题


I am using open XML(Microsoft Word - .docx) as a file template to automatically generate other documents. In the template document I have defined content controls, and I have written code to replace content in these content controls.

The content is replaced and the documents are generated, but I am struggling with keeping the style. In Word, when inspecting properties of the content control, I have checked the checbox for "Use a style to format text into the empty control: style", and also checked for "Remove content controls when content are edited". This doesn't seem to have any impact when documents are generated by code.

This is my code (which a community member here was kind enough to help with) for replacing the data in the content controls. Any ideas what I should do in order to keep the formatting? The formatting is simple text formatting, like size and font. Please advice:
    private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue)
    {
        //grab all the tag fields
        var tagFields = mainPart.Document.Body.Descendants<SdtBlock>().Where
            (r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName);

        foreach (var field in tagFields)
        {
            //remove all paragraphs from the content block
            field.SdtContentBlock.RemoveAllChildren<DocumentFormat.OpenXml.Wordprocessing.Paragraph>();
            //create a new paragraph containing a run and a text element
            var newParagraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
            var newRun = new DocumentFormat.OpenXml.Wordprocessing.Run();
            var newText = new DocumentFormat.OpenXml.Wordprocessing.Text(tagValue);
            newRun.Append(newText);
            newParagraph.Append(newRun);
            //add the new paragraph to the content block
            field.SdtContentBlock.Append(newParagraph);
        }
    }

回答1:


When you assign a style to the content control a new RunProperties element is added under the SdtProperties. For example, if I assign a new style called Style1 I can see the following XML is generated:

<w:sdt>
    <w:sdtPr>
        <w:rPr>
            <w:rStyle w:val="Style1" />
        </w:rPr>
    <w:alias w:val="LastName" />
    <w:tag w:val="LastName" />
    ....

You need to grab this value and assign it to the new Paragraph you are creating, add the Paragraph at the same level as the SdtBlock and then remove the SdtBlock which is what Word does when you select the "Remove content control when contents are edited" option. The RunProperties are the <w:rPr> element. The following should do what you're after.

private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue)
{
    //grab all the tag fields
    IEnumerable<SdtBlock> tagFields = mainPart.Document.Body.Descendants<SdtBlock>().Where
        (r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName);

    foreach (var field in tagFields)
    {
        //grab the RunProperties from the SdtBlcok
        RunProperties runProp = field.SdtProperties.GetFirstChild<RunProperties>();

        //create a new paragraph containing a run and a text element
        Paragraph newParagraph = new Paragraph();
        Run newRun = new Run();
        if (runProp != null)
        {
            //assign the RunProperties to our new run
            newRun.Append(runProp.CloneNode(true));
        }
        Text newText = new Text(tagValue);
        newRun.Append(newText);
        newParagraph.Append(newRun);
        //insert the new paragraph before the field we're going to remove
        field.Parent.InsertBefore(newParagraph, field);

        //remove the SdtBlock to mimic the Remove content control when contents are edited option
        field.Remove();
    }
}


来源:https://stackoverflow.com/questions/29092858/how-to-keep-style-on-open-xml-documents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!