需求:把原来的下载word文件改成pdf的文件 文件内容是模板+数据
1. freeMark 生成word
由于word的格式比较多,生成一个由模板+数据的word文档,如果有poi操作word写个模板也是一件费劲的事。
可以 word转成xml 然后改成ftl 的后缀,通过freeMark就可以读取word模板,填写相应的数据。
生成的word文件 其实并不是二进制的word文件,打开发现仍然是xml的组织结构数据,所以当想word转pdf的时候,不应该把这个文件看成word 而是看成xml ....
2.关于word转pdf
网上有很多技术,有的需要win环境,有的需要oppenOffice 服务,还有一种 itext 的第三方
word转pdf 这里有一篇文章 http://feifei.im/archives/93 头疼的地方是样式问题 对于修改样式我直接放弃...(因为有更简单的方式)
3.HTML转pdf
鉴于读取word转成pdf 会出现各种样式问题,itext HTML转换成pdf 就要容易的多了
1 // 设置FreeMarker的模版文件位置 2 String path = request.getSession().getServletContext().getRealPath("/") +"WEB-INF"+File.separator+"template"+File.separator; 3 configuration.setDirectoryForTemplateLoading(new File(path)); 4 // 模板 5 Template t = configuration.getTemplate(modelName); 6 //设置输入路径弹框 7 response.reset(); 8 response.setContentType("application/x-download; charset=utf-8"); 9 response.setHeader("Content-Disposition", "attachment; filename=" + new String(fileName.getBytes("GB2312"),"ISO-8859-1")); 10 11 StringWriter result = new StringWriter(); 12 try { 13 response.setContentType("text/html; charset=utf-8"); 14 t.process(dataMap, result); 15 //wr.flush(); 16 17 ITextRenderer renderer = new ITextRenderer(); 18 // PDFEncryption pdfEncryption = new 19 // PDFEncryption(null,null,PdfWriter.ALLOW_PRINTING); 20 // renderer.setPDFEncryption(pdfEncryption); //只有打印权限的 21 renderer.setDocumentFromString(result.toString()); 22 23 // 解决中文问题 24 ITextFontResolver fontResolver = renderer.getFontResolver(); 25 try { 26 fontResolver.addFont(path + "SIMSUN.ttc", 27 BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); 28 } catch (DocumentException e) { 29 // TODO Auto-generated catch block 30 e.printStackTrace(); 31 } 32 33 // 解决图片的相对路径问题 34 //renderer.getSharedContext().setBaseURL("file:/D:/Work/Demo2do/Yoda/branch/Yoda%20-%20All/conf/template/"); 35 36 renderer.layout(); 37 try { 38 renderer.createPDF(response.getOutputStream()); 39 } catch (DocumentException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 System.out.println("转换成功!"); 44 } catch (TemplateException e) { 45 throw new Exception("处理Template模版中出现错误", e); 46 }
我们可以用HTML 做出很漂亮的pdf界面,但是(这才是重点)pdf的显示和HTML之间也并不完美,pdf可以设置纸张的大小 <style> @page{size:210mm 290mm} </style> 这个mm是毫米 那么问题来了 HTML里面是px 要想pdf看起来和HTML一样
那么HTML的样式设计上就是一个不小的问题(我是没有找到解决的好方法)
4.最简单的模板+数据 生成pdf
需求很简单 我就是想生成一个有模板的pdf文件,可是要弄个模板文件 用HTML,word 的话 都将逃脱不了 去调样式 我实在是没有耐心去做这件事 so~
pdf 的编辑功能 是可以往pdf上进行表单编辑,在你填入数据的地方 添加适当的域 这样就做好了一个模板,然后用itext 读入模板 ,填入数据 就行了
PdfReader reader = new PdfReader(path+modelName); // 模版文件目录 PdfStamper ps = new PdfStamper(reader, response.getOutputStream()); // 生成的输出流 BaseFont bf = BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); AcroFields s = ps.getAcroFields(); s.setFieldProperty("fill_2","textfont",bf,null); s.setField("fill_2", "companyName"); ps.setFormFlattening(true); // 这句不能少 ps.close();
上面的过程就会把 companyName 打印在 file_2的位置
pdf的编辑可以设置很多属性 参考 http://help.adobe.com/zh_CN/acrobat/using/WSC9CAD508-1941-43db-B599-2DCBF7BFC055.w.html
上面的操作要导入这俩jar包
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.4.3</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>
以上是在使用中的一点总结,如有错误欢迎批评