最近项目中又遇到pdf导出的需求,以前一直都是用phantomjs-2.1.1-windows.exe插件做的pdf导出,运用插件优点是直接可以把html页面直接转换成pdf导出,缺点是它需要安装,windows、linux、mac等环境下需要的插件安装都不一样,中文字体还需要单独安装;查询了一些文档后就决定采用freemarker 与 ITextRenderer来实现了;偶然间在git看到了flying saucer项目;发现思路基本一致就在其基础上开发了(^_^) 。
freemarker 模板能很好的支持html、css样式;但是运用之前需要小小的学习一下freemarker ftl模板的一些固定语法,这对一般的开发者而言应该都没什么难度(^^)。
下面记录一下用到的方法与运用freemarker 与 ITextRenderer过程的一些坑
- ftl模板中中文字体显示
- ftl模板中静态资源引入
- ftl模板中img显示
@RequestMapping("/createPdf/{corpid}")
public ResponseEntity<byte[]> createPdf(@PathVariable(value="corpid")String corpid,HttpServletRequest request)
throws Exception {
Map<Object, Object> o = new HashMap<Object, Object>();
。。。。
//此处省略对o获取数据的过程
//获取ftl模板路径
String path = request.getSession().getServletContext().getRealPath("WEB-INF/views/page/favorable");
String uuid = UUID.randomUUID().toString().replace("-", "");
//设置图片路径,解决找不到图片问题
String imgUrl = request.getSession().getServletContext().getRealPath("WEB-INF/views/img/cx");
PdfUtils.generateToFile(request, path, "favorable.ftl", imgUrl + "/", o, path + "/" + uuid + ".pdf");
File file = new File(path + "/" + uuid + ".pdf");
// 更改下载名称
HttpHeaders headers = new HttpHeaders();
String entName=dto.getEnt_name()+".pdf";
String fileName = new String(entName.getBytes("GBK"), "iso-8859-1");// 为了解决中文名称乱码问题
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
ResponseEntity<byte[]>bytes= new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
if (file.isFile() && file.exists()) {
file.delete(); //删除掉pdf文件
}
return bytes;
}
PdfUtils 生成PDF到文件
/**
* 生成PDF到文件
* @param ftlPath 模板文件路径(不含文件名)
* @param ftlName 模板文件吗(不含路径)
* @param imageDiskPath 图片的磁盘路径
* @param data 数据
* @param outputFile 目标文件(全路径名称)
* @throws Exception
*/
public static void generateToFile(HttpServletRequest request,String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile) throws Exception {
String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
OutputStream out = null;
ITextRenderer render = null;
out = new FileOutputStream(outputFile);
render = PdfHelper.getRender(request);
render.setDocumentFromString(html);
if(imageDiskPath!=null&&!imageDiskPath.equals("")){
//render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
//在linux下file:/无法被识别,运用file:///来声明img根目录
render.getSharedContext().setBaseURL("file:///"+imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
out.close();
}
PdfHelper PDF生成辅助类
public static ITextRenderer getRender(HttpServletRequest request) throws DocumentException, IOException {
ITextRenderer render = new ITextRenderer();
String path = request.getSession().getServletContext()
.getRealPath("WEB-INF/views/page/resource");
//添加字体,以支持中文
render.getFontResolver().addFont(path + "/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
render.getFontResolver().addFont(path + "/SIMSUN.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
return render;
}
2017-08-28更新—静态打印pdf(pdf内容已知)加页码:
body里加入
<div id="footer" style=""> Page <span id="pagenumber"/> of <span id="pagecount"/> </div>
样式上加入
@page {
size:210mm 297mm;//纸张大小A4
margin: 0.25in;
-fs-flow-bottom: "footer";
-fs-flow-left: "left";
-fs-flow-right: "right";
border: thin solid black;
padding: 1em;
}
#footer {
font-size: 90%; font-style: italic;
position: absolute; top: 0; left: 0;
-fs-move-to-flow: "footer";
}
#pagenumber:before {
content: counter(page);
}
#pagecount:before {content: counter(pages);
}
以上部分的pdf添加页码,只适合对静态页面添加(知道内容或者页数固定的页面);对于动态页面的页码添加需要对添加页眉页脚了,还在研究中
来源:CSDN
作者:维尼love
链接:https://blog.csdn.net/u010515155/article/details/76186728