javams-wordopenxmldocxdocx4j

How to add custom XML storage part to Word doc - preferrably with docx4j


I'm trying to populate a Word content control with XML data using docx4j (version 3.2.1). I'm evaluating this in order to use it for invoice generation. The documents we want to generate are not very complicated so this looks like a good approach to me.

I have created the content control through Word 2010 dev tools. This is how I try to inject the XML into the docx (taken from this example):

WordprocessingMLPackage wordMLPackage = Docx4J.load(new File(input_DOCX));

FileInputStream xmlStream = new FileInputStream(new File(input_XML));

Docx4J.bind(wordMLPackage, xmlStream, Docx4J.FLAG_BIND_INSERT_XML & Docx4J.FLAG_BIND_BIND_XML);

I get the following exception:

org.docx4j.openpackaging.exceptions.Docx4JException: Couldn't find CustomXmlDataStoragePart! exiting..
    at org.docx4j.Docx4J.bind(Docx4J.java:300)
    at org.docx4j.Docx4J.bind(Docx4J.java:271)

How can I add the CustomXmlDataStoragePart with docx4j, if it doesn't exist yet? Or should/can I do this in Word directly?

Note: I decided to prepare templates in Word directly, because later on these templates must be edited by non-technical users and I don't want to burden them with extra tools, if possible.


Solution

  • You say you "created the content control through Word 2010 dev tools". Unless you mean the content control toolkit, you need to use that or better, either of the OpenDoPE Word addins. Not both.

    These tools add a custom xml part into the docx, and allow you to associate it with your content controls via XPath data bindings.

    Then, when at runtime you invoke Docx4J.bind, docx4j finds that existing custom xml part, and replaces it with the xml file you provide which contains your runtime data.