最近做了一个奇葩的需求,研究了一下Java纯后端生成PDF报表的方案,顺便将研究的方案做个总结复盘,分享一下。
需求分析:Java后端定时任务统计汇总成报表数据,并生成PDF格式的报表文件,并通过邮件、企业微信等发送给指定接收人。报表界面包含动态文字说明、折线图、饼图、条形图等图表,界面效果和前端生成的界面相同。
功能难点:前端要生成样式好看的图表比较简单,像Echarts这些前端工具都有现成的功能来完成。但是现在的需求是后端定时任务生成报表文件,报表界面的渲染都必须有后端来完成,由于缺少前端的用户操作动作,也无法在前端生成图表的图片后传到后端来。
方案一:
使用FreeMarker iText生成PDF文件。
原理和流程:
FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。
iText是一种生成PDF报表的Java组件。通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,这样就很好的解决了B/S系统的报表处理问题。
具体的流程如下:
缺点:这种方案只能生成很简单的Table模板,由于iText对html的要求非常严格,太复杂的界面会报错,所以无法生成echarts的图表。
方案二:
SwingUI JFreeChart JFreePDF生成PDF文件
这里JFreeChart和JFreePDF都是maven依赖包
JFreeChart是Java客户端应用的一个界面组件,在SwingUI上画出图表控件。
JFreePDF是能将JPanel面板截屏生成PDF的插件。
流程和原理:
缺点:
由于是将JPanel截屏生成的PDF。所以界面样式上比较难看,比不上前端界面生成的报表页面。
而且JFreePDF这个maven依赖的插件是基于JDK11开发的,如果要兼容JDK8,就要到github上将源码下载下来,自己编译生成一个兼容JDK8的依赖包。
方案三:(最终采用方案)
使用wkhtmltopdf 静态html界面生成pdf界面
wkhtmltopdf是一个将静态html网页截屏生成pdf文件的工具,Linux、Mac、Windows各个操作系统的版本都有。只需要输入目标网页的URL就能将网页完成的导出PDF文件。
流程和原理:
1.在操作系统安装wkhtmltopdf工具
2.前端编码html jquery echarts的纯静态页面,由于wkhtmltopdf工具使用内置的WebKit内核版本较低,所以不兼容太新的js语言,像VueJS这些最新的框架就无法使用这个工具。目前测试的能够兼容的echarts版本是4.2.1.
3.调用wkhtmltopdf命令输入静态网页地址生成pdf文件。
之前为了调试网页写了一个Java桌面应用来调用wkhtmltopdf工具生成pdf。
github地址:https://github.com/WrathLi/html2pdf
缺点:
1.需要在服务器系统中先安装wkhtmltopdf工具;
2.只能单独开发一个纯静态的html页面来生成报表
优点:
界面美观,因为是直接截取html网页,所以和前端生成的图表样式一样。
开发量最小。
最终效果: