Generate PDFs Dynamically with Spring Boot and easypdf in Just Two Lines
This article shows how to quickly generate PDF documents in a Spring Boot 3.5.0 project using the x‑easypdf library, covering both the FOP and PDFBox modules, required dependencies, configuration files, sample controller code, and a runnable example that renders a PDF in the browser.
Environment
Spring Boot version: 3.5.0
1. Introduction
The x-easypdf library provides two modules:
FOP module – renders PDFs from XSL‑FO templates. Supports data sources such as XML, Thymeleaf, Freemarker, JTE, Java objects, and custom sources.
PDFBox module – extends Apache PDFBox with editing features (line breaks, pagination, Chinese support, headers/footers, components, extensibility).
2. Dependency Setup
<dependency>
<groupId>org.dromara.x-easypdf</groupId>
<artifactId>x-easypdf</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>Freemarker is used as the data source in the examples.
3. Using the FOP Module
3.1 Module definition
The FOP module renders PDFs from XSL‑FO templates. All Chinese characters must use a supported font-family (e.g., "微软雅黑").
3.2 FOP configuration file ( fop.xconf )
<?xml version="1.0" encoding="utf-8"?>
<fop version="1.0">
<base>.</base>
<source-resolution>72</source-resolution>
<target-resolution>72</target-resolution>
<default-page-settings width="21cm" height="29.7cm"/>
<renderers>
<renderer mime="application/pdf">
<filterList>
<value>flate</value>
</filterList>
<fonts>
<auto-detect/>
</fonts>
</renderer>
</renderers>
</fop>This configuration sets page size, DPI, and enables automatic font detection.
3.3 Application configuration ( application.yml )
pack:
app:
pdf:
configPath: E:\pdf\fop.xconf
templatePath: E:\pdf\templateKeeping the configuration file and template directory outside the JAR simplifies management.
3.4 Controller example
@RestController
@RequestMapping("/easypdf")
public class EasypdfController {
@Value("${pack.app.pdf.configPath}")
private String configPath;
@Value("${pack.app.pdf.templatePath}")
private String templatePath;
@GetMapping("/test")
public void genPdf(String templateName, HttpServletResponse response) throws Exception {
Map<String, Object> data = prepareData();
TemplateHandler.DataSource.Freemarker.setTemplatePath(templatePath);
TemplateHandler.Template.build()
.setConfigPath(configPath)
.setDataSource(
TemplateHandler.DataSource.Freemarker.build()
.setTemplateName(templateName)
.setTemplateData(data)
)
.transform(response.getOutputStream());
}
private Map<String, Object> prepareData() {
Map<String, Object> data = new HashMap<>();
List<String> list = new ArrayList<>(2);
list.add("Pack");
list.add("Jeery");
list.add("张三");
data.put("list", list);
data.put("msg", "使用Fop模块第一个PDF文档");
return data;
}
}The endpoint streams the generated PDF to the browser; adding appropriate HTTP headers enables file download.
4. Using the PDFBox Module
Minimal example that creates a PDF with a single text field:
// Define output path
String outputPath = "E:\\pdf\\demo.pdf";
// Create document
Document document = PdfHandler.getDocumentHandler().create();
// Set font (must be installed on the system)
document.setFontName("微软雅黑");
// Create a page
Page page = new Page(document);
// Create a text area
Textarea textarea = new Textarea(page);
// Set text content
textarea.setText("Hello World!");
// Render the text
textarea.render();
// Add page to document
document.appendPage(page);
// Save and close
document.save(outputPath);
document.close();The resulting PDF can be opened to verify the rendered text.
5. References
https://x-easypdf.cn/guide/fop/object/#%E4%BB%8B%E7%BB%8D
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
