告别XML模板的繁琐!Word文档导出,easy!

word模板导出

最近项目中有个功能,导出月报,发现同事使用了docx格式模板,感觉比之前转成xml的简单多了,这边记录下使用方法。
xml方式导出word,模板太复杂了

资料

poi-tl

一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性


官方文档地址 ,还是很详细的,有多个场景的示例

如何使用

  • 必要的标签知识
    • 文字

    {{var}}

    • 数据模型:
     String :文本TextRenderData :有样式的文本HyperlinkTextRenderData :超链接和锚点文本Object :调用 toString() 方法转化为文本
    
    • 图片

      图片标签以@开始:{{@var}}

      • 数据模型:
      String :图片url或者本地路径,默认使用图片自身尺寸ByteArrayPictureRenderDataFilePictureRenderDataUrlPictureRenderData
      
    • 表格行循环

      配合插件-LoopRowTableRenderPolicy

    • 图标

      • 多系列图表指的是条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、散点图等

      数据模型ChartMultiSeriesRenderData

      • 单系列图表指的是饼图(3D饼图)、圆环图等。
  • 引入依赖
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.2</version></dependency>
  • 简单的demo
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.ChartMultiSeriesRenderData;
import com.deepoove.poi.data.Charts;
import com.deepoove.poi.data.PictureRenderData;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.deepoove.poi.policy.RenderPolicy;
import org.springframework.stereotype.Service;import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @program: learn_summary* @description:* @author: zzg@xnj* @create: 2025-03-10 15:58**/
@Service
public class WordService {public  void makeWord(){HashMap<String, Object> dates = new HashMap<>();//字符串String wenzi="这个是文字";dates.put("wenzi", wenzi);//单个图片
//        dates.put("pic", Pictures.ofUrl( "https://img.tukuppt.com/ad_preview/00/10/23/5c992ae114e20.jpg!/fw/980").size(200, 200).create());dates.put("pic", "https://img.tukuppt.com/ad_preview/00/10/23/5c992ae114e20.jpg!/fw/980");//多个图片ArrayList<String> urls = new ArrayList<>();urls.add("https://pic.52112.com/2020/04/13/JPG-200413_328/gCaPae4zjp_small.jpg");urls.add("https://img.tukuppt.com/ad_preview/00/10/23/5c992ae114e20.jpg!/fw/980");dates.put("pictures",  createPictureList("picture",urls,200,200));//插件使用HashMap<String, RenderPolicy> policyHashMap = new HashMap<>();//表格 使用LoopRowTableRenderPolicyLoopRowTableRenderPolicy loopRowTableRenderPolicy = new LoopRowTableRenderPolicy();ArrayList<HashMap<String, String>> tables = new ArrayList<>();HashMap<String, String> map = new HashMap<>();map.put("name", "大豆");map.put("count", "18");map.put("price", "100");tables.add(map);map = new HashMap<>();map.put("name", "黄豆");map.put("count", "38");map.put("price", "110");tables.add(map);dates.put("goods",tables);policyHashMap.put("goods", loopRowTableRenderPolicy);//图表ChartMultiSeriesRenderData chart = Charts.ofMultiSeries("商品售卖情况", new String[] { "大豆", "黄豆" }).addSeries("北京", new Double[] { 15.0, 6.0 }).addSeries("上海", new Double[] { 223.0, 119.0 }).create();dates.put("barChart", chart);try {WordService.createWordOfList("E:\\data\\text2.doc",new FileInputStream("E:\\data\\word_template.docx"),dates,policyHashMap);} catch (FileNotFoundException e) {e.printStackTrace();}}private List<Map<String, PictureRenderData>> createPictureList(String mapKey,List<String> urls,int width, int height) {List<Map<String, PictureRenderData>> list = new ArrayList<>();for (String url : urls) {list.add(createPictureMap(mapKey,url, width, height));}return list;}private Map<String, PictureRenderData> createPictureMap(String mapKey,String imgUrl, int width, int height) {Map<String, PictureRenderData> map = new HashMap<>();map.put(mapKey, Pictures.ofUrl( imgUrl).size(width, height).create());return map;}/*** 创建word文档* @param outputPath 输出路径* @param templatePath 模板路径* @param data 数据* @param placeholderPolicy 占位标签使用插件* @return*/public static boolean createWordOfList(String outputPath, InputStream templatePath, Map<String, Object> data, Map<String, RenderPolicy> placeholderPolicy)   {try {FileOutputStream out = new FileOutputStream(outputPath);BufferedOutputStream bos = new BufferedOutputStream(out);// 使用Configure.ConfigureBuilder而不是BuilderConfigureBuilder builder = Configure.builder();// 动态绑定插件if (placeholderPolicy!=null) {for (Map.Entry<String, RenderPolicy> entry : placeholderPolicy.entrySet()) {builder.bind(entry.getKey(), entry.getValue());}}Configure configure = builder.build();// 读取模板并渲染数据XWPFTemplate template = XWPFTemplate.compile(templatePath, configure).render(data);try {template.write(bos);template.close();} catch (Exception e) {e.printStackTrace();return false;}out.flush();bos.flush();} catch (Exception e) {e.printStackTrace();return false;}return true;}}
  • 模板
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34099.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue 过滤器深度解析与应用实践

文章目录 1. 过滤器概述1.1 核心概念1.2 过滤器生命周期 2. 过滤器基础2.1 过滤器定义2.2 过滤器使用 3. 过滤器高级用法3.1 链式调用3.2 参数传递3.3 动态过滤器 4. 过滤器应用场景4.1 文本格式化4.2 数字处理4.3 数据过滤 5. 性能优化与调试5.1 性能优化策略5.2 调试技巧 6. …

ST电机库电流采样 三电阻单ADC

一、概述 下图是三电阻采样的电路结构 其中流过三相系统的电流I1、I2、I3遵循以下关系: 因此,为了重建流过普通三相负载的电流,在我们可以用以上公式计算的情况下,只需要对三相中的两相进行采样即可。 STM32的ADC可以很灵活的配置成同步采集两路ADC数据,…

【测试篇】打破测试认知壁垒,从基础概念起步

前言 &#x1f31f;&#x1f31f;本期讲解关于测试的基本概念相关知识介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话…

SpringBoot MCP 入门使用

随着AI的火爆&#xff0c;最近发现MCP在未来确实大有可为&#xff0c;作为一名javaer怎么可以落后在历史洪流呢&#xff0c;根据官网和cursor也从零开始体验一下自定义mcp server。以后可以根据自己业务场景做出各种适合自身业务的工具。 至于什么是MCP 可以到https://modelcon…

@Autowired和@Resource的区别是?

前情回顾 正确使用Autowired Autowired 注解在构造器上的使用规则&#xff08;字段注入也挺好的&#xff09; 正确使用Resource 来源不同 Autowired的“爹”是Spring Resource的“爹”是Java&#xff08;JSR-250&#xff09; 这是一个规范&#xff0c;Spring对这个注解进行…

3.9/Q2,Charls最新文章解读!

文章题目&#xff1a;Association between remnant cholesterol and depression in middle-aged and older Chinese adults: a population-based cohort study DOI&#xff1a;10.3389/fendo.2025.1456370 中文标题&#xff1a;中国中老年人残留胆固醇与抑郁症的关系&#xff1…

无再暴露源站!群联AI云防护IP隐匿方案+防绕过实战

一、IP隐藏的核心原理 群联AI云防护通过三层架构实现源站IP深度隐藏&#xff1a; 流量入口层&#xff1a;用户访问域名解析至高防CNAME节点&#xff08;如ai-protect.example.com&#xff09;智能调度层&#xff1a;基于AI模型动态分配清洗节点&#xff0c;实时更新节点IP池回…

项目开发 1-确定选题,制作原型

一、AI问答 问&#xff1a; 作为计算机专家&#xff0c;密码学家&#xff0c;给研究生一年级学生设计20个实践项目&#xff0c;具体要求如下&#xff1a; 一. 总体要求 必须使用 Linux 系统调用&#xff0c;要求使用文件I/O,多进程或多线程&#xff0c;一定要用到 Socket 系统…

使用SetupTools 管理你的项目打包工作

Setuptools 是一个用于 Python 的包管理工具&#xff0c;主要用于构建、打包和分发 Python 软件包。它是 distutils 的增强版&#xff0c;提供了更多的功能和灵活性&#xff0c;是 Python 包管理的核心模块之一。 功能与特点 依赖管理&#xff1a;Setuptools 提供了强大的依赖…

人工智能与人的智能,改变一生的思维模型【8】逆向思维

逆向偏差思维模型&#xff1a;顶尖高手如何「反常识」破局 &#xff08;斯坦福决策科学中心认证的逆向思考框架&#xff09; 一、直击本质&#xff1a;什么是逆向偏差思维&#xff1f; 定义&#xff1a; 逆向偏差思维是一种主动对抗本能认知倾向的决策模式&#xff0c;通过系…

YOLO优化之扫描融合模块(SimVSS Block)

研究背景 在自动驾驶技术快速发展的背景下,目标检测作为其核心组成部分面临着严峻挑战。 驾驶场景中目标尺度和大小的巨大差异 ,以及 视觉特征不显著且易受噪声干扰 的问题,对辅助驾驶系统的安全性构成了潜在威胁。 传统的卷积神经网络(CNN)虽然在目标检测领域取得了显著…

(全)2024下半年真题 系统架构设计师 综合知识 答案解析01

系统架构设计师第二版教程VIP课程https://edu.csdn.net/course/detail/40283 操作系统 下列选项中不能作为预防死锁措施的是 。 A. 破坏“循环等待"条件 B. 破坏“不可抢占”条件 C. 破坏“互斥”条件 D. 破坏“请求和保持”条件 答案&#xff1a;C 解析&…

通义万相 2.1 + 蓝耘算力,AI 视频生成的梦幻组合

在这个科技日新月异的时代&#xff0c;人工智能不断刷新着我们对世界的认知。一次偶然的机会&#xff0c;我借助北京蓝耘科技股份有限公司提供的算力支持&#xff0c;踏上了使用通义万相 2.1 进行 AI 视频生成的奇妙之旅。 目录 1.1初遇蓝耘科技&#xff1a; 1.2通义万相 2.1…

链表·简单归并

cur->next la; //将 p指针所指向的链表节点的 next 指针&#xff08;也就是 p 节点的下一个节点的指针&#xff09;指向 l1 所指向的链表节点。简单来说&#xff0c;就是把 la 节点连接到 p 节点的后面&#xff0c;更新了链表的连接关系。 p la; //将p指针的值更新为 la …

kmp报错→Cannot find skiko-windows-x64.dll.sha256

1、前言 学习kmp&#xff08;Kotlin MultiPlatform简称&#xff09;过程中报了错误&#xff0c;这个报错在直接运行desktop的main方法才会出现&#xff0c;用gradle运行却不会报错&#xff0c;新建的kmp项目也不会出现&#xff0c;我学习的写了一些代码的项目才会出现。   运…

MySQL(事物下)

目录 一 多版本并发控制&#xff08; MVCC &#xff09;是一种用来解决 读-写冲突 的无锁并发控制 1. 前置知识 示例&#xff1a; 二 Read View 1. 当事物进行快照读(读历史数据)会MySQL会创建一个Read Vidw类对象&#xff0c;用来记录和当前一起并发的事物(活跃的事物)&a…

星型组网模块的两种交互方式优缺点解析

星型组网模块简介 星型组网模块工作在433MHz频段&#xff1b;星型组网模块集主机&#xff08;协调器&#xff09;、终端为一体&#xff0c;星型组网模块具有长距离、高速率两种传输模式&#xff0c;一个主机&#xff08;协调器&#xff09;支持多达200个节点与其通讯&#xff0…

IMX6ULL学习整理篇——UBoot的一些基础知识(1.编译流程)

前言 笔者整理了最近刷IMX6ULL的一些学习笔记&#xff0c;这里打算稍微整理一下东西发上来作为作为一个补充 正文 大部分而言&#xff0c;当我们拿到源码的时候&#xff0c;一般都是——先使用make来生成一份针对我们目标开发板的配置。举个例子&#xff0c;正点原子针对他们…

docker桌面版启动redis,解决无法连接

docker run -d --name redis -p 6379:6379 -v E:\2\redis\redis.conf:/usr/local/etc/redis/redis.conf redis redis-server /usr/local/etc/redis/redis.conf 在本地创建一个目录&#xff0c;里面有个redis.conf文件&#xff0c;内容如下&#xff0c;启动时绑定这个配置文件目…

2025-03-15 学习记录--C/C++-PTA 习题3-3 出租车计价

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 习题3-3 出租车计价 本题要求根据某城市普通出租车收费标准编写程序进行车费计算。具体标准如下&#xff1…