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

打印 上一主题 下一主题

主题 862|帖子 862|积分 2586

文章首发于我的博客: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}}来表现
如果表格中某一列是图片,则表现为[@变量]

模板绘制好以后,开始使用poi-tl工具生成word文档,首先新建maven项目,引入poi-tl的依赖和需要的其他依赖,然后将这个绘制好的word模板文件放在工程的根目录
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>org.example</groupId>
  7.     <artifactId>poi-tl</artifactId>
  8.     <version>1.0-SNAPSHOT</version>
  9.     <properties>
  10.         <maven.compiler.source>8</maven.compiler.source>
  11.         <maven.compiler.target>8</maven.compiler.target>
  12.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13.     </properties>
  14.     <dependencies>
  15.         <dependency>
  16.             <groupId>com.deepoove</groupId>
  17.             <artifactId>poi-tl</artifactId>
  18.             <version>1.12.2</version>
  19.         </dependency>
  20.         <dependency>
  21.             <groupId>org.projectlombok</groupId>
  22.             <artifactId>lombok</artifactId>
  23.             <version>1.18.24</version>
  24.             <scope>provided</scope>
  25.         </dependency>
  26.     </dependencies>
  27. </project>
复制代码
然后,新建一个Entity类: org.example.TravelApplyExportVO
  1. package org.example;
  2. import com.deepoove.poi.data.PictureRenderData;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. @Data
  9. @AllArgsConstructor
  10. @NoArgsConstructor
  11. public class TravelApplyExportVO {
  12.     private String no;
  13.     private String name;
  14.     private String dept;
  15.     private String employeeNo;
  16.     private String start;
  17.     private String end;
  18.     private String days;
  19.     private String address;
  20.     private String reason;
  21.     /**
  22.      * com.deepoove.poi.data.PictureRenderData 代表图片
  23.      */
  24.     private PictureRenderData applyPin;
  25.     private PictureRenderData bossPin;
  26.     private PictureRenderData leaderPin;
  27.     private String date;
  28.     /**
  29.      * 用于渲染表格的集合
  30.      */
  31.     private List<Route> tripList = new ArrayList<>();
  32.     @Data
  33.     @AllArgsConstructor
  34.     @NoArgsConstructor
  35.     public static class Route {
  36.         private String from;
  37.         private String to;
  38.         private String flight;
  39.         private String depTime;
  40.         private String arrTime;
  41.         private String cabin;
  42.     }
  43. }
复制代码
新建测试类: org.example.Main,用poi-tl组件基于刚刚绘制的word模板生成一个差旅行程单
  1. package org.example;
  2. import com.deepoove.poi.XWPFTemplate;
  3. import com.deepoove.poi.config.Configure;
  4. import com.deepoove.poi.data.PictureRenderData;
  5. import com.deepoove.poi.data.Pictures;
  6. import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
  7. import lombok.SneakyThrows;
  8. import java.nio.file.Files;
  9. import java.nio.file.Paths;
  10. import java.util.ArrayList;
  11. public class Main {
  12.     @SneakyThrows
  13.     public static void main(String[] args) {
  14.         TravelApplyExportVO vo = new TravelApplyExportVO();
  15.         vo.setNo("202500001");
  16.         vo.setName("lzj");
  17.         vo.setDept("技术部");
  18.         vo.setEmployeeNo("00000001");
  19.         vo.setStart("2025-01-01");
  20.         vo.setEnd("2025-02-01");
  21.         vo.setDays("30");
  22.         vo.setAddress("中国香港");
  23.         vo.setReason("系统维护");
  24.         // 在项目根路径读取笔迹图片,并设置大小
  25.         PictureRenderData data1 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img2.png")))
  26.                 .size(120, 60)
  27.                 .create();
  28.         PictureRenderData data2 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png")))
  29.                 .size(120, 60)
  30.                 .create();
  31.         PictureRenderData data3 = Pictures.ofBytes(Files.readAllBytes(Paths.get("img.png")))
  32.                 .size(120, 60)
  33.                 .create();
  34.         vo.setApplyPin(data1 );
  35.         vo.setBossPin( data2);
  36.         vo.setLeaderPin( data3);
  37.         vo.setDate("2025-01-10");
  38.         // 行程List,最终渲染到文档的表格中
  39.         vo.setTripList(new ArrayList<TravelApplyExportVO.Route>() {
  40.             {
  41.                 add(new TravelApplyExportVO.Route("BJX","ZQZ","ZH5643","2025-01-01 15:00","2025-01-01 16:00","E"));
  42.                 add(new TravelApplyExportVO.Route("ZQZ","CDE","JUH6532","2026-01-01 15:00","2025-12-01 16:00","A"));
  43.                 add(new TravelApplyExportVO.Route("BJX","ZQZ","KJU0954","2027-01-01 15:00","2025-05-01 16:00","Q"));
  44.             }
  45.         });
  46.         LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
  47.         // !!将tripList通过表格来渲染
  48.         Configure config = Configure.builder()
  49.                 .bind("tripList", policy)
  50.                 .build();
  51.         XWPFTemplate template = XWPFTemplate
  52.                 .compile("模板.docx", config)
  53.                 .render(vo);
  54.         template.writeAndClose(Files.newOutputStream(Paths.get("output.docx")));
  55.     }
  56. }
复制代码
然后领导署名笔记图片素材img.png,img2.png也需要放进工程根目录下
都完成后,执行main()方法测试,步伐运行结束后,将在根路径生成文件output.docx,打开就是我们想要的效果了。

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表