iText (低版本 com.lowagie.text) 是 Java 生成 PDF 的經典庫。本文提供兩個完整可運行範例:基礎文本輸出、帶章節結構/字體/顏色/表格的豐富文檔,並說明中文字體註冊關鍵步驟。
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version> <!-- 老版本,新版請用 com.itextpdf:itextpdf:5.5.x -->
</dependency>
package com.qhdstar.java.pdf;
import java.io.FileOutputStream;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
public class GeneratePDF {
public static void writeSimplePdf() throws Exception {
// 1. 建立文檔:A4,邊距 50pt
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
// 2. 綁定寫入器
PdfWriter.getInstance(document, new FileOutputStream("C:/ITextTest.pdf"));
// 3. 開啟文檔
document.open();
// 4. 添加內容
document.add(new Paragraph("First page of the document."));
document.add(new Paragraph("Different font and color.",
com.lowagie.text.FontFactory.getFont(com.lowagie.text.FontFactory.COURIER, 14,
com.lowagie.text.Font.BOLD, new java.awt.Color(255, 150, 200))));
// 5. 關閉文檔(必須調用,否則 PDF 損壞)
document.close();
}
}
public static void writeChapter() throws Exception {
Document document = new Document(PageSize.A4, 20, 20, 20, 20);
PdfWriter.getInstance(document, new FileOutputStream("c:/ITextTest.pdf"));
document.open();
// 元數據
document.addTitle("Hello iText Example");
document.addAuthor("wolf");
document.addSubject("Chapter & Section demo");
document.addKeywords("iText, Chapter, Section");
document.addCreator("My program using iText");
// 空行佔位
for (int i = 0; i < 5; i++) document.add(new Paragraph("\n"));
document.add(new Paragraph("First page content."));
// 章節標題:藍色、18pt、粗斜體
Paragraph title1 = new Paragraph("Chapter 1",
FontFactory.getFont(FontFactory.HELVETICA, 18, Font.BOLDITALIC, new Color(0, 0, 255)));
Chapter chapter1 = new Chapter(title1, 1);
chapter1.setNumberDepth(0); // 不顯示章節編號
// 節:紅色、16pt、粗體
Paragraph title11 = new Paragraph("This is Section 1 in Chapter 1",
FontFactory.getFont(FontFactory.HELVETICA, 16, Font.BOLD, new Color(255, 0, 0)));
com.lowagie.text.Section section1 = chapter1.addSection(title11);
section1.add(new Paragraph("This text comes as part of section 1 of chapter 1."));
section1.add(new Paragraph("Following is a 3 X 2 table."));
// 簡易表格(3行2列)
com.lowagie.text.Table table = new com.lowagie.text.Table(2);
table.setPadding(5);
table.addCell("Header 1");
table.addCell("Header 2");
table.addCell("Row1 Col1");
table.addCell("Row1 Col2");
table.addCell("Row2 Col1");
table.addCell("Row2 Col2");
section1.add(table);
document.add(chapter1);
document.close();
}
iText 核心字體不含中文字形,必須註冊 TTF 字體文件:
// 註冊系統字體(以 Windows 微軟雅黑為例)
String fontPath = "C:/Windows/Fonts/msyh.ttf";
FontFactory.register(fontPath, "MicrosoftYaHei");
// 使用
Font cnFont = FontFactory.getFont("MicrosoftYaHei", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 12);
document.add(new Paragraph("中文測試:你好,iText!", cnFont));
BaseFont.IDENTITY_H:Unicode 水平書寫編碼。BaseFont.EMBEDDED:將字體嵌入 PDF,確保無字體環境也能正確顯示。/usr/share/fonts/truetype/dejavu/)。| 現象 | 原因 | 解決 |
|---|---|---|
| 中文顯示為方塊/亂碼 | 未註冊中文字體或編碼錯誤 | 註冊 TTF + IDENTITY_H + EMBEDDED |
| PDF 生成後 0 字節/打不開 | 未調用 document.close() 或流未 flush | 確保 finally 關閉 document 與流 |
| 表格跨頁錯亂 | 老版 Table 不支援自動分頁 | 升級 iText 5+ 使用 PdfPTable |
| 圖片不顯示 | 路徑錯誤或圖片流未讀取 | 用 Image.getInstance(url) 或字節數組 |
iText 以 Document → PdfWriter → Paragraph/Chapter/Section/Table 結構化 API 構建 PDF,核心在於「開啟-添加-關閉」生命周期。中文項目務必完成字體註冊與嵌入。若專案需求複雜(數位簽章、表單、PDF/A 合規),建議升級至 iText 7 或評估 Apache PDFBox。