Introduction
Sometimes, we find ourselves in a situation where we need to hand some sort of document filled with all sorts of generated data to the user (like an automated letter to a customer or a certificate). This can be a somewhat challenging task, especially in a Java environment. To get rid of this problem, the PrintEngine was created:
The PrintEngine is a Java based SOAP Web service that allows us to replace the bookmarks in a Word file with variable texts.
What can you do with the PrintEngine?
- Replace texts in a Word file
- Convert Word files to .pdf
- Replace texts multiple times and merge the documents, thus creating a serial letter
Background
After some research, we decided to use the Apache POI library to find and replace the bookmarks in the Word files. It has proven quite helpful, but unfortunately, the HWPF library - which is used to modify documents in the .doc format - does not offer as much functionality as we have wished and is currently not being expanded.
Therefore, please understand that the PrintEngine does not work very well with the old .doc Word format. Yet, the .doc part of the application is included in the source, and please feel free to have a look at it, maybe you will find another neat solution!
Using the PrintEngine
To get the engine running, just get the sources from GitHub and deploy it to your webserver.
If you want to test the web service right away, we recommend you also check out the PrintEngineTestClient
project and deploy it as well. You should now be able to open the index.xhtml page in your browser and check if your engine runs smoothly.
Note that this project was created using JRE 1.8 and Apache Tomcat/7.0.59.
Using the PrintEngine in your Client
Getting the engine running should be the easiest part. The main work you will have to do is embedding the PrintEngine smoothly in your client. The possibilities you can do this are endless and entirely up to you, so I will be focusing on the essential part: Calling the service with the correct data.
The Web Service provides one method:
public PrintResponseObj getDocument(PrintRequestObj request)
Your main focus should be on filling the PrintRequestObj
with the correct Data. It holds the following properties:
byte[] fileData;
String fileType;
String responseType;
ValueMap[] valueMaps;
fileData
is your template document, the original .doc or .docx file with the defined bookmarks, as a byte-arraay. fileType
holds the file type of your document, as String
. Should be either ".doc" or ".docx". responseType
holds the file type of the response document you want. Should be ".doc", ".docx" or ".pdf". valueMaps
is an array of ValueMaps
. It contains all the data the PrintEngine needs to know to replace the bookmarks in your document.
To fully explain the contents of valueMaps
, I have to go a little more into detail:
valueMaps
is an array of ValueMap
, which just contains an array of Value
. A Value
contains all information to replace one bookmark in the document.
It holds a key, which is the name of the bookmark that was defined in the Word document.
It also contains the effective values, an array of strings that contains all the values that will be inserted at the spot of the bookmark.
Then there are the prefix and the suffix: these will be inserted before and after each value.
And finally the asList
flag can be set on each Value
object. It defines if the values will be inserted seperated with newlines or separated with commas.
A ValueMap
simply holds an array of Values
. So one ValueMap
object has the data to replace all bookmarks in a document.
The valueMaps
variable holds an array of ValueMap
. Thus, for each item, the PrintEngine will replace the whole documents bookmarks once and append it to the last iteration. And like this, a serial letter could be created.
For a better overview of the valueMap
object, please have a look at the provided test page.
Example
You have a table ‘person
’ in your database. It contains three records: John
, Mike
and Pete
. You made a document you want to print for each one of them, each containing their respective names. So here is what you want to do:
For each data record, meaning each person, you have to create a ValueMap. Inside each ValueMap you can define Values, each one representing a bookmark to replace. So you do the following:
- Define an array of ValueMaps with the size 3.
ValueMap[] valueMapsExample = new ValueMap[3];
- Define three Values. Set the field ‘
key
’ to the name of the bookmark, i.e. ‘firstName
’.
ValueMap exampleValueMap1 = new ValueMap();
Value exampleValue1 = new Value();
exampleValue1.setKey("firstName");
ValueMap exampleValueMap2 = new ValueMap();
Value exampleValue2 = new Value();
exampleValue2.setKey("firstName");
ValueMap exampleValueMap3 = new ValueMap();
Value exampleValue3 = new Value();
exampleValue3.setKey("firstName");
- Fill the Values with the names ‘
John
’, ‘Mike
’ and ‘Pete
’ and fill the ValueMaps
with those new Values
.
exampleValue1.setValues(new String[]{"John"});
exampleValue2.setValues(new String[]{"Mike"});
exampleValue3.setValues(new String[]{"Pete"});
exampleValueMap1.setValueMap(new Value[]{exampleValue1});
exampleValueMap2.setValueMap(new Value[]{exampleValue2});
exampleValueMap3.setValueMap(new Value[]{exampleValue3});
- Now, we just have to add the three created
ValueMaps
to the initially created array of valueMaps
.
valueMapsExample[0] = exampleValueMap1;
valueMapsExample[1] = exampleValueMap2;
valueMapsExample[2] = exampleValueMap3;
Now, you can send the document along with the array of ValueMaps
(valueMapsExample
) to the PrintEngine and it will replace the bookmarks for you.
Further Work
If you find this article useful, please feel free to make or suggest changes in any way. Also feel free to ask questions or give feedback anytime. Thanks for reading!
History