I have a document template where some fields are static and others are dynamic. I need to replace some data (name, last name, salary) and generate the new file. What library do you recommend to do this? Is POI appropriate? I am working with Spring, Java EE6 and Oracle.
You can give Apache POI a try but the HWPF and XWPF part of POI which are required to manipulate word files are really complicated to use - you need to have at least a good understanding how a word file is structured!
Solution using iText and PDF
I did something similar with PDF (this might be an option for you)
1) You can use LibreOffice to create fields in the document (like in Acrobat Pro)
2) Now you can use iText to fill in the created fields
The following is just example code:
public byte[] getDocumentAsByteArray(Object dataBean, String pdfTemplateName) throws KkmsException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamp = null;
InputStream templateInputStream = null;
Locale local = new Locale(language);
try {
templateInputStream = // get the file input stream of the pdf
PdfReader reader = new PdfReader(templateInputStream);
// Create a stamper that will copy the document to a new file
stamp = new PdfStamper(reader, outputStream);
AcroFields form = stamp.getAcroFields();
// form fields are normal text in the end
stamp.setFormFlattening(true);
Map<String, AcroFields.Item> map = (Map<String, AcroFields.Item>)form.getFields();
if (map != null) {
if (map.size() == 0) {
logger.debug("There are no fields in this PDF layout");
}
for (Entry<String, AcroFields.Item> e : map.entrySet()) {
logger.debug("PDF fieldname = " + e.getKey());
// at the moment we only handle text fields
if (AcroFields.FIELD_TYPE_TEXT == form.getFieldType(e.getKey())) {
fillForm(dataBean, form, e.getKey(), local);
} else {
logger.warn("Field type is not supported: "+form.getFieldType(e.getKey()));
}
}
}
stamp.close();
} catch (Exception e) {
logger.warn("Failed to create PDF document", e);
throw new KkmsException("Failed to create PDF document: "+e.getMessage());
} finally {
if (templateInputStream != null) {
try {
templateInputStream.close();
} catch (IOException e) {
throw new KkmsException("Failed to close InputStream of PDF document", e);
}
}
}
return outputStream.toByteArray();
}
In the end you get a PDF -> hope this helps you at least a little bit!
Another quick and dirty solution
Could be to use the power of odt or docx -> convert your doc to docx or odt -> its just a zip file -> so unzip it -> you will see a content.xml file in the root of the zip -> there is all the document content in there Now you could add some magic tags (e.g. $$$) here which can later be replaced by your program
<text:p text:style-name="P3">SAP Customer Number:</text:p>
<text:p text:style-name="P3">SAP Customer Number: $$$sapCustomerNumber$$$</text:p>
Now create a program which unzips the odt/docx file -> replaces the tags -> zips the file again