首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

iText 實戰:從 Java 動態產生 PDF 完整指南(Maven/Gradle 依賴、核心 API、範例專案、中文字型解決方案)

     編輯:Java 程式設計入門

為什麼選 iText?

  • 開源、成熟、功能強大:支援 PDF、HTML、RTF、XML 多格式輸出。
  • 統一 API:同一套程式碼可切換輸出格式。
  • 豐富元素:段落、章節、字型、列表、表格、浮水印、加密、數位簽章等。

專案建置(Maven / Gradle)

<!-- Maven -->
<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itextpdf</artifactId>
  <version>5.5.13.3</version> <!-- 5.x 為 LGPL/MPL,7.x 為 AGPL -->
</dependency>


<dependency>
  <groupId>com.itextpdf</groupId>
  <artifactId>itext-asian</artifactId>
  <version>5.2.0</version>
</dependency>
// Gradle (Kotlin DSL)
implementation("com.itextpdf:itextpdf:5.5.13.3")
implementation("com.itextpdf:itext-asian:5.2.0")

核心類別速查

類別用途
Document文件容器,設定頁面大小、邊距
PdfWriterPDF 輸出器,綁定 Document 與 OutputStream
Paragraph段落(可設定縮進、對齊、字型)
Chapter / Section章節結構,自動產生書籤
Font字型規格:家族、大小、樣式、顏色
List / ListItem有序/無序清單
Table / Cell表格佈局(舊版),新版建議用 PdfPTable

最小可行範例:Hello PDF

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.FileOutputStream;

public class HelloPdf {
    public static void main(String[] args) throws Exception {
        // 1. 建立文件
        Document doc = new Document(PageSize.A4, 50, 50, 50, 50);
        
        // 2. 綁定輸出器
        PdfWriter.getInstance(doc, new FileOutputStream("hello.pdf"));
        
        // 3. 開啟文件
        doc.open();
        
        // 4. 寫入內容
        Font titleFont = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD);
        doc.add(new Paragraph("Hello, iText!", titleFont));
        
        Font bodyFont = new Font(Font.FontFamily.HELVETICA, 12);
        doc.add(new Paragraph("這是第一個動態產生的 PDF 文件。", bodyFont));
        
        // 5. 關閉文件(必要!)
        doc.close();
        System.out.println("PDF 生成完成:hello.pdf");
    }
}

中文字型解決方案(關鍵!)

iText 5 預設不含中文字型,直接寫中文會顯示 □。三種方案:

方案一:itext-asian + 內建 CJK 字型(最簡單)

// 需加入 itext-asian 依賴
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font chineseFont = new Font(bf, 12);
  • 優點:零字型檔、部署輕量。
  • 缺點:僅支援簡體中文、依賴閱讀器內建字型、Linux/伺服器常缺字導致亂碼。

方案二:嵌入 TTF/OTF 字型檔(推薦生產環境)

// 將微軟正黑體 .ttf 放入 resources/fonts/
BaseFont bf = BaseFont.createFont(
    "fonts/MicrosoftJhengHei.ttf",
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED  // 關鍵:嵌入字型檔進 PDF
);
Font chineseFont = new Font(bf, 12);
  • 優點:跨平台完美顯示、支援繁/簡/日/韓、可商業授權字型。
  • 缺點:PDF 體積增大(每字型約 5-20 MB)、需處理字型授權。

方案三:iText 7 + pdfCalligraph(進階排版)

iText 7 重寫核心,支援複雜文字排版(阿拉伯文、印地文等),但授權為 AGPL,商業用途需購買授權。

進階實戰:報表產生器骨架

public class ReportGenerator {
    public void generate(OutputStream out, List orders) throws DocumentException {
        Document doc = new Document(PageSize.A4.rotate(), 36, 36, 36, 36); // 橫向
        PdfWriter writer = PdfWriter.getInstance(doc, out);
        
        // 頁首/頁尾事件
        writer.setPageEvent(new HeaderFooterEvent());
        
        doc.open();
        // 標題
        doc.add(new Paragraph("訂單報表", titleFont));
        doc.add(Chunk.NEWLINE);
        
        // 表格
        PdfPTable table = new PdfPTable(new float[]{1, 3, 2, 2, 1.5f});
        table.setWidthPercentage(100);
        addTableHeader(table);
        for (Order o : orders) addOrderRow(table, o);
        doc.add(table);
        
        doc.close();
    }
}

常見坑點與避雷指南

  • ❌ 忘記 doc.close() → PDF 損毀、0 bytes。
  • ❌ 字型未嵌入 → 客戶端無字型顯示亂碼。
  • ❌ 大量資料一次加入 Document → OOM。改用 PdfPTable 串流寫入或分頁處理。
  • ❌ iText 5 vs 7 API 不相容 → 遷移時需全面重寫。
  • ⚠️ 授權陷阱:iText 5 為 LGPL/MPL(可商業但需開源修改部分),iText 7 為 AGPL(商業必買授權)。評估法律風險。

替代方案速覽

函式庫授權特色
Apache PDFBoxApache 2.0純 Java、低層控制、文字提取強
OpenPDFLGPL/MPLiText 4 分支、免費商業友善
Flying SaucerLGPLHTML/CSS → PDF、排版優
pdfbox-layoutApache 2.0PDFBox 上層封裝、類 iText API
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved