先给大家一个效果图:
左侧是word模板,右侧是生成后的word文档。
在工作中经常用到会有一些生成统计报告、请假等word的功能需求,小编之前做了一些报表的生成,使用过freemarker和poi,但是使用freemarker生成word有一些麻烦的点:
需要先将模板word转化为xml,而且在模板word中写好的占位符${obj}也会在转化为xml后被拆分开,还需要人工处理一次在表格循环的时候,需要使用freemarker的标签进行遍历统计图表(饼图、折线图、柱状图等),图片适配度地,操作麻烦,图表需要人工修改大量xml中的标签已达到动态修改图表数据的效果,而word转为xml时,图片是已base64进行存储,在模板替换中我们需要将图片的base64码替换为占位符这就意味着使用freemarker需要我们预先编写好word模板再转化为xml,再对xml进行freemaker的标签、占位符等的处理后才能进行word生成,而且图表支持度很低。
这里小编使用easypoi+jfree的形式进行word生成,使用jfree生成统计图表(饼图、折线图、柱状图等)图片,使用easypoi进行占位符替换、表格循环、图片插入已达到根据word模板生成word的效果。通过这个方式生成word只需要预先编写好word模板就可以进行word生成。
但这个解决方案有一种缺点就是只支持07以后的word,也就是后缀为.docx的word文档。
下面我就以Spring Boot项目为例举一个例子:
开发工具:IntelliJ IDEA
JDK:1.8
以及项目目录结构:
1、添加依赖:
cn.afterturneasypoi-base4.1.0org.jfreejcommon1.0.24org.jfreejfreechart1.5.02、编写jfreeutil工具类
作为例子,我只封装了将图片转为字节数组和根据具有生成饼状图Image实体的两个方法,各位自行参考
import cn.afterturn.easypoi.entity.ImageEntity;import lombok.extern.slf4j.Slf4j;import org.jfree.chart.ChartFactory;import org.jfree.chart.ChartUtils;import org.jfree.chart.JFreeChart;import org.jfree.chart.StandardChartTheme;import org.jfree.chart.labels.StandardPieSectionLabelGenerator;import org.jfree.chart.plot.PiePlot;import org.jfree.data.general.DefaultPieDataset;import org.springframework.util.Assert;import java.awt.*;import java.io.*;import java.util.Map;/** * @author 何昌杰 * * 参考API博客 https://blog.csdn.net/dagecao/article/details/86536680 */@Slf4jpublic class JfreeUtil { private static String tempImgPath="D:\tempJfree.jpeg"; /** * 将图片转化为字节数组 * @return 字节数组 */ private static byte[] imgToByte(){ File file = new File(tempImgPath); byte[] buffer = null; try { FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(1000); byte[] b = new byte[1000]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); } catch (IOException e) { log.error(e.getMessage()); } //删除临时文件 file.delete(); return buffer; } public static ImageEntity pieChart(String title, Map datas, int width, int height) { //创建主题样式 StandardChartTheme standardChartTheme = new StandardChartTheme("CN"); //设置标题字体 standardChartTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 20)); //设置图例的字体 standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15)); //设置轴向的字体 standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15)); //设置主题样式 ChartFactory.setChartTheme(standardChartTheme); //根据jfree生成一个本地饼状图 DefaultPieDataset pds = new DefaultPieDataset(); datas.forEach(pds::setValue); //图标标题、数据集合、是否显示图例标识、是否显示tooltips、是否支持超