admin 管理员组

文章数量: 1087548

工作中碰到了需要导出Word表格文档的需求,最简单的方式就是使用easypoi先配置好word模板文件(使用他的插值语法),准备好需要导出的数据直接导出即可。

不过在测试时发现,使用循环插值语法导出表格中部分列表内容时会出现表格错位的问题。

网上找了许多方法都不能解决(我甚至使用原生poi去写这一块循环生成的表格,捣鼓了一天发现导出来的跟用easypoi导出来的一模一样,错位问题也一模一样。吐血了,怕不是把easypoi实现他的循环插值语法的方法手写出来了),最后使用freemarker将模版文件转成xml格式,再根据freemarker的模板语法修改xml模板文件后成功解决。

1. 使用easypoi导出Word文档

1.1 添加依赖

<dependency>
     <groupId>cn.afterturn</groupId>
     <artifactId>easypoi-spring-boot-starter</artifactId>
     <version>4.4.0</version>
</dependency>

1.2 设置Word模板

这里只贴出出现表格错位的部分模板

easypoi支持的插值语法如下:

1.3 准备表格数据

将所有数据封装为一个Map即可

1.4 编写导出工具代码

    /**
     * 导出word
     * 模版变量中变量格式:{
  {a}}
     *
     * @param templatePath word模板地址
     * @param fileName     文件名
     * @param params       替换的参数
     * @param response     响应头
     *
     */
    public static void exportWord(String templatePath, String fileName, Map<String, Object> params, HttpServletResponse response) {
        Assert.notNull(templatePath, "模板路径不能为空");
        Assert.notNull(fileName, "导出文件名不能为空");
        Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");

        try {
            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);

            //设置响应体内容类型
            response.setContentType("application/octet-stream");
            //添加响应头
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            //暴露新添加的响应头
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            //将word文档流输出到输出流中
            doc.write(response.getOutputStream());
            //关闭流
            doc.close();
        } catch (Exception e) {
            log.error("exportWord方法出现问题", e);
        }
    }

1.5 调用接口导出word

上面的导出工具是通过设置响应请求头,在浏览器调用请求后进行导出文件下载。

如果想要直接下载到本地,直接将设置响应头的代码改成使用File对象获取输出流即可。

1.6 导出表格错位展示

导出后,循环遍历导出的错位问题如下:

2. 使用freemarker导出Word文档

2.1 添加依赖

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

2.2 设置xml模版文件

直接将上面的Word模板文件另存为XML格式文件,再将文件改为ftl格式(直接改文件后缀名即可)。将文件加入到项目中,我是放在了如下位置:

再将文件在idea中打开,先格式化一下xml文本,再按照freemarker的插值语法进行修改。

这里只贴出表格错位部分的xml模板内容:

说明:

1、找到需要循环生成的那一行,即对应的 <w:tr> 标签,在开始标签前加上 <#list summaries as item> ,同时在结束标签后加上 </#list> (有开有闭)。完成循环生成的语句的编写。

2、找到表格中需要插值的位置,将原来的插值语句改为 ${item.val} 的形式,因为在上面的循环语句中将 list 中的单元素定义为了 item。

3、因为我这里的表格还需要将每一行的第3个单元格进行合并单元格的操作,所以还需要编写合并单元格的语句。

先在 <w:tr> 前加上 <#if item_index==0> 判断语句(语意为:当处理 list 中的第一个元素时,使用下面的xml文本),同时找到需要合并的单元格的 <w:tc> 标签内容中的 <w:tcW> 标签,在该标签下加上 <w:vMerge w:val="restart"/> &

本文标签: 表格 freemarker easypoi Word