java生成word(报告报表)含统计图表图片、循环表格,Spring Boot整合word生成 您所在的位置:网站首页 数据表格统计下载 java生成word(报告报表)含统计图表图片、循环表格,Spring Boot整合word生成

java生成word(报告报表)含统计图表图片、循环表格,Spring Boot整合word生成

2023-08-10 17:10| 来源: 网络整理| 查看: 265

先给大家一个效果图:

左侧是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.afterturn easypoi-base 4.1.0 org.jfree jcommon 1.0.24 org.jfree jfreechart 1.5.0

2、编写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 */ @Slf4j public 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、是否支持超链接 JFreeChart chart = ChartFactory.createPieChart(title, pds, true, false, false); //设置抗锯齿 chart.setTextAntiAlias(false); PiePlot plot = (PiePlot) chart.getPlot(); plot.setNoDataMessage("暂无数据"); //忽略无值的分类 plot.setIgnoreNullValues(true); plot.setBackgroundAlpha(0f); //设置标签阴影颜色 plot.setShadowPaint(new Color(255,255,255)); //设置标签生成器(默认{0}) plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}({1})/{2}")); try { ChartUtils.saveChartAsJPEG(new File(tempImgPath), chart, width, height); } catch (IOException e1) { log.error("生成饼状图失败!"); } ImageEntity imageEntity = new ImageEntity(imgToByte(), width, height); Assert.notNull(imageEntity.getData(),"生成饼状图对象失败!"); return imageEntity; } }

关于jfree的一些API接口,和图形图表属性设置各位可参考这篇博客。

注:@Slf4j注解需要添加lombok的依赖

3、编写wordutil工具类

import cn.afterturn.easypoi.word.WordExportUtil; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.util.Assert; import java.io.File; import java.io.FileOutputStream; import java.util.Map; /** * @author 何昌杰 */ public class WordUtil { /** * 导出word *

第一步生成替换后的word文件,只支持docx

*

第二步下载生成的文件

*

第三步删除生成的临时文件

* 模版变量中变量格式:{{foo}} * * @param templatePath word模板地址 * @param temDir 生成临时文件存放地址 * @param fileName 文件名 * @param params 替换的参数 */ public static void exportWord(String templatePath, String temDir, String fileName, Map params) { Assert.notNull(templatePath, "模板路径不能为空"); Assert.notNull(temDir, "临时文件路径不能为空"); Assert.notNull(fileName, "导出文件名不能为空"); Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式"); if (!temDir.endsWith("/")) { temDir = temDir + File.separator; } File dir = new File(temDir); if (!dir.exists()) { dir.mkdirs(); } try { XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params); String tmpPath = temDir + fileName; FileOutputStream fos = new FileOutputStream(tmpPath); doc.write(fos); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } }

4、编写word模板

关于word中的更多表达式各位可参考easypoi文档的3节内容。

5、编写测试类

import java.util.ArrayList; import java.util.HashMap; import cn.afterturn.easypoi.entity.ImageEntity; import com.springclouddemo.freemarkerdemo.utils.JfreeUtil; import com.springclouddemo.freemarkerdemo.utils.WordUtil; /** * @author 何昌杰 */ public class WordDemo1 { public static void main(String[] args) { HashMap map = new HashMap(4); //模拟饼状图数据 HashMap datas = new HashMap(3); datas.put("一号",10); datas.put("二号",20); datas.put("三号",40); ImageEntity imageEntity = JfreeUtil.pieChart("测试",datas, 500, 300); map.put("picture", imageEntity); //模拟其它普通数据 map.put("username", "张三"); map.put("date", "2019-10-10"); map.put("desc", "测试"); map.put("boo", true); //模拟表格数据 ArrayList list = new ArrayList(2); HashMap temp = new HashMap(3); temp.put("sn","1"); temp.put("name","第一个人"); temp.put("age","23"); list.add(temp); temp = new HashMap(3); temp.put("sn","2"); temp.put("name","第二个人"); temp.put("age","24"); list.add(temp); map.put("personlist",list); //word模板相对路径、word生成路径、word生成的文件名称、数据源 WordUtil.exportWord("template/demo1.docx", "D:/", "生成文件.docx", map); } }

6、运行测试

生成后的word文档



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有