4

I have the following scenario, and need some advice:

The user will input a word document as a template, and provide some parameters in runtime so i can query my database and get data to fill the document. So, there are two basic things i need to do:

  1. Replace every key in the document with it´s respective result from the current query line.
  2. "Merge" (copy? duplicate?) the existing document unchanged into itself (append) depending on how many rows i got from the query, and replacing the keys from this new copy with the next row values.

What´s is the best aprroach to do this? I´ve managed to do the replace part for now, by using the unmarshallfromtemplate providing it a hashmap. But this way is a little bit tricky, because i need to add "${variable_name}" in the document, and sometimes word separates "${" and "}" in different tags, causing issues.

I´ve read about the custom xml binding, but didn´t understand it completely. I need to generate a custom XML, inject it in the document (all of this un runtime) and call the applybindings?? If this is true, how would i bind the fields in the document to the xml ? By name?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
wilson
  • 281
  • 6
  • 22

1 Answers1

7

docx4j includes VariablePrepare, which can tidy up your input docx so that your keys are not split across separate runs.

But, you would still be better off switching to content control data binding, particularly if you have repeated data (think for example of line items in an invoice). Disclosure: I champion this approach in docx4j.

To adopt the content control data binding approach:

  1. dream up an XML format which makes sense for your data, and write some code to convert the results of your database query into that format.

  2. modify your template, so that the content controls are bound to elements in your XML document. ordinarily you'd use an authoring add-in for Word to help with this. (The technology Microsoft uses for binding is XPath, so how you bind depends on your XML structure, but, yes, you'd typically bind to the element name or ID).

  3. now you have your XML file and a suitable intput docx, ContentControlsMergeXML contains the code you need to create an instance document at run time. There's also a version of this for a servlet environment at https://github.com/plutext/OpenDoPE-WAR

As an alternative to 1 & 2, there is also org.docx4j.model.datastorage.migration.FromVariableReplacement in current nightlies, which can convert your existing "${" document. Only to a standardised target XML format though.

If you have further questions, there is a forum devoted to this topic at http://www.docx4java.org/forums/data-binding-java-f16/

JasonPlutext
  • 15,352
  • 4
  • 44
  • 84