XDocreport è una libreria open-source scritta in Java, che permette di manipolare documenti MS Office e LibreOffice in cui sono definiti form, campi variabili e macro. La libreria supporta i template engine Velocity e Freemarker, entrambi di Apache e permette la conversione dei documenti a partire dal modello di origine (docx, pptx, odt, ods) nei formati PDF e XHTML. In questo articolo riporto un esempio di come utilizzare XDocReport per fare il merge di un modello dati rappresentato da un semplice Pojo Java su un template ODT creato con LibreOffice (i field sono definiti in sintassi Freemarker ma ovviamente la scelta è del tutto personale). Il risultato finale è un file PDF generato utilizzando il converter di XDocReport.
Stack
JDK 1.8
Maven 3.5.9
Opensagres XDocReport 2.0.1
Apache Freemarker 2.3.23
Customer POJO
// A model for the Customer. public class CustomerPojo { // Customer attributes with Getters and Setters here... private String name; private String surname; private String email; }
ODT Freemarker Template
Creare il template ODT con LibreOffice Writer. Gli input field vengono gestiti con Freemarker.
<#-- Freemarker code snippet related to the Customer --> <#-- ${foo}!'' expression handles missing values --> Name ${customer.name!''} Surname ${customer.surname!''} Email ${customer.email!''} [#list customer.addressList as address] Address ${address?counter} - ${address.street} - ${address.streetNumber} - ${address.city} - ${address.state} [/#list]
XDocReport Engine
//Load ODT file and set the template engine to Freemarker IXDocReport xdocGenerator = XDocReportRegistry.getRegistry().loadReport(templateOdtInputStream,TemplateEngineKind.Freemarker); IContext context = xdocGenerator.createContext(); //Configuring the XDOCReport Context by registering the Customer Java model with a key. //we use key "customer" in the ODT freemarker template to reference the java object. context.put("customer", customer); //Set format converter ODT to PDF Options options = Options.getFrom(DocumentKind.ODT).to(ConverterTypeTo.PDF); //Merge Java model with the ODT and convert it to PDF xdocGenerator.convert(context, options, pdfOutputStream); templateOdtInputStream.close(); pdfOutputStream.close();
Main Executor
AddressPojo addr1 = new AddressPojo("Iron Maiden", "666", "Leyton", "England"); AddressPojo addr2 = new AddressPojo("Kiss", "1973", "New York City", "US"); AddressPojo addr3 = new AddressPojo("Metallica", "1986", "Los Angeles", "US"); List<AddressPojo> addrList = new ArrayList<CustomerPojo.AddressPojo>(); addrList.add(addr1); addrList.add(addr2); addrList.add(addr3); CustomerPojo customer = new CustomerPojo("Lemmy", "Kilmister", "motorhead@metal.net", "666666", addrList); File templateOdt = new File("src/main/resources/customer-template.ftl.odt"); File generatedPdf = new File("target/generated-report.pdf"); //Generating the PDF file by using XDocReport InputStream odtStream = FileUtils.openInputStream(templateOdt); OutputStream pdfStream = new FileOutputStream(generatedPdf); XdocreportGenerator.createPdf(odtStream, pdfStream, customer);