Java Export PDF File from HTML Template
Tags: ClassLoaderTemplateResolver TemplateEngine ITextRenderer pdf export pdf Thymeleaf
In this Java tutorial we learn how to export .pdf files from HTML template files using the Thymeleaf and Flying Saucer PDF libraries.
Table of contents
- Add Thymeleaf and Flying Saucer PDF libraries
- Implement Exporter Class to Generate PDF File
- Add HTML Template File to resources directory
- Implement DTO classes
- Implement Main Class to Generate PDF File
- Download Source Code
Add Thymeleaf and Flying Saucer PDF libraries
To use the Thymeleaf and Flying Saucer PDF libraries in the Gradle build project, add the following dependency into the build.gradle file.
implementation group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.13.RELEASE'
implementation group: 'org.xhtmlrenderer', name: 'flying-saucer-pdf', version: '9.1.22'
To use the Thymeleaf and Flying Saucer PDF libraries in the Maven build project, add the following dependency into the pom.xml file.
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
Implement Exporter Class to Generate PDF File
Create a new Java class named PdfFileExporter, in this class we use Thymeleaf template engine to populate the HTML content from a given template file name and data in method generateHtml(). And then we implement the exportPdfFile() method to write the .pdf file from HTML content.
PdfFileExporter.java
import com.lowagie.text.DocumentException;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Map;
public class PdfFileExporter {
public void exportPdfFile(String templateFileName, Map<String, Object> data, String pdfFileName) {
String htmlContent = generateHtml(templateFileName, data);
try {
FileOutputStream fileOutputStream = new FileOutputStream(pdfFileName);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(htmlContent);
renderer.layout();
renderer.createPDF(fileOutputStream, false);
renderer.finishPDF();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
private String generateHtml(String templateFileName, Map<String, Object> data) {
TemplateEngine templateEngine = createTemplateEngine();
Context context = new Context();
context.setVariables(data);
String htmlContent = templateEngine.process(templateFileName, context);
return htmlContent;
}
private TemplateEngine createTemplateEngine() {
ClassLoaderTemplateResolver pdfTemplateResolver = new ClassLoaderTemplateResolver();
pdfTemplateResolver.setPrefix("pdf-templates/");
pdfTemplateResolver.setSuffix(".html");
pdfTemplateResolver.setTemplateMode("HTML5");
pdfTemplateResolver.setCharacterEncoding("UTF-8");
pdfTemplateResolver.setOrder(1);
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(pdfTemplateResolver);
return templateEngine;
}
}
Add HTML Template File to resources directory
For example, we need to implement a program to export the supply order form to PDF file.
At this step we create new HTML template file in Thymeleaf format under resources/pdf-templates directory with file named order-template.html as below.
resources/pdf-templates/order-template.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<style>
h1 {
color: #25a7e7;
text-align: center;
}
.order {
width: 100%;
}
.order, .order th, .order td {
border: 1px solid #25a7e7;
border-collapse: collapse;
}
.order th {
background-color: #25a7e7;
color: white;
}
.total {
text-align: right;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<img width="80" src="https://simplesolution.dev/images/Logo_S_v1.png" />
</td>
<td>
<h1>Supply Order Form</h1>
</td>
</tr>
</table>
<div>
<table>
<tr>
<td th:text="'Date: ' + ${#dates.format(order.date, 'dd/MM/yyyy')}"></td>
</tr>
<tr>
<td th:text="'Order #: ' + ${order.orderNo}"></td>
</tr>
<tr>
<td th:text="'Request Date: ' + ${#dates.format(order.requestDate, 'dd/MM/yyyy')}"></td>
</tr>
<tr>
<td th:text="'Order Date: ' + ${#dates.format(order.orderDate, 'dd/MM/yyyy')}"></td>
</tr>
</table>
</div>
<br />
<table class="order">
<tr>
<th>Item #</th>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
<tr th:each="item, iterStat: ${orderItems}">
<td th:text="${iterStat.index + 1}"></td>
<td th:text="${item.description}"></td>
<td th:text="${item.quantity}"></td>
<td th:text="${item.unitPrice}"></td>
<td th:text="${item.total}"></td>
</tr>
<tr>
<td class="total" colspan="4"><b>Total</b></td>
<td><b th:text="${#aggregates.sum(orderItems.{total})}"></b></td>
</tr>
</table>
</body>
</html>
Implement DTO classes
In order to process the HTML template file above we add DTO classed named Order and OrderItem as below.
Order.java
import java.util.Date;
public class Order {
private String orderNo;
private Date date;
private Date requestDate;
private Date orderDate;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Date getRequestDate() {
return requestDate;
}
public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
}
OrderItem.java
public class OrderItem {
private String description;
private Integer quantity;
private Double unitPrice;
private Double total;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Double getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(Double unitPrice) {
this.unitPrice = unitPrice;
}
public Double getTotal() {
return total;
}
public void setTotal(Double total) {
this.total = total;
}
}
Implement Main Class to Generate PDF File
At this step we implement a Main class with create some test data and use PdfFileExporter class to export PDF file.
Main.java
import java.util.*;
public class Main {
public static void main(String... args) {
PdfFileExporter pdfFileExporter = new PdfFileExporter();
Map<String, Object> data = createTestData();
String pdfFileName = "D:\\SimpleSolution\\order.pdf";
pdfFileExporter.exportPdfFile("order-template", data, pdfFileName);
}
private static Map<String, Object> createTestData() {
Map<String, Object> data = new HashMap<>();
Order order = new Order();
order.setOrderNo("ABC-12345");
order.setDate(new Date());
order.setOrderDate(new Date());
order.setRequestDate(new Date());
data.put("order", order);
List<OrderItem> orderItems = new ArrayList<>();
OrderItem orderItem1 = new OrderItem();
orderItem1.setDescription("Test Order Item 1");
orderItem1.setQuantity(1);
orderItem1.setUnitPrice(100.0);
orderItem1.setTotal(100.0);
orderItems.add(orderItem1);
OrderItem orderItem2 = new OrderItem();
orderItem2.setDescription("Test Order 2");
orderItem2.setQuantity(5);
orderItem2.setUnitPrice(50.0);
orderItem2.setTotal(250.0);
orderItems.add(orderItem2);
OrderItem orderItem3 = new OrderItem();
orderItem3.setDescription("Test Order 3");
orderItem3.setQuantity(2);
orderItem3.setUnitPrice(200.0);
orderItem3.setTotal(400.0);
orderItems.add(orderItem3);
data.put("orderItems", orderItems);
return data;
}
}
Execute the above Java program the PDF file will be exported at D:\SimpleSolution\order.pdf, then open the file with an PDF reader you can see the PDF file content as below.
Download The Source Code
The source code in this article can be found at: github.com/simplesolutiondev/java-export-pdf
or clone at:
git clone https://github.com/simplesolutiondev/java-export-pdf.git
or download at:
Happy Coding 😊
Related Articles
Spring Boot Generate PDF File from HTML Template
Spring Boot Web Download PDF File from HTML Template