Templ4docx - Easy way to fill docx templates
A few days ago, I had to prepare Proof-of-Concept connected with filling templates prepared in docx. I took into account two libraries: org.docx4j and apache-poi. After a short play with them, the second library appears to be more suitable in my case. In order to compare these two libraries I’ve prepared two classes that perform the same operations:
- reading docx file
- finding all variables in docx file
- replacing (filling) variables in the template
- saving filled template
Docx4j | Apache-poi | |
---|---|---|
Operation | ||
Reading | 5599 ms | 921,3 ms |
Finding variables | 205,8 ms | 34,51 ms |
Filling template | 65,46 ms | 129,6 ms |
Saving template | 99,38 ms | 267,7 ms |
Test docx template
Doc4j test classes
Stopwatch stopwatch = Stopwatch.createStarted();
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(path));
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
stopwatch.stop();
System.out.println("READ FILE : " + stopwatch);
stopwatch = Stopwatch.createStarted();
List<String> tagValues = getTagValues(documentPart.getXML());
stopwatch.stop();
System.out.println("FIND VARIABLES : " + stopwatch);
stopwatch = Stopwatch.createStarted();
documentPart.variableReplace(mappings);
stopwatch.stop();
System.out.println("REPLACE VARIABLES : " + stopwatch);
stopwatch = Stopwatch.createStarted();
wordMLPackage.save(new java.io.File(outputPath));
stopwatch.stop();
System.out.println("SAVE DOCUMENT : " + stopwatch);
...
private static List<String> getTagValues(final String str) {
final List<String> tagValues = new ArrayList<String>();
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
tagValues.add(matcher.group());
}
return tagValues;
}
Apache-POI test classes
Stopwatch stopwatch = Stopwatch.createStarted();
FileInputStream fis = new FileInputStream(path);
XWPFDocument xdoc = new XWPFDocument(OPCPackage.open(fis));
stopwatch.stop();
System.out.println("READ FILE : " + stopwatch);
XWPFWordExtractor extractor = new XWPFWordExtractor(xdoc);
stopwatch = Stopwatch.createStarted();
List<String> tags = getTagValues(extractor.getText());
stopwatch.stop();
System.out.println("FIND VARIABLES: " + stopwatch);
stopwatch = Stopwatch.createStarted();
replace(xdoc, mappings);
stopwatch.stop();
System.out.println("REPLACE VARIABLES: " + stopwatch);
stopwatch = Stopwatch.createStarted();
xdoc.write(new FileOutputStream(outputPath));
stopwatch.stop();
System.out.println("SAVE DOCUMENT: " + stopwatch);
extractor.close();
...
private List<String> getTagValues(final String str) {
final List<String> tagValues = new ArrayList<String>();
Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
tagValues.add(matcher.group());
}
return tagValues;
}
Templ4docx
Given these results, I’ve chosen apache-poi library. Unfortunately, this library hasn’t any method to find variables in template and replace variables.
For this reason I’ve decided to write utility library to work with templates in docx. The heart of the library is Template
class which allows you to read docx, find all variables for given pattern, replace variables and save filled template. The example usage of templ4docx is presented below:
Deprecated
The following section concerns the version 1.0.1 The current version is 2.0.0. Read more about this version:
Text VariablesImage Variables
Bullet list Variables
Table Variables
// create new instance of docx template
Docx docx = new Docx("template.docx");
// set the variable pattern. In this example the pattern is as follows: #{variableName}
docx.setVariablePattern(new VariablePattern("#{", "}"));
// read docx content as simple text
String content = docx.readTextContent();
// and display it
System.out.println(content);
// find all variables satisfying the pattern #{...}
List<String> findVariables = docx.findVariables();
// and display it
for (String var : findVariables) {
System.out.println("VARIABLE => " + var);
}
// prepare map of variables for template
Variables var = new Variables();
var.addTextVariable(new TextVariable("#{name}", "Lukasz"));
// fill template by given map of variables
docx.fillTemplate(var);
// save filled document
docx.save("output.docx");
How to start ?
The recommended way to get started using templ4docx in your project is a dependency management system – the snippet below can be copied and pasted into your build.
<dependency>
<groupId>pl.jsolve</groupId>
<artifactId>templ4docx</artifactId>
<version>2.0.0</version>
</dependency>