How to Generate PDF Files in Java: A Complete Step‑by‑Step Tutorial
This guide walks through the need for PDF generation in business scenarios, introduces the iText library (both iText5 and iText7), shows how to add Maven dependencies, provides a minimal “Hello World” PDF example, then details converting HTML (with CSS, images, and Freemarker variables) into PDF, and discusses when custom adaptation is required.
Background
In many business applications developers need to provide electronic documents such as e‑invoices, order printouts, or signed contracts for users to view, download or print.
iText Library Overview
iText is an open‑source Java library for creating PDF (and RTF) files. It is hosted on SourceForge and currently has two major branches: iText5, which is widely used but has some design shortcomings, and iText7, a newer refactor with many improvements. For simple use cases either version works.
Adding iText Dependencies
<dependencies>
<!-- pdf:start -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!-- support Chinese characters -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- CSS rendering support -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.16</version>
</dependency>
<!-- HTML → XHTML conversion -->
<dependency>
<groupId>net.sf.jtidy</groupId>
<artifactId>jtidy</artifactId>
<version>r938</version>
</dependency>
<!-- pdf:end -->
</dependencies>Simple "Hello World" PDF
public class CreatePDFMainTest {
public static void main(String[] args) throws Exception {
Document document = new Document(PageSize.A4);
// Step 2: create Writer instance
PdfWriter.getInstance(document, new FileOutputStream("hello.pdf"));
// Create Chinese font
BaseFont bfchinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontChinese = new Font(bfchinese, 12, Font.NORMAL);
// Step 3: open document
document.open();
// Step 4: write content
Paragraph paragraph = new Paragraph("hello world", fontChinese);
document.add(paragraph);
// Step 5: close document
document.close();
}
}Running the program produces hello.pdf containing the text "hello world" rendered with a Chinese‑compatible font.
Complex Implementation – Converting HTML to PDF
When the business scenario requires rendering a full HTML page (including CSS, images and tables) as a PDF, the article shows how to use iText5 together with the XML‑Worker pipeline.
private static void writeToOutputStreamAsPDF(String htmlStr) throws Exception {
String targetFile = "pdfDemo.pdf";
File targeFile = new File(targetFile);
if (targeFile.exists()) { targeFile.delete(); }
Document document = new Document(PageSize.A4, 25, 25, 15, 40);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(targetFile));
PdfReportHeaderFooter header = new PdfReportHeaderFooter("", 8, PageSize.A4);
writer.setPageEvent(header);
writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
document.open();
// CSS resolver
CSSResolver cssResolver = new StyleAttrCSSResolver();
// Font provider for Chinese characters
CssAppliers cssAppliers = new CssAppliersImpl(new XMLWorkerFontProvider(){
@Override
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {
try {
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
return new Font(bfChinese, size, style);
} catch (Exception e) {
return super.getFont(fontname, encoding, size, style);
}
}
});
HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider(){
@Override
public Image retrieve(String src) {
int pos = src.indexOf("base64,");
try {
if (src.startsWith("data") && pos > 0) {
byte[] img = Base64.decode(src.substring(pos + 7));
return Image.getInstance(img);
} else if (src.startsWith("http")) {
return Image.getInstance(src);
}
} catch (BadElementException | IOException ex) { return null; }
return null;
}
@Override
public String getImageRootPath() { return null; }
});
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(htmlStr.getBytes()));
document.close();
}
private static String readHtmlFile() {
StringBuffer textHtml = new StringBuffer();
try {
File file = new File("printDemo.html");
BufferedReader reader = new BufferedReader(new FileReader(file));
String tempString;
while ((tempString = reader.readLine()) != null) {
textHtml.append(tempString);
}
reader.close();
} catch (IOException e) { return null; }
return textHtml.toString();
}
public static void main(String[] args) throws Exception {
String htmlStr = readHtmlFile();
writeToOutputStreamAsPDF(htmlStr);
}The HTML file printDemo.html contains a table that represents an inbound‑stock order. After running the program, pdfDemo.pdf shows the rendered table with proper borders, fonts and embedded images.
Variable Substitution with Freemarker
For fully dynamic content the article recommends using a template engine such as Freemarker. By defining placeholders like ${name} in the HTML template and replacing them before the conversion step, any business data (e.g., order numbers, QR codes) can be injected.
<html>
<head><meta charset="utf-8"><title></title></head>
<body>
<div>您好:${name}</div>
<div>欢迎,登录博客网站</div>
</body>
</html>After the placeholder is replaced with the actual value, the same HTML‑to‑PDF pipeline described above produces the final document.
Conclusion
The iText framework is a very practical third‑party library for generating PDF files in Java. For simple static PDFs it satisfies most requirements out‑of‑the‑box. Complex PDFs that involve rich HTML, CSS, images or dynamic data may require additional adaptation or custom development, for which the official iText API documentation should be consulted.
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.
Pan Zhi's Tech Notes
Sharing frontline internet R&D technology, dedicated to premium original content.
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.
