I am taking the docx file as a template, and when writing variables(${}) with Microsoft Word, not seeing some variables
But when I am changing it on LibreOffice, it is working(java seeing variable), but I can't do it everytime with 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 of Docx file:
<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>
As you see brackets goes other runs, but when with 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>
And the Error:
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.
Root cause
Word's text proofing feature have wrapped lessonsEachWeek
text into some tags splitting it out from ${
and }
tokens. Given such document docx4j tries to find substitution for key </w:t></w:r><w:r><w:rPr>...lessonsEachWeek...</w:rPr><w:t xml:space="preserve">
while there is no such key, of course.
Solution
For existing document i was unable to find automated and graceful way to remove these wrapping tags, unfortunately. Disabling spell check in Word, rechecking and saving document doesn't work for some reason. I have done some "manual surgery": opened docx file in 7z as zip file, located \word\document.xml in it, F4 (edit) and removed these wrapping tags. 7z repacked zip file, Word still opens it without a problem while my Java / Kotlin application can now substitute keys that were fixed! Any similar archiver and editor should also do the trick.
How to avoid this problem in new documents
Disable text proofing in Word when creating such templates.
"File" -> "Options" -> "Proofing", uncheck all checkboxes in "When correcting spelling and grammar in Word" section.