前言
最近遇到了一个需求:后台根据存储数据生成一个PDF报表,里面还会有各种分析图表,经过技术调研后,大体技术栈如下
- 使用
poi-tl
来作为报表模板,生成word文档
- 使用
jfreechart
来进行各种分析图表生成
- 随后将生成word文档转换为PDF即可
开放思路理清后,下面就来了解一下怎么编码把~
poi-tl
poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档。
上面就是官方的介绍,它支持动态将标签渲染为文本、图片、表格、图表等,能够满足我们的各种需求。
同时官方还列举了与其他word模板框架的对比:
方案 |
移植性 |
功能性 |
易用性 |
Poi-tl |
Java跨平台 |
Word模板引擎,基于Apache POI,提供更友好的API |
低代码,准备文档模板和数据即可 |
Apache POI |
Java跨平台 |
Apache项目,封装了常见的文档操作,也可以操作底层XML结构 |
文档不全,这里有一个教程:Apache POI Word快速入门 |
Freemarker |
XML跨平台 |
仅支持文本,很大的局限性 |
不推荐,XML结构的代码几乎无法维护 |
OpenOffice |
部署OpenOffice,移植性较差 |
- |
需要了解OpenOffice的API |
HTML浏览器导出 |
依赖浏览器的实现,移植性较差 |
HTML不能很好的兼容Word的格式,样式糟糕 |
- |
Jacob、winlib |
Windows平台 |
- |
复杂,完全不推荐使用 |
那么下面就来写个demo试试,是否能够满足我的需求~
demo例子
首先创建一个word文档,创建了一个文本标签和图片标签
1 2 3
| // quick-start.docx {{str}} {{@img}}
|
随后在项目中引入相关依赖
1 2 3 4 5
| <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.0</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Test public void testPoiTl() throws IOException { InputStream inputStream = this.getClass().getResourceAsStream( "/word/quick-start.docx" ); JFreeChart barChart = generateJFreeChart(); BufferedImage bufferedImage = barChart.createBufferedImage( 640, 480 ); XWPFTemplate template = XWPFTemplate.compile( inputStream ).render( new HashMap<String, Object>() {{ put( "str", "Hi, poi-tl Word模板引擎" ); put( "img", Pictures.ofBufferedImage( bufferedImage, PictureType.PNG ).size( 640,480 ).create() ); // 先不用理这一行 }} ); template.writeAndClose( new FileOutputStream( "./word/output.docx" ) ); }
|
上面的代码可以分为三部分:
- 调用compile方法对word模板进行编译,读取相关标签
- 调用render方法替换标签,进行渲染数据操作
- 随后将渲染后的word文档进行输出
将其称为:TDO模式:Template + data-model = output
jfreechart
通过上面的代码,可以看到图表的生成我使用了JFreeChart
类,这是jfreechart中条状图的实现类。
JFreeChart是一个适用于Java™平台的综合免费图表库,可以在客户端(JavaFX和Swing)或服务器端使用,可导出多种格式,包括SVG、PNG和PDF。
该项目的文档可能比较少,不过官方提供了一个demo库来让我们学习相关API:jfree/jfree-demos: Various demo programs for JFree projects (github.com)
demo例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @Test public void testGenerateChart() throws IOException { JFreeChart barChart = generateJFreeChart(); ChartUtils.saveChartAsJPEG( new File( "./word/chart.jpeg" ), barChart, 640, 480 ); }
public JFreeChart generateJFreeChart() { // 条状图的标题 String chartTitle = "测试条状图"; // 行名称 String departmentName1 = "文商学院"; String departmentName2 = "汽车学院"; String departmentName3 = "创意学院"; // 需要注意中文图表需要使用Font类来进行设置,否则会乱码 Font font = new Font( "宋体", Font.BOLD, 15 ); DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset(); // 设置图表值 categoryDataset.setValue( 90, departmentName1, departmentName1 ); categoryDataset.setValue( 91, departmentName2, departmentName2 ); categoryDataset.setValue( 81, departmentName3, departmentName3 );
JFreeChart barChart = ChartFactory.createBarChart( chartTitle, "部门", "分数", categoryDataset, PlotOrientation.VERTICAL, true, true, false ); // 设置font类型 barChart.getTitle().setFont( font ); barChart.getLegend().setItemFont( font ); CategoryPlot categoryPlot = barChart.getCategoryPlot(); CategoryAxis domainAxis = categoryPlot.getDomainAxis(); domainAxis.setLabelFont( font ); domainAxis.setTickLabelFont( font ); categoryPlot.getRangeAxis().setLabelFont( font ); categoryPlot.getRangeAxis().setTickLabelFont( font ); return barChart; }
|
最终生成的图表图片如下图:
小结
通过上面两个例子就可以看到,使用poi-tl和jfreechart框架就可以实现各种报表文档的生成拉,如果还有其他需求就去官方看看把。