背景:
PDF的生成有多種方式,常見是直接從無到有生成一份PDF,包含設置輸出格式,增設頁面,繪制內容並填寫數據。
而這里介紹的是,使用靜態PDF模板填充數據,生成一份新的靜態PDF。
模板:
可使用 LiveCycle Designer 制作模板。
拖拉常用控件textfield,然后設置它的綁定名稱key,這個key是后續Java填值的關鍵,如圖設置:
繪制好想要的內容后,選擇另存為static類型的PDF文件,此為模板。
Java填值部分:
1.使用PdfReader讀取模板PDF,然后使用 PdfStamper把 resultPDF與reader兩者綁定。
PdfReader reader = new PdfReader(templateFilePath); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(resultFilePath));
2.然后開始操作這個PdfStamper對象,核心代碼是
AcroFields acroFields = stamper.getAcroFields();
acroFields.setField("account全稱", "航天科技有限公司");
這里的 “account全稱” 必須與圖1模板中定義的Binding name一致,即可給控件 “公司全稱” 填值 “航天科技有限公司”。
3. 解決填值中文亂碼問題
// 指定中文字體 BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); acroFields.setFieldProperty("account全稱", "textfont", font, null);
設定 ”公司全稱“ 輸入框可填值中文,實際上我直接給所有控件都設置中文格式了,也暫未發現有啥毛病。
4.關閉流有區分先后順序,原先在網上見到人胡亂關閉,抄下來運行后報錯了。
// 先關閉stamper stamper.close(); reader.close();
參考完整代碼:
1 private void fillStaticPdf(String templateFilePath, String resultFilePath, Map<String, String> data){ 2 3 if(StringUtils.isEmpty(templateFilePath) || StringUtils.isEmpty(resultFilePath) || data == null){ 4 log.info("[fillStaticPdf]params is empty"); 5 throw new InvalidInputException(LACK_OF_PARAM); 6 } 7 8 PdfReader reader = null; 9 PdfStamper stamper = null; 10 try { 11 reader = new PdfReader(templateFilePath); 12 stamper = new PdfStamper(reader, new FileOutputStream(resultFilePath)); 13 AcroFields acroFields = stamper.getAcroFields(); 14 15 //中文字體 16 BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED); 17 18 //靜態賦值 19 for (Map.Entry<String, String> d : data.entrySet()) { 20 acroFields.setFieldProperty(d.getKey(), "textfont", font, null); 21 acroFields.setField(d.getKey(), d.getValue(), true); 22 } 23 24 //設置pdf為只讀 25 stamper.setFormFlattening(true); 26 } catch (DocumentException e) { 27 log.info("[fillStaticPdf]-文件異常!"); 28 throw new InvalidInputException(SYSTEM_ERROR); 29 } catch (IOException e) { 30 log.info("[fillStaticPdf]-生成PDF時IOException異常!"); 31 throw new InvalidInputException(SYSTEM_ERROR); 32 } finally { 33 if(stamper!=null){ 34 try { 35 stamper.close(); 36 } catch (Exception e) { 37 log.info("關閉stamper時遇到錯誤!"); 38 } 39 } 40 if(reader!=null){ 41 reader.close(); 42 } 43 } 44 }