文章首发于我的博客: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导出的场景很多,由于之前没怎么接触过,于是熬夜攻关了一下并记录了下来,接下来希望项目能顺利交付吧~

参考


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

Java怎样实现将数据导出为Word文档的更多相关文章

  1. javadoc导出成word文档

    刚刚上次弄完了一个坑爹的任务,这次我领导又给我一个让人脑瓜子疼的任务了. 基本上客户他在验收我们系统的时候,都会要求我们编写相关的文档,这次也不例外. 只是这次的客户要求我们给出接口文档.不仅是要整个 ...

  2. PowerDesigner将PDM导出生成WORD文档

    PowerDesigner将PDM导出生成WORD文档 环境 PowerDesigner15 1.点击Report Temlates 制作模板 2.如果没有模板,单击New图标创建.有直接双击进入. ...

  3. 将HTML导出生成word文档

    前言: 项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔. 当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下.下面就介绍两个导出word文档的方法. ...

  4. (转)WEB页面导出为Word文档后分页&横向打印的方法

    <html>    <HEAD>        <title>WEB页面导出为Word文档后分页&横向打印的方法 </title>    < ...

  5. 网页导出成word文档的默认视图方式问题

    网页导出成word文档的默认视图方式问题 一般保存后的word文档默认是“Web版式视图”打开,这样会给客户的感觉不是真正的word文档,必须实现打开就是“页面视图” 1. 修改<html> ...

  6. 可以把思维导图导出为word文档方便其他人查看吗?

    MindManager除了强大的大纲视图编辑功能外,还拥有多种导出格式,方便大家迅速导出文件,在团队中分享自己的观点,提高团队的工作效率,本次小编使用的思维导图软件版本是MindManager 202 ...

  7. Java中用Apache POI生成excel和word文档

    概述: 近期在做项目的过程中遇到了excel的数据导出和word的图文表报告的导出功能.最后决定用Apache POI来完毕该项功能.本文就项目实现过程中的一些思路与代码与大家共享.同一时候.也作为自 ...

  8. 如何在PowerDesigner将PDM导出生成WORD文档或者html文件

    a)         使用PowerDesigner打开pdm文件 b)         点击Report Temlates 制作模板 点击PowerDesigner菜单栏“Report” -> ...

  9. PowerDesigner将PDM导出生成WORD文档--温习老知识

    转:http://www.cnblogs.com/wudiwushen/archive/2010/05/13/1734812.html 今天的温习老知识,是如何将一个PD设计的PDM来导出WORD文档 ...

  10. Java Web项目中使用Freemarker生成Word文档

    Web项目中生成Word文档的操作屡见不鲜.基于Java的解决方式也是非常多的,包含使用Jacob.Apache POI.Java2Word.iText等各种方式,事实上在从Office 2003開始 ...

随机推荐

  1. 基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform

    前言 今天大姚给大家分享一个基于C#开源.功能强大.灵活的跨平台开发框架:Uno Platform.通过 Uno Platform,开发者可以利用单一代码库实现多平台兼容,极大地提高了开发效率和代码复 ...

  2. .NET9 - 新功能体验(一)

    被微软形容为"迄今为止最高效.最现代.最安全.最智能.性能最高的.NET版本"--.NET 9已经发布有一周了,今天想和大家一起体验一下新功能. 此次.NET 9在性能.安全性和功 ...

  3. Spring常见面试问题

    Spring 1.  Spring工作机制及为什么要用? Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.Spring既是一个AOP框架,也是一IOC容器. SpringFra ...

  4. Linux管道命令

    Linux中常用文件字符串分析的命令 在linux中文件管理与系统管理的方面,经常会用到要从一个文件中或者一长串字符串中提取你所需要的数据,或者某些字段来进行查看或者分析,作为一个初级linux小菜鸟 ...

  5. Django之跨域

    解决跨域请求问题可以从前端解决也可以通过配置后台解决,通过配置后台允许跨域可以解决前端的一些麻烦.Django通过中间件实现允许跨域. 1.安装django-cors-headers中间件 pip i ...

  6. Mybatis【16】-- Mybatis多对一关联查询

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-12-many2one,需要自取,需要配置mave ...

  7. Python 潮流周刊#81:在个人电脑上运行 GPT-4 级别的大模型(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  8. 在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析

    本文主要分析了在 K8s 中创建一个 Pod 并申请 GPU 资源,最终该 Pod 时怎么能够使用 GPU 的,具体的实现原理,以及 device plugin.nvidia-container-to ...

  9. Qt编写地图综合应用21-路径规划

    一.前言 近期重新将这个地图综合应用进行大幅度的改进更新升级,包括使用示例也做了非常多的改进和调整,其中就包括路径规划功能,之前只是调用了百度地图的JS交互接口,根据起始点坐标经纬度和结束点坐标经纬度 ...

  10. Qt音视频开发9-ffmpeg录像存储

    一.前言 上一篇文章写道直接将视频流保存裸流到文件,尽管裸流文件有一定的好处,但是 毕竟大部分用户需要的不是裸流而是MP4视频文件,所以需要将视频流保存成MP4文件,毕竟电脑上的播放器包括默认的播放器 ...