使用itext填充静态PDF模板,生成PDF新文件
背景:
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 }