I am responsible for a Play! intranet that generates word documents using templates that have a .docx extension. To achieve this, we have the following inheritance tree : Document > Word > [someDocument]
The abstract class Word handles replacing variables in Word documents
public abstract class Word extends Document {
public static JAXBContext context = org.docx4j.jaxb.Context.jc;
public Word(String inputfilepath){
super(inputfilepath);
}
public String generer(String outputfilepath) throws Exception {
//String inputfilepath = System.getProperty("user.dir")+"/app/doc/adhesionTemplate.docx";
//String outputfilepath = System.getProperty("user.dir")+ "/test-out.docx";
// Open a document from the file system
// 1. Load the Package
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
// 2. Fetch the document part
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document) documentPart.getJaxbElement();
// xml --> string
String xml = XmlUtils.marshaltoString(wmlDocumentEl, true);
//Change the variables using an abstract function getMapping()
HashMap<String, String> mappings = getMapping();
Object obj = XmlUtils.unmarshallFromTemplate(xml, mappings);
// change JaxbElement
documentPart.setJaxbElement((org.docx4j.wml.Document) obj);
//Footers :
List<SectionWrapper> wrappers = wordMLPackage.getDocumentModel().getSections();
for (SectionWrapper sw : wrappers) {
FooterPart footer = sw.getHeaderFooterPolicy().getDefaultFooter();
if (footer != null) {
Ftr footerDoc = footer.getJaxbElement();
String footerXml = XmlUtils.marshaltoString(footerDoc, true);
Object footerObj = XmlUtils.unmarshallFromTemplate(footerXml, mappings);
footer.setJaxbElement( (Ftr) footerObj);
}
}
// Save it
SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
saver.save(outputfilepath);
Console.commande("sudo chmod 660 \"" + outputfilepath + "\"");
System.out.println("Saved output to:" + outputfilepath);
return outputfilepath;
}
Then, we have classes that inherit from this Word abstract class:
public class FAC extends Word {
public FAC() {
super(System.getProperty("user.dir") + "/templates/Facture.docx");
}
@Override
public HashMap<String, String> getMapping() {
//Preparing variables
int price = blablabla;
HashMap<String, String> map = new HashMap<String, String>();
map.put("FACDate", Utils.dateConvert(new Date()));
map.put("somePrice", String.valueOf(price));
return map;
}
}
Note : the "Document" superclass has nothing special, just a variable "inputFilePath", and the abstract method getMapping()
Hope this help, either you or future viewers like me :P