Generate PDFs with Spring Boot 3, iText, and Thymeleaf – 170 Real‑World Cases
This article presents a comprehensive guide to generating PDF documents in Spring Boot 3 applications using iTextpdf and Thymeleaf, covering environment setup, Maven dependencies, data model, HTML template design, controller implementation, and a test case that produces a correctly rendered PDF with external CSS and images.
1. Introduction
In enterprise applications, generating PDF files is a common requirement for invoices, receipts, contracts, and reports. PDFs provide cross‑platform consistency, tamper‑resistance, and fixed layout, making them suitable for finance, e‑commerce, and government scenarios.
2. Practical Cases
2.1 Environment Preparation
Add the following Maven dependencies:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>9.3.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.4.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>2.2 Data Model and Thymeleaf Template
Define a Java data class representing a receipt:
public class Receipt {
// Acquirer information
private String scope;
// Merchant information
private String merchantName;
private String merchantId;
private String terminalId;
private String merchantCity;
// Transaction basics
private String stan; // system trace number
private String transactionDate;
private String transactionType;
private BigDecimal requestAmount;
// Transaction details
private String mcc; // merchant category code
private String scheme; // card scheme
private String maskedPan; // masked card number
private String acquirer; // acquiring BIN
// System information
private String approvalNumber;
private String processingCode;
private String responseCode;
private String retrievalNumber;
private String displayMessage;
// getters and setters omitted
}The corresponding Thymeleaf HTML template (receipt.html) uses expressions such as
to fill the fields and includes external CSS and an image.</p>
<h3>2.3 Controller Definition</h3>
<p>Expose an endpoint that renders the template and converts it to PDF:</p>
<pre><code>@RestController
@RequestMapping("/html2pdf")
public class Html2PdfController {
private final ITemplateEngine templateEngine;
public Html2PdfController(ITemplateEngine templateEngine) {
this.templateEngine = templateEngine;
}
@GetMapping("/download")
public ResponseEntity<byte[]> downloadEJournalFile(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// 1. Prepare data
Map<String, Object> variables = Map.of("receipt", getData());
// 2. Create Thymeleaf context
Context context = new Context();
context.setVariables(variables);
String receiptTemplate = templateEngine.process("receipt", context);
// 3. Configure converter properties (base URI, fonts)
ConverterProperties converterProperties = new ConverterProperties();
converterProperties.setBaseUri("http://localhost:8080");
FontProvider fontProvider = new FontProvider();
fontProvider.addSystemFonts();
converterProperties.setFontProvider(fontProvider);
// 4. Convert HTML to PDF
ByteArrayOutputStream target = new ByteArrayOutputStream();
HtmlConverter.convertToPdf(receiptTemplate, target, converterProperties);
// 5. Set download headers
String fileName = URLEncoder.encode("receipt_detail.pdf", "UTF-8");
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
return ResponseEntity.ok()
.headers(header)
.contentType(MediaType.APPLICATION_PDF)
.body(target.toByteArray());
}
public Receipt getData() {
// return a populated Receipt instance
return ...;
}
}2.4 Test Result
Calling the endpoint returns a PDF that correctly displays all receipt fields, loads external CSS and images, and matches the layout shown below.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
