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

Tomcat 整合 iText 實現 Servlet 動態生成 PDF 報表

     編輯:Java 程式設計入門

專案目標與技術選型

iText (現為 iText 7/8) 是 Java 領域標杆級 PDF 庫,支援表格、圖片、水印、數位簽章等企業級功能。本文示範在 Tomcat 5.x 下,透過 Servlet 動態生成包含大量資料表格的 PDF 報表並直接輸出瀏覽器下載。

環境準備

  1. Tomcat 安裝目錄:C:\Tomcat 5.0
  2. Web 應用目錄:C:\Tomcat 5.0\webapps\pdfservlet
  3. JDK:C:\j2sdk1.4.2_09
  4. 依賴:從 官網 下載 itext-1.3.0.jar,放入 WEB-INF/lib 及 JDK lib,並加入 CLASSPATH。

核心 Servlet 代碼

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

public class HelloWorldServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 1. 文檔模型:A4 橫向、邊距 10pt
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);

        try {
            // 2. 綁定輸出流至 HTTP 響應
            resp.setContentType("application/pdf");
            PdfWriter.getInstance(document, resp.getOutputStream());

            // 3. 開啟文檔
            document.open();

            // 4. 建立 12 欄位表格
            String[] bogusData = {"M0065920", "SL", "FR86000P", "PCGOLD",
                    "119000", "96 06", "2001-08-13", "4350", "6011648299",
                    "FLFLMTGP", "153", "119000.00"};
            int NumColumns = 12;
            PdfPTable table = new PdfPTable(NumColumns);
            int[] headerWidths = {9, 4, 8, 10, 8, 11, 9, 7, 9, 10, 4, 10};
            table.setWidths(headerWidths);
            table.setWidthPercentage(100);

            // 5. 表頭樣式
            PdfPCell cell = new PdfPCell();
            cell.setPadding(3);
            cell.setBorderWidth(2);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.setDefaultCell(cell);
            String[] headers = {"Clock #", "Trans Type", "Cusip", "Long Name",
                    "Quantity", "Fraction Price", "Settle Date", "Portfolio",
                    "ADP Number", "Account ID", "Reg Rep ID", "Amt To Go"};
            for (String h : headers) table.addCell(h);
            table.setHeaderRows(1); // 表頭重複顯示

            // 6. 資料列:交替灰底、細邊框
            cell.setBorderWidth(1);
            for (int i = 1; i < 750; i++) {
                if (i % 2 == 1) cell.setGrayFill(0.9f);
                else cell.setGrayFill(0f);
                for (String val : bogusData) table.addCell(val);
            }

            // 7. 加入文檔並關閉(會自動 flush/close outputstream)
            document.add(table);
        } catch (DocumentException de) {
            de.printStackTrace();
        } finally {
            document.close(); // 關鍵:確保 PDF 結構完整寫入
        }
    }
}

Web.xml 註冊

<web-app>
  <servlet>
    <servlet-name>HelloWorldServlet</servlet-name>
    <servlet-class>HelloWorldServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>HelloWorldServlet</servlet-name>
    <url-pattern>/HelloWorldServlet</url-pattern>
  </servlet-mapping>
</web-app>

部署驗證

  1. 編譯類別至 WEB-INF/classes。
  2. 重啟 Tomcat。
  3. 瀏覽器訪問 https://IP:8080/pdfservlet/HelloWorldServlet,應直接觸發 PDF 下載或瀏覽器內嵌預覽。

關鍵技術點與避坑指南

項目說明
大數據量iText 以流式寫入,記憶體佔用極低,百萬行同樣適用
中文字型需註冊中文字型:BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED)
表格分頁setHeaderRows(1) 確保跨頁表頭重複
響應頭可加 Content-Disposition: attachment; filename="report.pdf" 強制下載
異常處理document.close() 必須在 finally 執行,否則 PDF 結尾缺失導致損壞

現代化升級建議

  • 遷移至 iText 7/8 (AGPL) 或 OpenPDF (LGPL),API 重大變更但效能更強。
  • 引入 pdfHTML 附件,支援 HTML+CSS 直接轉 PDF,大幅降低表格樣式維護成本。
  • Spring Boot 整合:@Controller 直接返回 ResponseEntity,無需繼承 HttpServlet。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved