Java怎样实现将数据导出为Word文档

文章首发于我的博客:Java怎样实现将数据导出为Word文档 - Liu Zijian's Blog

我们在开发一些系统的时候,例如OA系统,经常能遇到将审批单数据导出为word和excel文档的需求,导出为excel是比较简单的,因为excel有单元格来供我们定位数据位置,但是word文档的格式不像表格那样可以轻松的定位,要想将数据导出为一些带有图片和表格的这种结构复杂的word文档该怎样实现呢。

poi-tl [1]是一款可以帮助我们实现这种功能的Java开源项目,它把POI和Freemarker相结合,可以基于我们绘制好的word文档模板来填充数据进去,然后生成新的word文档。poi-tl托管在GitHub:https://github.com/Sayi/poi-tl

例如,我们要生成一个差旅行程单,首先要绘制这样的一个word文档模板,用{{name}}代表姓名进行占位,姓名就是普通文字类型,以此类推。tripList作为渲染行程表格的数据源的名字,是ArrayList集合类型,放在表格的表头,用[from]表示tripList集合中每个元素的from属性的值,渲染到当前行的某一列上,以此类推。最后的三个签署对应的是领导的签名笔迹图片,图片类型要用变量名前多一个@的形式{{@****Pin}}来表示

如果表格中某一列是图片,则表示为[@变量]

image

模板绘制好以后,开始使用poi-tl工具生成word文档,首先新建maven项目,引入poi-tl的依赖和需要的其他依赖,然后将这个绘制好的word模板文件放在工程的根目录

```xml


    4.0.0

    org.example
    poi-tl
    1.0-SNAPSHOT

    
        8
        8
        UTF-8
    

    
        
            com.deepoove
            poi-tl
            1.12.2
        

        
            org.projectlombok
            lombok
            1.18.24
            provided
        
    


```

然后,新建一个Entity类: org.example.TravelApplyExportVO

```java
package org.example;

import com.deepoove.poi.data.PictureRenderData;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TravelApplyExportVO {
    private String no;
    private String name;
    private String dept;
    private String employeeNo;
    private String start;
    private String end;
    private String days;
    private String address;
    private String reason;
    /**
     * com.deepoove.poi.data.PictureRenderData 代表图片
     */
    private PictureRenderData applyPin;
    private PictureRenderData bossPin;
    private PictureRenderData leaderPin;

    private String date;

    /**
     * 用于渲染表格的集合
     */
    private List tripList = new ArrayList<>();

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Route {
        private String from;
        private String to;
        private String flight;
        private String depTime;
        private String arrTime;
        private String cabin;
    }
}
```

新建测试类: org.example.Main,用poi-tl组件基于刚刚绘制的word模板生成一个差旅行程单

```java
package org.example;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import lombok.SneakyThrows;


import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;

public class Main {

    @SneakyThrows
    public static void main(String[] args) {

        TravelApplyExportVO vo = new TravelApplyExportVO();
        vo.setNo("202500001");
        vo.setName("lzj");
        vo.setDept("技术部");
        vo.setEmployeeNo("00000001");
        vo.setStart("2025-01-01");
        vo.setEnd("2025-02-01");
        vo.setDays("30");
        vo.setAddress("中国香港");
        vo.setReason("系统维护");

        // 在项目根路径读取笔迹图片,并设置大小
        PictureRenderData data1 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img2.png")))
                .size(120, 60)
                .create();

        PictureRenderData data2 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png")))
                .size(120, 60)
                .create();

        PictureRenderData data3 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png")))
                .size(120, 60)
                .create();

        vo.setApplyPin(data1 );
        vo.setBossPin( data2);
        vo.setLeaderPin( data3);

        vo.setDate("2025-01-10");

        // 行程List,最终渲染到文档的表格中
        vo.setTripList(new ArrayList() {
            {
                add(new TravelApplyExportVO.Route("BJX","ZQZ","ZH5643","2025-01-01 15:00","2025-01-01 16:00","E"));
                add(new TravelApplyExportVO.Route("ZQZ","CDE","JUH6532","2026-01-01 15:00","2025-12-01 16:00","A"));
                add(new TravelApplyExportVO.Route("BJX","ZQZ","KJU0954","2027-01-01 15:00","2025-05-01 16:00","Q"));
            }
        });

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();

        // !!将tripList通过表格来渲染
        Configure config = Configure.builder()
                .bind("tripList", policy)
                .build();

        XWPFTemplate template = XWPFTemplate
                .compile("模板.docx", config)
                .render(vo);

        template.writeAndClose(Files.newOutputStream(Paths.get("output.docx")));
    }
}
```

然后领导签名笔记图片素材img.png,img2.png也需要放进工程根目录下

都完成后,执行main()方法测试,程序运行结束后,将在根路径生成文件output.docx,打开就是我们想要的效果了。

image

文章写到这已经是深夜了,最新在开发一个OA系统,需要Word导出的场景很多,由于之前没怎么接触过,于是熬夜攻关了一下并记录了下来,接下来希望项目能顺利交付吧~

参考


  1. https://deepoove.com/poi-tl/ ↩︎

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/6143.html

(0)
LomuLomu
上一篇 2025 年 1 月 13 日 上午6:11
下一篇 2025 年 1 月 13 日 上午6:47

相关推荐

  • Python深度学习(第2版)PDF免费下载

    适读人群 :想要学习深度学习的学生、职业开发者。 流行深度学习框架Keras之父执笔,涵盖Transformer架构等进展,文字生,简单方式解释复杂概念,不用一个数学公式,利用直觉自然入门深度学习。 电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍 点击原文去下载 书籍信息 作者: [美] 弗朗索瓦·肖莱出版社: 人民邮电出版社出品方…

    2025 年 1 月 1 日
    15900
  • Java【多线程】(1)进程与线程

    “`markdown 目录 1. 前言 2. 正文 2.1 什么是进程 2.2 PCB(进程控制块) 2.2.1 进程id 2.2.2 内存指针 2.2.3 文件描述符表 2.2.4 进程状态 2.2.4.1 就绪状态 2.2.4.2 阻塞状态 2.2.5 进程优先级 2.2.6 进程上下文 2.2.7 进程的记账信息 2.3 CPU操作进程的方法 2.4…

    2024 年 12 月 28 日
    18000
  • 华为OD机试E卷 –游戏分组–24年OD统一考试(Java & JS & Python & C & C++)

    文章目录 题目描述 输入描述 输出描述 用例 题目解析 Js算法源码 python算法源码 java算法源码 c++算法源码 c算法源码 题目描述 部门准备举办一场王者荣耀表演赛,有 10 名游戏爱好者参与,分为两队,每队 5 人。每位参与者都有一个评分,代表着他的游戏水平。为了表演赛尽可能精彩,我们需要把 10 名参赛者分为示例尽量相近的两队。一队的实力可…

    未分类 2025 年 1 月 5 日
    21000
  • MySQL 优化利器 SHOW PROFILE 的实现原理

    背景 近期,我遇到了一个技术挑战:通过传输表空间的方式导入一个体积达4GB的表,整个过程耗时13分钟。通过PROFILE工具的分析,我惊讶地发现,大部分时间竟然花费在了System lock阶段。 mysql> set profiling=1; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> al…

    未分类 2024 年 12 月 24 日
    19400
  • Python深度学习(第2版)PDF免费下载

    适读人群 :想要学习深度学习的学生、职业开发者。 流行深度学习框架Keras之父执笔,涵盖Transformer架构等进展,文字生,简单方式解释复杂概念,不用一个数学公式,利用直觉自然入门深度学习。 电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍 点击原文去下载 书籍信息 作者: [美] 弗朗索瓦·肖莱出版社: 人民邮电出版社出品方…

    2024 年 12 月 31 日
    13800

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信