方案架構:Controller 準備資料 → 自訂 JSP Tag (繼承 BodyTagSupport) 驅動 FreeMarker 渲染 HTML → Flying Saucer (core-renderer) 將 HTML+CSS 轉 PDF → iText 輸出 PDF 流供下載/列印,HTML 同時回傳瀏覽器預覽。
core-renderer.jar (Flying Saucer R8+)freemarker-2.3.16.jariText-2.0.8.jar (注意:iText 5+ 版權變更,2.0.8 為最後 LGPL 版)iTextAsian.jar (中文字體支援)封裝通用流程:解析 JSON 參數 → 合併資料模型 → FreeMarker 處理模板 → 生成暫存 HTML → 輸出至 Response (預覽) 與檔案 (供 PDF 轉換)。定義四個模板方法讓子類實作業務邏輯:
setConfigParams():設定模板路徑、輸出檔名、編碼等。doServiceStart():填充預覽階段資料 (flag=0)。doServiceDoing():切換列印階段資料 (flag=1),同一模板產出不同風格。doServiceEnd():清理資源。注入專案屬性 (專案性質、書名、編碼),實作上述四方法,並定義 PDFConfigurationInterface 內部介面集中管理 Tag 屬性配置。
<tag> <name>print</name> <tagclass>com.iris.taglib.web.PreviewPDFTag</tagclass> <attribute><name>json</name><required>true</required></attribute> <attribute><name>prjNature</name><required>true</required></attribute> ... </tag>
<%@ taglib prefix="pdf" uri="/WEB-INF/tld/pdf.tld" %>
<pdf:print json="${json}" prjNature="${prjNature}" bookName="${bookName}" tempDir="${tempDir}" prjCode="${prjCode}" />
查詢業務資料,放入 Map 或直接傳遞 JSON 字串給 Tag,同時傳遞字體路徑、水印圖片路徑、靜態資源根路徑等上下文參數。
font-family: "SimSun"; 並確保 iTextAsian 可用。