如何保持打开的 xml 文档的样式
How to keep style on open xml documents
我正在使用 open XML(Microsoft Word - .docx) 作为文件模板来自动生成其他文档。在模板文档中我定义了内容控件,并且我编写了代码来替换这些内容控件中的内容。
内容已替换,文档已生成,但我很难保持样式。在 Word 中,检查内容控件的属性时,我选中了 "Use a style to format text into the empty control: style" 的复选框,还选中了 "Remove content controls when content are edited"。当文档由代码生成时,这似乎没有任何影响。
这是我用于替换内容控件中的数据的代码(这里的一位社区成员非常友好地提供了帮助)。有什么想法我应该怎么做才能保持格式?格式是简单的文本格式,如大小和字体。请指教:
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);
}
}
当您为内容控件指定样式时,会在 SdtProperties
下添加一个新的 RunProperties
元素。例如,如果我分配一个名为 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
当您 select "Remove content control when contents are edited" 选项时,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();
}
}
我正在使用 open XML(Microsoft Word - .docx) 作为文件模板来自动生成其他文档。在模板文档中我定义了内容控件,并且我编写了代码来替换这些内容控件中的内容。
内容已替换,文档已生成,但我很难保持样式。在 Word 中,检查内容控件的属性时,我选中了 "Use a style to format text into the empty control: style" 的复选框,还选中了 "Remove content controls when content are edited"。当文档由代码生成时,这似乎没有任何影响。
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);
}
}
当您为内容控件指定样式时,会在 SdtProperties
下添加一个新的 RunProperties
元素。例如,如果我分配一个名为 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
当您 select "Remove content control when contents are edited" 选项时,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();
}
}