news 2026/4/14 16:12:09

Springboot项目中使用EasyPOI方式导出合同word文档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Springboot项目中使用EasyPOI方式导出合同word文档

在Java开发中,使用EasyPOI导出Word合同文档是一种高效且灵活的解决方案。通过模板驱动的方式,开发者可以轻松地将动态数据填充到预设的Word模板中,生成格式规范的合同文件 。这种方法特别适合需要批量生成标准化合同、协议或报告的场景。

1、需求

使用easyPOI方式导出合同word文档。

前几篇文章,我们注重讲了使用EasyPoi操作Excel文件的详细流程,使用Word模板和Excel模板用法基本一致,支持的标签也是一致的,仅仅**支持07版本的word**也是只能生成后缀是docx的文档,本文我们就拿docx做导出功能,

2、导入依赖

版本兼容性
确保使用EasyPOI 4.3.0及以上版本,旧版本可能不支持多图片循环导出等高级功能。同时注意Spring Boot版本与EasyPOI的兼容性:

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

3、模板指令

EasyPOI提供了丰富的模板指令,可以处理各种复杂的合同导出需求。掌握这些指令能让你的合同文档更加灵活和强大。
下面列举下EasyPoi支持的指令以及作用,最主要的就是各种fe的用法:

三元运算{{test ? obj:obj2}}n: 表示 这个cell是数值类型{{n:}}le: 代表长度{{le:()}}在if/else 运用{{le:()>8? obj1:obj2}}fd: 格式化时间{{fd:(obj;yyyy-MM-dd)}}fn: 格式化数字{{fn:(obj;###.00)}}fe: 遍历数据,创建row!fe: 遍历数据不创建row$fe:下移插入,把当前行,下面的行全部下移.size()行,然后插入#fe: 横向遍历v_fe: 横向遍历值!if: 删除当前列{{!if:(test)}}单引号表示常量值 ‘’ 比如’1’ 那么输出的就是1&NULL&空格&INDEX&表示循环中的序号,自动添加]]换行符 多行遍历导出 sum: 统计数据
指令功能描述合同应用示例
{{fe:resourceList }}遍历列表数据创建行合同条款列表、附件清单
{{fd:date;yyyy-MM-dd}}格式化日期合同签署日期、生效日期
{{fn:amount;.00}}格式化数字合同金额、违约金计算
{{if:condition}}条件判断显示/隐藏可选条款、特殊约定
{{}}换行符多行地址、条款换行

对于复杂的合同表格,可以使用{{fe:tableData}}指令动态生成多行数据。例如在合同附件清单中,可以通过遍历List数据自动生成表格行,每行包含附件名称、编号、页数等信息。

4、制作模板

  1. 根据上述的指令要求,我们制作模板如下:
  2. 把制作好的模板放入到项目中

5、代码实现

5.1、UserController

修改原来的导出合同的方法:

@GetMapping(value="/downloadContract",name="导出用户合同")publicvoiddownloadContract(Longid,HttpServletResponseresponse)throwsException{// userService.downloadContract(id,response);userService.downloadContractWithEasyPOI(id,response);}

5.2、IUserService

voiddownloadContractWithEasyPOI(Longid,HttpServletResponseresponse)throwsException;

5.3、UserServiceImpl

@OverridepublicvoiddownloadContractWithEasyPOI(Longid,HttpServletResponseresponse)throwsException{FilerootPath=newFile(ResourceUtils.getURL("classpath:").getPath());//SpringBoot项目获取根目录的方式FiletemplatePath=newFile(rootPath.getAbsolutePath(),"/word_template/contract_template2.docx");// 先获取导出word需要的数据Useruser=this.findById(id);// 把需要的数据放到map中,方便替换SimpleDateFormatsimpleDateFormat=newSimpleDateFormat("yyyy-MM-dd");Map<String,Object>params=newHashMap<String,Object>();params.put("userName",user.getUserName());params.put("hireDate",simpleDateFormat.format(user.getHireDate()));params.put("address",user.getAddress());// 下面是表格中需要的数据List<Map>resourceList=newArrayList<>();Map<String,Object>map=null;for(Resourceresource:user.getResourceList()){map=newHashMap<String,Object>();map.put("name",resource.getName());map.put("price",resource.getPrice());map.put("needReturn",resource.getNeedReturn());ImageEntityimage=newImageEntity();image.setHeight(64);image.setWidth(72);image.setUrl(rootPath.getPath()+"\\static"+resource.getPhoto());map.put("photo",image);resourceList.add(map);}// 把组建好的表格需要的数据放到大map中params.put("resourceList",resourceList);// 根据模板+数据 导出文档XWPFDocumentxwpfDocument=WordExportUtil.exportWord07(templatePath.getPath(),params);Stringfilename=user.getUserName()+"_合同.docx";// 设置文件的打开方式和mime类型ServletOutputStreamoutputStream=response.getOutputStream();response.setHeader("Content-Disposition","attachment;filename="+newString(filename.getBytes(),"ISO8859-1"));response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");xwpfDocument.write(outputStream);}

其中findById方法代码如下:

@OverridepublicUserfindById(Longid)throwsException{Useruser=userMapper.selectById(id);List<Resource>resources=resourceMapper.selectList(newQueryWrapper<Resource>().in("user_id",id));user.setResourceList(resources);returnuser;}

6、导出结果


说明:

  1. 使用.docx格式:模板必须保存为.docx格式(Word 2007+),不支持旧的.doc格式;
  2. 占位符格式:严格使用{{变量名}}格式,前后不能有空格;
  3. 复杂表格处理:对于动态行表格,在模板中只需设计一行,EasyPOI会自动复制并填充数据;
  4. 图片导出:如果需要导出合同中的公司logo或签名图片,使用ImageEntity类进行配置。


“人的一生会经历很多痛苦,但回头想想,都是传奇”。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 12:23:46

深夜的“闪电侠”:在线监测如何让电网故障秒级“自愈”

深夜&#xff0c;雷雨交加。一道闪电划过&#xff0c;小区突然陷入黑暗。然而就在你刚摸到手机&#xff0c;准备发朋友圈吐槽时&#xff0c;灯光瞬间恢复了。前后不过几秒钟&#xff0c;快得让人以为是错觉。这不是电网魔法&#xff0c;而是现代电力系统的“智慧大脑”——在线…

作者头像 李华
网站建设 2026/4/14 20:08:09

选延时摄影白云大海素材库?5个免费站+3个坑别踩!

根据《2025中国数字创意产业发展报告》显示&#xff0c;2025年国内延时摄影素材的需求同比增长了35%&#xff0c;其中白云大海类自然景观素材的下载量占比达22%&#xff0c;成为短视频、广告制作中的热门选择。但很多创作者在寻找**延时摄影白云大海视频素材库**时&#xff0c;…

作者头像 李华
网站建设 2026/4/15 9:13:45

基因组+单细胞--弥漫性大B细胞淋巴瘤的生物学变异轴向

作者&#xff0c;Evil Genius分享文章之前&#xff0c;大家对基因组 单细胞的联合分析思路有了解了么&#xff1f;单细胞分析的CNV可以和WES的CNV分析相互对应么&#xff1f;比较维度WES-CNV (基于Bulk WES)scCNV (基于scRNA-seq&#xff0c;如inferCNV分析)互补与验证关系检测…

作者头像 李华
网站建设 2026/4/13 18:18:42

火山云豆包:重新定义AI交互,让智能触手可及

火山云豆包&#xff1a;重新定义AI交互&#xff0c;让智能触手可及在人工智能技术日新月异的今天&#xff0c;火山云豆包模型以其卓越的性能和人性化的交互体验&#xff0c;正逐渐成为用户心中智能助手的新标杆。这款由火山引擎自主研发的AI模型&#xff0c;凭借强大的自然语言…

作者头像 李华
网站建设 2026/4/14 12:41:04

小白程序员也能掌握的AI黑科技:本体驱动的零噪声GraphRAG,让知识图谱自我进化,告别“裸奔“数据垃圾场!

今天分享一个不错的开源项目trustgraph&#xff1a;AI 上下文图谱工厂&#xff0c;构建、管理并部署专为 AI 优化的上下文图谱 但是重点要分享的是其中关于本体驱动的零噪声GraphRAG部分 为什么要用本体Ontology尼&#xff0c;原因在于&#xff1a;构建一张会自我完善的知识图…

作者头像 李华