变量替换有时不起作用
VariableReplacing is not working sometimes
我以docx文件为模板,用Microsoft Word写变量(${})时,没有看到一些变量
但是当我在 LibreOffice 上更改它时,它正在工作(java 看到变量),但我不能每次使用 LibreOffice 都这样做!
File doc = new File("nameOfMyFile.docx");
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc);
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
HashMap mappings = new HashMap();
VariablePrepare.prepare(wordMLPackage);
mappings.put("lessonsEachWeek", contract.getHoursInWeek());
wordMLPackage.getMainDocumentPart().variableReplace(mappings);
Docx4J.save(wordMLPackage, new File("someName.docx"));
XML 个 Docx 文件:
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t xml:space="preserve">1.2 some text ${</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:val="en-US" w:eastAsia="ru-RU"/>
</w:rPr>
<w:t>lessonsEachWeek</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t xml:space="preserve">} some text</w:t>
</w:r>
</w:p>
如您所见,括号会出现在其他运行中,但在使用 LibreOffice 时:
<w:r>
<w:rPr>
<w:rFonts w:eastAsia="Times New Roman" w:cs="Calibri"/>
<w:b/>
<w:bCs/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t>${lessonsEachWeek}</w:t>
</w:r>
错误:
2019-07-17 15:00:57.097 WARN 10717 --- [nio-8080-exec-5] org.docx4j.XmlUtils : Invalid key '</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:val="en-US" w:eastAsia="ru-RU"/></w:rPr><w:t>lessonsEachWeek</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:eastAsia="ru-RU"/></w:rPr><w:t xml:space="preserve">' or key not mapped to a value
2019-07-17 15:00:57.097 WARN 10717 --- [nio-8080-exec-5] org.docx4j.XmlUtils : Invalid key '</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:val="en-US" w:eastAsia="ru-RU"/></w:rPr><w:t>lessonsEachWeek</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:eastAsia="ru-RU"/></w:rPr><w:t xml:space="preserve">' or key not mapped to a value
2019-07-17 15:00:57.135 INFO 10717 --- [nio-8080-exec-5] o.d.o.parts.WordprocessingML.BinaryPart : .. closed.
根本原因
Word 的文本校对功能已将 lessonsEachWeek
文本包装到一些标记中,将其从 ${
和 }
标记中分离出来。给定这样的文档,docx4j 会尝试找到键 </w:t></w:r><w:r><w:rPr>...lessonsEachWeek...</w:rPr><w:t xml:space="preserve">
的替代,当然没有这样的键。
解决方案
不幸的是,对于现有文档,我无法找到自动且优雅的方式来删除这些包装标签。由于某些原因,禁用 Word 中的拼写检查、重新检查和保存文档不起作用。我做了一些 "manual surgery":在 7z 中打开 docx 文件作为 zip 文件,位于 \word\document.xml 中,F4(编辑)并删除这些包装标签。 7z 重新打包的 zip 文件,Word 仍然可以毫无问题地打开它,而我的 Java / Kotlin 应用程序现在可以替换已修复的密钥!任何类似的存档器和编辑器也应该可以做到这一点。
如何在新文档中避免这个问题
创建此类模板时禁用 Word 中的文本校对。
"File" -> "Options" -> "Proofing",取消选中 "When correcting spelling and grammar in Word" 部分中的所有复选框。
我以docx文件为模板,用Microsoft Word写变量(${})时,没有看到一些变量
但是当我在 LibreOffice 上更改它时,它正在工作(java 看到变量),但我不能每次使用 LibreOffice 都这样做!
File doc = new File("nameOfMyFile.docx");
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(doc);
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
HashMap mappings = new HashMap();
VariablePrepare.prepare(wordMLPackage);
mappings.put("lessonsEachWeek", contract.getHoursInWeek());
wordMLPackage.getMainDocumentPart().variableReplace(mappings);
Docx4J.save(wordMLPackage, new File("someName.docx"));
XML 个 Docx 文件:
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t xml:space="preserve">1.2 some text ${</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:val="en-US" w:eastAsia="ru-RU"/>
</w:rPr>
<w:t>lessonsEachWeek</w:t>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t xml:space="preserve">} some text</w:t>
</w:r>
</w:p>
如您所见,括号会出现在其他运行中,但在使用 LibreOffice 时:
<w:r>
<w:rPr>
<w:rFonts w:eastAsia="Times New Roman" w:cs="Calibri"/>
<w:b/>
<w:bCs/>
<w:color w:val="000000"/>
<w:lang w:eastAsia="ru-RU"/>
</w:rPr>
<w:t>${lessonsEachWeek}</w:t>
</w:r>
错误:
2019-07-17 15:00:57.097 WARN 10717 --- [nio-8080-exec-5] org.docx4j.XmlUtils : Invalid key '</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:val="en-US" w:eastAsia="ru-RU"/></w:rPr><w:t>lessonsEachWeek</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:eastAsia="ru-RU"/></w:rPr><w:t xml:space="preserve">' or key not mapped to a value
2019-07-17 15:00:57.097 WARN 10717 --- [nio-8080-exec-5] org.docx4j.XmlUtils : Invalid key '</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:val="en-US" w:eastAsia="ru-RU"/></w:rPr><w:t>lessonsEachWeek</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="Times New Roman" w:cs="Times New Roman"/><w:color w:val="000000"/><w:lang w:eastAsia="ru-RU"/></w:rPr><w:t xml:space="preserve">' or key not mapped to a value
2019-07-17 15:00:57.135 INFO 10717 --- [nio-8080-exec-5] o.d.o.parts.WordprocessingML.BinaryPart : .. closed.
根本原因
Word 的文本校对功能已将 lessonsEachWeek
文本包装到一些标记中,将其从 ${
和 }
标记中分离出来。给定这样的文档,docx4j 会尝试找到键 </w:t></w:r><w:r><w:rPr>...lessonsEachWeek...</w:rPr><w:t xml:space="preserve">
的替代,当然没有这样的键。
解决方案
不幸的是,对于现有文档,我无法找到自动且优雅的方式来删除这些包装标签。由于某些原因,禁用 Word 中的拼写检查、重新检查和保存文档不起作用。我做了一些 "manual surgery":在 7z 中打开 docx 文件作为 zip 文件,位于 \word\document.xml 中,F4(编辑)并删除这些包装标签。 7z 重新打包的 zip 文件,Word 仍然可以毫无问题地打开它,而我的 Java / Kotlin 应用程序现在可以替换已修复的密钥!任何类似的存档器和编辑器也应该可以做到这一点。
如何在新文档中避免这个问题
创建此类模板时禁用 Word 中的文本校对。
"File" -> "Options" -> "Proofing",取消选中 "When correcting spelling and grammar in Word" 部分中的所有复选框。