專案需求:用戶查詢出貨資訊,以 PDF 格式返回,支援瀏覽器下載與 Acrobat Reader 閱讀。團隊選擇開源純 Java 庫 iText 實現伺服器端動態生成。
| 策略 | 說明 | 優/缺點 |
|---|---|---|
| A:檔案系統 | 用 FileOutputStream 寫入伺服器磁碟,HTTP GET 下載 | 集群環境下若無 Session Affinity 易失效 |
| B:記憶體流(推薦) | 用 ByteArrayOutputStream 在記憶體生成,Servlet 輸出流直傳客戶端 | 無磁碟 I/O,天然支援集群,本文採用 |
Document:PDF 文件的物件模型描述PdfWriter:綁定 OutputStream,將 Document 序列化為 PDF 位元組Paragraph、Phrase、Table、Cell、HeaderFooter:內容構建元素// 1. 建立記憶體輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 2. 綁定 Document 與 PdfWriter
Document doc = new Document();
PdfWriter writer = PdfWriter.getInstance(doc, baos);
doc.open();
// 3. 添加內容
doc.add(new Paragraph("動態生成於 " + new java.util.Date()));
// 表格、圖片、分頁等豐富排版...
// 4. 關閉文件(觸發序列化)
doc.close();
writer.close();
// 5. 取得 PDF 位元組
return baos;
| Header | 值範例 | 用途 |
|---|---|---|
| Content-Type | application/pdf | 告知瀏覽器 MIME 類型 |
| Content-Disposition | inline; filename=report.pdf / attachment; filename=report.pdf | 內嵌顯示或作為附件下載 |
| Content-Length | baos.size() | 必須準確,否則瀏覽器顯示異常 |
| Cache-Control | max-age=30 / no-store / must-revalidate | 控制快取策略 |
注意:Header 必須在寫入輸出流之前設定。
ServletOutputStream sos = resp.getOutputStream();
baos.writeTo(sos);
sos.flush();
itext-0.99.jar 放入 WAR 的 WEB-INF/libhttps://host:8080/pdfservlet/createpdf 即可獲取 PDF掌握 iText 核心 API 與 Servlet 輸出機制,即可在任何 Java Web 應用中靈活實現動態 PDF 生成與下載。