如何在打开的xml文档上保留样式

时间:2015-03-17 06:43:59

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

我使用开放式XML(Microsoft Word - .docx)作为文件模板来自动生成其他文档。在模板文档中,我定义了内容控件,并且我编写了代码来替换这些内容控件中的内容。

更换内容并生成文档,但我正在努力保持风格。在Word中,当检查内容控件的属性时,我已经检查了checbox"使用样式将文本格式化为空控件:style",并且还检查"当内容时删除内容控件编辑"。当代码生成文档时,这似乎没有任何影响。

Here is how I set the properties of the content control in Word 这是我的代码(这里的社区成员非常友好地帮助)来替换内容控件中的数据。任何想法,我应该做什么,以保持格式?格式化是简单的文本格式,如大小和字体。请指教:

    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 个答案:

答案 0 :(得分:6)

为内容控件指定样式时,RunProperties下会添加一个新的SdtProperties元素。例如,如果我分配一个名为Style1的新样式,我可以看到生成以下XML:

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

您需要获取此值并将其分配给您正在创建的新Paragraph,并将Paragraph添加到与SdtBlock相同的级别,然后移除SdtBlock这是Word在您选择“编辑内容时删除内容控件”选项时所执行的操作。 RunProperties<w:rPr>元素。以下应该做你想要的。

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();
    }
}