com.itextpdf:itext7-core:7.2.5,AGPL/商業雙授權com.github.librepdf:openpdf:1.3.35,免費商用本文基於 iText 7 演示,核心包:kernel、layout、io。
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>7.2.5</version>
</dependency>
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.*;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.*;
import java.io.*;
public class BasicPdf {
public static void main(String[] args) throws IOException {
String dest = "basic.pdf";
// 1. PdfWriter
PdfWriter writer = new PdfWriter(dest);
// 2. PdfDocument
PdfDocument pdfDoc = new PdfDocument(writer);
// 3. Document (高層布局)
Document document = new Document(pdfDoc);
// 文檔元數據
pdfDoc.getDocumentInfo().setTitle("iText 7 Demo");
pdfDoc.getDocumentInfo().setAuthor("Developer");
pdfDoc.getDocumentInfo().setSubject("Basic Example");
pdfDoc.getDocumentInfo().setKeywords("iText, PDF, Java");
// 4. 添加內容
document.add(new Paragraph("Hello World!")
.setFontSize(24)
.setBold()
.setTextAlignment(TextAlignment.CENTER)
.setMarginTop(100));
document.add(new Paragraph("這是使用 iText 7 生成的第一個 PDF 文檔。")
.setFontSize(14)
.setMarginTop(20));
// 5. 關閉 (自動 flush)
document.close();
System.out.println("PDF 生成完成: " + dest);
}
}
public class TablePdf {
public static void main(String[] args) throws IOException {
PdfWriter writer = new PdfWriter("table.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
// 創建 3 列表格
Table table = new Table(3).useAllAvailableWidth();
// 表頭
table.addHeaderCell(new Cell().add(new Paragraph("ID")).setBold().setBackgroundColor(ColorConstants.LIGHT_GRAY));
table.addHeaderCell(new Cell().add(new Paragraph("名稱")).setBold().setBackgroundColor(ColorConstants.LIGHT_GRAY));
table.addHeaderCell(new Cell().add(new Paragraph("價格")).setBold().setBackgroundColor(ColorConstants.LIGHT_GRAY));
// 數據行
String[][] data = {
{"1", "蘋果", "¥5.00"},
{"2", "香蕉", "¥3.50"},
{"3", "橙子", "¥4.20"}
};
for (String[] row : data) {
for (String cell : row) {
table.addCell(new Cell().add(new Paragraph(cell)));
}
}
// 跨列合併
table.addCell(new Cell(1, 3).add(new Paragraph("總計: 3 種水果")).setTextAlignment(TextAlignment.CENTER));
document.add(table);
document.close();
}
}
public class ImagePdf {
public static void main(String[] args) throws IOException {
// A4 橫向,邊距 0
PageSize pageSize = PageSize.A4.rotate();
PdfWriter writer = new PdfWriter("image.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.setDefaultPageSize(pageSize);
Document document = new Document(pdfDoc, pageSize);
document.setMargins(0, 0, 0, 0);
// 背景圖片鋪滿
Image bg = new Image(ImageDataFactory.create("bg.jpg"))
.setFixedPosition(0, 0)
.scaleToFit(pageSize.getWidth(), pageSize.getHeight());
document.add(bg);
// 絕對定位文字 (使用 Canvas 底層 API)
PdfCanvas canvas = new PdfCanvas(pdfDoc.getFirstPage());
PdfFont font = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
canvas.beginText()
.setFontAndSize(font, 12)
.moveText(100, 500)
.showText("坐標 (100, 500) 的中文文字")
.endText();
// 批量繪製網格座標
canvas.beginText().setFontAndSize(font, 8);
for (int y = 0; y <= pageSize.getHeight(); y += 50) {
for (int x = 0; x <= pageSize.getWidth(); x += 50) {
canvas.moveText(x, y).showText(String.format("(%d,%d)", x, y));
}
}
canvas.endText();
document.close();
}
}
| 方案 | 適用場景 | 代碼示例 |
|---|---|---|
| font-asian 模塊 | 簡體/繁體/日/韓,無需字體文件 | PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H") |
| 本地 TTF 字體 | 特定字體要求、商業項目 | PdfFontFactory.createFont("msyh.ttf", PdfEncodings.IDENTITY_H, true) |
| 系統字體註冊 | 動態加載系統字體 | FontProgramFactory.registerSystemFonts(); 後用字體名 |
PdfCanvas 繪製半透明文字/圖片,或 PdfPageEventForwarder 頁面事件PdfSigner + 憑證鏈,支持 PAdES-LTVPdfAcroForm 獲取字段 setValue()pdfHTML 模塊 HtmlConverter.convertToPdf()PdfADocument 創建歸檔級 PDFPdfWriter.setSmartMode(true) + 分頁寫入| 問題 | 解決 |
|---|---|
| 中文顯示方框/亂碼 | 未註冊中文字體,用 font-asian 或本地 TTF |
| 表格跨頁斷裂 | table.setSplitLate(false) 或調整 setKeepTogether(true) |
| 圖片模糊/變形 | scaleToFit() 保持比例,避免 setFixedPosition 強制拉伸 |
| 內存溢出 | 大文檔用 PdfWriter.setSmartMode(true),分批 document.flush() |
| AGPL 合規 | 商業閉源項目需購買授權,或遷移 OpenPDF |
iText 7 通過 PdfDocument (底層) + Document (高層布局) 分離關注點,功能強大但學習曲線較陡。核心掌握:字體註冊、表格佈局、Canvas 底層繪圖、流式處理大文件。中文項目優先用 font-asian 解決字體問題。商業項目注意 AGPL 協議,評估 OpenPDF 或購買授權。