July 22, 2024

ODT to PDF using XDocReport and Apache Freemarker

XDocreport is an open-source Java library designed to merge and combine templates with a data model. XDocReport supports both Velocity and Freemarker as template engine and allows you to convert the finished document into PDF or XHTML format. Templates are just regular documents, created using Microsoft Word or LibreOffice, with added placeholders for any dynamic content. In this post I show how to merge a data source coming from a simple Java Pojo with an ODT Freemarker template. The finished document will be a PDF file, generated by using the built-in XDocReport converter.


JDK 1.8
Maven 3.5.9
Opensagres XDocReport 2.0.1
Apache Freemarker 2.3.23

SOURCE CODE (/giuseu/java-utilities)

git clone https://gitlab.com/giuseppeurso-eu/java-utilities

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

Use LibreOffice Writer to create the ODT template. Input fields are defined according to the Freemarker syntax.

<#-- 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}

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);

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>();
 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);



Related posts


  1. Pedro

    This dependency does not execute my code. When I remove it works only there problems in the conversion of the document.


    1. Giuseppe

      according to the provided stack, the code works correctly. On a fresh build:

      > git clone https://gitlab.com/giuseppeurso-eu/java-utilities

      > cd java-utilities/3rdpartyapi

      > mvn clean install
      > mvn dependency:tree | grep opensagres.xdocreport.converter.odt.odfdom


      What is exactly your issue?

Leave a Reply

Your email address will not be published.