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

先给大家一个效果图:

左侧是word模板,右侧是生成后的word文档。

 

在工作中经常用到会有一些生成统计报告、请假等word的功能需求,小编之前做了一些报表的生成,使用过freemarker和poi,但是使用freemarker生成word有一些麻烦的点:

  1. 需要先将模板word转化为xml,而且在模板word中写好的占位符${obj}也会在转化为xml后被拆分开,还需要人工处理一次
  2. 在表格循环的时候,需要使用freemarker的<#list list as item>标签进行遍历
  3. 统计图表(饼图、折线图、柱状图等),图片适配度地,操作麻烦,图表需要人工修改大量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、添加依赖:

        <dependency>
			<groupId>cn.afterturn</groupId>
			<artifactId>easypoi-base</artifactId>
			<version>4.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.jfree</groupId>
			<artifactId>jcommon</artifactId>
			<version>1.0.24</version>
		</dependency>
		<dependency>
			<groupId>org.jfree</groupId>
			<artifactId>jfreechart</artifactId>
			<version>1.5.0</version>
		</dependency>

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<String, Integer> 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
     * <p>第一步生成替换后的word文件,只支持docx</p>
     * <p>第二步下载生成的文件</p>
     * <p>第三步删除生成的临时文件</p>
     * 模版变量中变量格式:{{foo}}
     *
     * @param templatePath word模板地址
     * @param temDir       生成临时文件存放地址
     * @param fileName     文件名
     * @param params       替换的参数
     */
    public static void exportWord(String templatePath, String temDir, String fileName, Map<String, Object> 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<String, Object> map = new HashMap<>(4);

        //模拟饼状图数据
        HashMap<String, Integer> 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<HashMap<String, String>> list = new ArrayList<>(2);
        HashMap<String, String> 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文档

  • 14
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 57
    评论
### 回答1: 要使用Java动态获取数据库信息生成Word文档(包表格和柱状图),并且实现下载功能,可以按照以下步骤进行: 1. 连接数据库:使用Java的JDBC连接数据库,可以使用相关的驱动程序来实现。通过建立数据库连接,可以执行SQL查询语句来获取需要的数据。 2. 生成Word文档:使用Java的Apache POI库来创建和编辑Word文档。通过POI库提供的API,可以创建一个新的Word文档,并添加所需的内容,包括表格和图表。 3. 添加表格:使用POI库提供的API,可以创建表格对象并设置表格的行数和列数。然后,通过遍历数据库查询结果,将数据逐行填充到表格中。 4. 添加柱状图:使用POI库提供的API,可以创建柱状图对象,并设置图表的标题、数据源以及数据系列。通过遍历数据库查询结果,将需要的数据添加到图表的数据系列中。 5. 下载生成Word文档:可以使用Java的Servlet或Spring MVC等Web框架,在用户请求下载时生成Word文档,并将生成的文档通过HTTP响应返回给用户。可以设置适当的HTTP响应头,以使浏览器将响应内容作为文件下载。 总结: 通过JDBC连接数据库获取数据,使用Apache POI库生成Word文档,并根据数据库信息生成表格和柱状图。最后通过Web框架下载生成的文档。这种方法可以实现动态生成和下载数据库信息的Word文档,方便用户查看和使用。 ### 回答2: 在Java中,可以使用Apache POI库来生成Word文档,并使用JFreeChart库来生成柱状图。下面是一个大致的步骤来实现动态获取数据库信息生成Word文档(包表格和柱状图)并下载: 1. 首先,需要在Java项目中引入Apache POI以及JFreeChart的相关依赖。 2. 获取数据库中的数据,可以使用JDBC连接数据库,并执行SQL语句,将查询结果保存在一个数据集中。 3. 使用Apache POI的XWPFDocument类创建一个新的Word文档。 4. 在Word文档中创建一个表格,根据查询结果的行数和列数创建对应大小的表格。可以使用Apache POI的XWPFTable类来实现表格的创建,以及设置表格的样式和内容。 5. 将查询结果填充到表格中,使用Apache POI的XWPFTableCell类来设置表格中每个单元格的内容和样式。 6. 使用JFreeChart来生成柱状图,并将其插入Word文档中。可以使用JFreeChart的相关类来创建柱状图,设置图表的样式和标题,并将图表导出为一个图片文件。 7. 使用Apache POI的XWPFParagraph类创建一个段落,并将生成的柱状图的图片插入到段落中。 8. 将段落添加到Word文档中。 9. 将生成Word文档保存到服务器的指定目录下,可以使用Apache POI的XWPFDocument类的write方法将文档写入到硬盘上的一个文件中。 10. 将生成Word文档提供给用户下载,可以使用Java的文件下载功能,将生成Word文档以文件流的形式返回给用户。 以上是动态获取数据库信息生成Word文档(包表格和柱状图)并下载的大致步骤,具体的实现需要根据项目的需求进行适当的调整和完善。 ### 回答3: 要实现动态获取数据库信息生成Word并下载,可以按照以下步骤进行操作: 1. 导入所需的Java库,如Apache POI(用于操作Word文档)和JFreeChart(用于生成柱状图)。 2. 连接数据库并查询需要的数据。使用Java的数据库连接库(如JDBC)连接到数据库,并编写SQL查询语句。 3. 使用Apache POI创建Word文档,并插入表格。使用POI的API逐行读取数据库查询结果,并将数据插入Word表格中。 4. 使用JFreeChart生成柱状图。根据从数据库中查询到的数据,使用JFreeChart库生成相应的柱状图。 5. 将表格和柱状图插入Word文档中。使用POI的API将表格和柱状图插入到创建的Word文档中。 6. 设置下载功能。将生成Word文档保存到服务器上的指定路径。 7. 提供下载链接。将生成Word文档路径返回给前端,前端通过点击链接即可下载。 8. 设置下载文件的内容类型和文件名。在响应给前端的HTTP头中设置Content-Type为"application/msword",并设置Content-Disposition的attachment属性,指定下载的文件名。 通过以上步骤,可以实现动态获取数据库信息并生成Word文档(包表格和柱状图),并提供下载功能。用户可以通过点击链接下载生成Word文件。
评论 57
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值