使用 OpenXML 替换 DOCX 文件中的文本 - 奇怪的内容
Use OpenXML to replace text in DOCX file - strange content
我正在尝试使用 OpenXML SDK 和 Microsoft 页面上的示例将占位符替换为 Word 文档中的真实内容。
它曾经像 here 描述的那样工作,但在 Word 中编辑模板文件添加页眉和页脚后它停止工作。我想知道为什么,一些调试向我展示了这个:
这段代码中texts
的内容是什么:
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(DocumentFile, true))
{
var texts = wordDoc.MainDocumentPart.Document.Body.Descendants<Text>().ToList();
}
所以我在这里看到的是文档正文是 "fragmented",即使在 Word 中内容看起来像这样:
谁能告诉我如何解决这个问题?
有人问我要达到什么目的。基本上我想用真实内容替换用户定义的 "placeholders" 。我想像对待模板一样对待 Word 文档。占位符可以是任何东西。在我上面的示例中,它们看起来像 {var:Template1}
,但这只是我正在玩的东西。它基本上可以是任何个词。
例如,如果文档包含以下段落:
Do not use the name USER_NAME
用户应该能够将 USER_NAME
占位符替换为单词 admin
,例如,保持格式不变。结果应该是
Do not use the name admin
我在处理段落级别、连接内容和 然后 替换段落内容时遇到的问题,我担心我丢失了应该保留的格式在
Do not use the name admin
各种各样的东西都可以使文本运行碎片化。最常见的校对标记(显然是这里的情况,其中有 "squigglies")或 rsid(用于比较文档和跟踪谁在什么时候编辑了什么),以及 "Go back" 书签 Word 集的背景。如果您在 document.xml "part" 中查看基础 WordOpenXML(例如,使用 Open XML SDK 生产力工具),这些将变得很明显。
它通常有助于达到元素级别 "higher"。在这种情况下,获取 Paragraph 后代列表并从那里获取所有 Text 后代并连接它们的 InnerText。
OpenXML 确实使您的文本碎片化:
我创建了一个 library 来执行此操作:使用 JSON.
中的值渲染一个单词模板
来自documenation of docxtemplater :
Why you should use a library for this
Docx is a zipped format that contains some xml. If you want to build a simple replace {tag} by value system, it can already become complicated, because the {tag} is internally separated into <w:t>{</w:t><w:t>tag</w:t><w:t>}</w:t>
. If you want to embed loops to iterate over an array, it becomes a real hassle.
库基本上会执行以下操作来保持格式:
如果文字是:
<w:t>Hello</w:t>
<w:t>{name</w:t>
<w:t>} !</w:t>
<w:t>How are you ?</w:t>
结果将是:
<w:t>Hello</w:t>
<w:t>John !</w:t>
<w:t>How are you ?</w:t>
您还必须用 <w:t xml:space=\"preserve\">
替换标签,以确保 space 不会被删除(如果它们在您的变量中)。
我正在尝试使用 OpenXML SDK 和 Microsoft 页面上的示例将占位符替换为 Word 文档中的真实内容。
它曾经像 here 描述的那样工作,但在 Word 中编辑模板文件添加页眉和页脚后它停止工作。我想知道为什么,一些调试向我展示了这个:
这段代码中texts
的内容是什么:
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(DocumentFile, true))
{
var texts = wordDoc.MainDocumentPart.Document.Body.Descendants<Text>().ToList();
}
所以我在这里看到的是文档正文是 "fragmented",即使在 Word 中内容看起来像这样:
谁能告诉我如何解决这个问题?
有人问我要达到什么目的。基本上我想用真实内容替换用户定义的 "placeholders" 。我想像对待模板一样对待 Word 文档。占位符可以是任何东西。在我上面的示例中,它们看起来像 {var:Template1}
,但这只是我正在玩的东西。它基本上可以是任何个词。
例如,如果文档包含以下段落:
Do not use the name USER_NAME
用户应该能够将 USER_NAME
占位符替换为单词 admin
,例如,保持格式不变。结果应该是
Do not use the name admin
我在处理段落级别、连接内容和 然后 替换段落内容时遇到的问题,我担心我丢失了应该保留的格式在
Do not use the name admin
各种各样的东西都可以使文本运行碎片化。最常见的校对标记(显然是这里的情况,其中有 "squigglies")或 rsid(用于比较文档和跟踪谁在什么时候编辑了什么),以及 "Go back" 书签 Word 集的背景。如果您在 document.xml "part" 中查看基础 WordOpenXML(例如,使用 Open XML SDK 生产力工具),这些将变得很明显。
它通常有助于达到元素级别 "higher"。在这种情况下,获取 Paragraph 后代列表并从那里获取所有 Text 后代并连接它们的 InnerText。
OpenXML 确实使您的文本碎片化:
我创建了一个 library 来执行此操作:使用 JSON.
中的值渲染一个单词模板来自documenation of docxtemplater :
Why you should use a library for this
Docx is a zipped format that contains some xml. If you want to build a simple replace {tag} by value system, it can already become complicated, because the {tag} is internally separated into
<w:t>{</w:t><w:t>tag</w:t><w:t>}</w:t>
. If you want to embed loops to iterate over an array, it becomes a real hassle.
库基本上会执行以下操作来保持格式:
如果文字是:
<w:t>Hello</w:t>
<w:t>{name</w:t>
<w:t>} !</w:t>
<w:t>How are you ?</w:t>
结果将是:
<w:t>Hello</w:t>
<w:t>John !</w:t>
<w:t>How are you ?</w:t>
您还必须用 <w:t xml:space=\"preserve\">
替换标签,以确保 space 不会被删除(如果它们在您的变量中)。