我对您尝试做的事情的理解是在您的文档中插入一个脏的w:fldSimple 元素(SimpleField 类),以使 Word 更新所有字段,包括目录,一旦用户使用 Microsoft Word 打开该文档.但是,如果您在更新字段后查看 Microsoft Word 生成的 Open XML 标记,您会发现您的w:fldSimple 是罪魁祸首。
我创建了以下代码来生成一个简单的 Word 文档,其中(几乎)只有一个字段:
[Fact]
public void CheckBookmarkNotDefined()
{
using WordprocessingDocument wordDocument = WordprocessingDocument.Create(
"SimpleField.docx", WordprocessingDocumentType.Document);
MainDocumentPart part = wordDocument.AddMainDocumentPart();
part.Document =
new Document(
new Body(
new Paragraph(
new SimpleField
{
Instruction = "sdtContent",
Dirty = true
})));
}
以上代码在主文档部分创建了以下 Open XML 标记:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:fldSimple w:instr="sdtContent" w:dirty="true" />
</w:p>
</w:body>
</w:document>
请注意,w:fldSimple 元素包含在 w:p 元素(Paragraph 类)中,因为将其添加到 w:body 元素(Body 类)会产生无效的 Open XML 标记。
在 Microsoft Word 中打开该文档,更新字段并保存文档,使 Word 创建以下 Open XML 标记(我已经简化了一点):
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:fldChar w:fldCharType="begin"/>
</w:r>
<w:r>
<w:instrText>sdtContent</w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType="separate"/>
</w:r>
<w:r>
<w:rPr>
<w:b/>
<w:bCs/>
</w:rPr>
<w:t>Error! Bookmark not defined.</w:t>
</w:r>
<w:r>
<w:fldChar w:fldCharType="end"/>
</w:r>
</w:p>
<w:sectPr>
[Child elements removed for clarity]
</w:sectPr>
</w:body>
</w:document>
您可以看到 Word 已将简单字段(w:fldSimple 元素)转换为复杂字段,使用多个 w:fldChar 元素和一个以“sdtContent”为内容的w:instrText 元素。此外,您可以看到文本“错误!未定义书签”。作为该字段的结果。
Word 会创建该错误消息,因为您的说明文本 ("sdtContent") 不正确。如果您将"sdtContent" 替换为有效的字段名称,例如"AUTONUM",您将不会看到该错误消息。但是,在AUTONUM 的情况下,您显然会得到一个可见的字段结果。为避免这种情况,您可以使用REF 字段,但是您需要一个有效的书签。这是在以下示例中创建的:
[Fact]
public void CreateSimpleFieldForAutomaticUpdate()
{
using WordprocessingDocument wordDocument = WordprocessingDocument.Create(
"SimpleFieldRef.docx", WordprocessingDocumentType.Document);
MainDocumentPart part = wordDocument.AddMainDocumentPart();
part.Document =
new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello World!"))),
new BookmarkStart { Id = "32767", Name = "_RefUpdate" },
new BookmarkEnd { Id = "32767" },
new Paragraph(
new SimpleField
{
Instruction = "REF _RefUpdate",
Dirty = true
}),
new SectionProperties()));
}
您必须编写代码来插入 w:bookmarkStart 元素(BookmarkStart 类)、w:bookmarkEnd 元素(BookmarkEnd 类)和 w:p 元素与您的 w:fldSimple 子元素之前w:sectPr 元素(SectionProperties 类)。在我的示例中,我使用了一个大整数值作为书签 id,_RefUpdate 作为书签名称,Instruction 属性中也使用了该名称。