iText (現為 iText 7/8) 是 Java 領域標杆級 PDF 庫,支援表格、圖片、水印、數位簽章等企業級功能。本文示範在 Tomcat 5.x 下,透過 Servlet 動態生成包含大量資料表格的 PDF 報表並直接輸出瀏覽器下載。
C:\Tomcat 5.0C:\Tomcat 5.0\webapps\pdfservletC:\j2sdk1.4.2_09itext-1.3.0.jar,放入 WEB-INF/lib 及 JDK lib,並加入 CLASSPATH。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-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>
WEB-INF/classes。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 結尾缺失導致損壞 |
pdfHTML 附件,支援 HTML+CSS 直接轉 PDF,大幅降低表格樣式維護成本。@Controller 直接返回 ResponseEntity,無需繼承 HttpServlet。