Java使用apache.poi生成word

加油,打工人!

工作需求,将现有的word模板有段落和表格,从数据库中查出数据并填充,word里面也有表格数据,需要将excel表格数据单独处理,然后插入到生成好的word文档中。
下面代码模拟从数据库查出来数据,生成word。
此代码,版本4.X,5.X都可以使用。
封面
在这里插入图片描述
在这里插入图片描述

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency>
package com.wh.filedownload.controller;import org.apache.poi.xwpf.usermodel.*;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/**
*@author wh
*@date 2024年05月24日8:59
*/
public class ReaderWord{static class User {String name;String email;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public User(String name, String email) {this.name = name;this.email = email;}}public static void generateWordFromTemplate(String templatePath, String outputPath, List<User> users) throws IOException {FileInputStream fis = new FileInputStream(templatePath);XWPFDocument doc = new XWPFDocument(fis);int userIndex = 0; // 用来追踪当前处理的用户索引for (XWPFParagraph p : doc.getParagraphs()) {for (XWPFRun r : p.getRuns()) {String text = r.getText(0);if (text != null) {text = replaceUserData(text, users.get(userIndex));r.setText(text, 0);}}// 处理完一个段落后检查是否需要开始下一个用户的数据填充if (shouldMoveToNextUser(p)) {userIndex++;if (userIndex >= users.size()) break; // 防止数组越界}}// 处理表格for (XWPFTable table : doc.getTables()) {for (XWPFTableRow row : table.getRows()) {for (XWPFTableCell cell : row.getTableCells()) {for (XWPFParagraph para : cell.getParagraphs()) {for (XWPFRun run : para.getRuns()) {String text = run.getText(0);if (text != null) {text = replaceUserData(text, users.get(userIndex));run.setText(text, 0);}}}}}// 同样,处理完一个表格后可能需要切换到下一个用户的数据userIndex++;if (userIndex >= users.size()) break; // 防止数组越界}FileOutputStream out = new FileOutputStream(outputPath);doc.write(out);out.close();doc.close();fis.close();}// 简化的替换逻辑,实际应用可能需要更复杂的正则表达式匹配private static String replaceUserData(String text, User user) {return text.replace("{{name}}", user.name).replace("{{email}}", user.email);}// 假设某些特定的段落标记(如特殊文本或样式)意味着应该开始下一个用户的数据显示private static boolean shouldMoveToNextUser(XWPFParagraph paragraph) {// 这里可以根据实际情况定义何时跳到下一个用户的数据// 例如,检查段落是否包含特定标记文本return paragraph.getText().contains("<!--NEXT_USER-->");}private static void replaceText(XWPFDocument doc, String oldText, String newText) {for (XWPFParagraph p : doc.getParagraphs()) {for (XWPFRun r : p.getRuns()) {String text = r.getText(0);if (text != null && text.contains(oldText)) {text = text.replace(oldText, newText);r.setText(text, 0);}}}}public static List<User> getUsersFromDatabase() {List<User> users = new ArrayList<>();User user = new User("小米", "");users.add(user);return users;}public static void main(String[] args) {List<User> users = getUsersFromDatabase();try {generateWordFromTemplate("template.docx", "output.docx", users);System.out.println("Word文档生成成功!");} catch (IOException e) {e.printStackTrace();}}
}

运行结果
在这里插入图片描述
在这里插入图片描述
这样就可了,如果字段没有数据,自动不显示,不用去掉空标签了。

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

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

相关文章

Kubernetes——Kubectl详解

目录 前言 一、陈述式资源管理方法 二、Kubectl命令操作 1.查 1.1kubectl version——查看版本信息 1.2kubectl api-resources——查看资源对象简写 1.3kubectl cluster-info——查看集群信息 1.4配置Kubectl补全 1.5journalctl -u kubelet -f——查看日志 1.6kubec…

物联网应用开发--STM32与机智云通信(ESP8266 Wi-Fi+手机APP+LED+蜂鸣器+SHT20温湿度传感器)

实现目标 1、熟悉机智云平台&#xff0c;会下载APP 2、熟悉新云平台创建产品&#xff0c;项目虚拟调试 3、掌握云平台生成MCU代码&#xff0c;并移植。机智云透传固件的下载 4、具体目标&#xff1a;&#xff08;1&#xff09;注册机智云平台&#xff1b;&#xff08;2&…

148.【Windows DOS命令脚本文件】

Window待处理脚本 (一)、批处理编程初步体验1.什么是批处理程序&#xff1f;(1).批处理程序的定义(2).如何编辑批处理程序 2.批处理程序可以做什么&#xff1f;(1).匹配规则删除文件(2).新建文件&#xff0c;日志等(3).创建计算机病毒等 3.一个基本的批处理文件(1).带盘符的输出…

[深入理解DDR5] 2-1 封装与引脚

3500字&#xff0c;依公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《深入理解DDR》 1 DDR5 颗粒 X4 X8 X16 这里的 X8 or X16&#xff0c; 可以理解为一个DRAM芯片有几个存储阵列。“X几”。进行列寻址时会同时从几个阵列的同一个坐标位置读出数据bit来&a…

前端中 dayjs 时间的插件使用(在vue 项目中)

Day.js中文网 这是dayjs的中文文档 里面包括了使用方法 下面我来详细介绍一下这个插件的使用 Day.js 可以运行在浏览器和 Node.js 中。 一般咱直接是 npm 安装 npm install dayjs 目前应该使用的是Es6 的语法 import dayjs from dayjs 当前时间 直接调用 dayjs() 将返回…

如何优雅的卸载linux上的todesk

要优雅地卸载Linux上的ToDesk&#xff0c;您可以按照以下步骤操作&#xff1a; 打开终端。 输入以下命令来停止ToDesk服务&#xff08;如果它正在运行的话&#xff09;&#xff1a; sudo systemctl stop todesk 然后&#xff0c;使用包管理器卸载ToDesk。如果您使用的是apt&…

【飞桨AI实战】基于PP-OCR和ErnieBot的智能视频问答

前言 本次分享将带领大家从 0 到 1 完成一个基于 OCR 和 LLM 的视频字幕提取和智能视频问答项目&#xff0c;通过 OCR 实现视频字幕提取&#xff0c;采用 ErnieBot 完成对视频字幕内容的理解&#xff0c;并回答相关问题&#xff0c;最后采用 Gradio 搭建应用。本项目旨在帮助初…

小猫咪的奇幻冒险:一个简单的Python小游戏

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、游戏简介与演示 二、游戏开发与运行 1. 环境搭建 2. 代码解析 3. 加速机制 三、游戏…

GitHub的原理及应用详解(一)

本系列文章简介&#xff1a; GitHub是一个基于Git版本控制系统的代码托管平台&#xff0c;为开发者提供了一个方便的协作和版本管理的工具。它广泛应用于软件开发项目中&#xff0c;包括但不限于代码托管、协作开发、版本控制、错误追踪、持续集成等方面。 GitHub的原理可以简单…

【LinuxC语言】目录操作

文章目录 前言常用目录操作函数1. `opendir`2. `readdir`3. `closedir`4. `mkdir`5. `rmdir`6. `chdir`7. `getcwd`8. `scandir`9. `rename`总结前言 在Linux系统中,目录操作是文件系统管理的重要组成部分。对于使用C

Java中的集合框架(Collections Framework)深入解析

在Java编程中&#xff0c;集合框架&#xff08;Collections Framework&#xff09;是一个重要的组成部分&#xff0c;它为程序员提供了一套丰富的接口和类&#xff0c;用于存储、检索和操作对象集合。下面&#xff0c;我将从技术难点、面试官关注点、回答吸引力和代码举例四个方…

Jeecg | 完成配置后,如何启动整个项目?

前端启动步骤&#xff1a; 1. 以管理员身份打开控制台&#xff0c;切换到前端项目目录。 2. 输入 pnpm install 3. 输入 pnpm dev 4. 等待前端成功运行。 可以看到此时前端已经成功启动。 后端启动步骤&#xff1a; 1. 启动 mysql 服务器。 管理员身份打开控制台&#…

得物小程序逆向+qt可视化(不含sku)

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

Python实现国密GmSSL

Python实现国密GmSSL 前言开始首先安装生成公钥与私钥从用户证书中读取公钥读取公钥生成签名验证签名加密解密 遇到的大坑参考文献 前言 首先我是找得到的gmssl库&#xff0c;经过实操&#xff0c;发现公钥与密钥不能通过pem文件得到&#xff0c;就是缺少导入pem文件的api。这…

迷你手持小风扇到底哪个牌子最好?揭秘迷你手持手持小风扇排行榜

在炎炎夏日&#xff0c;迷你手持小风扇成为了我们不可或缺的清凉伴侣。然而&#xff0c;面对市场上琳琅满目的品牌&#xff0c;迷你手持小风扇到底哪个牌子最好&#xff1f;今天&#xff0c;我将揭秘迷你手持小风扇排行榜&#xff0c;带大家一探各大品牌的魅力&#xff0c;让你…

Linux-用户管理

Linux的用户 用户是必须的吗 用户&#xff1a;标识计算机上的资源的归属 保存账号或密码的数据库文件 /etc/passwd&#xff1a;保存系统中的全部用户名 /etc/group&#xff1a;保存系统中的全部用户组名 /etc/shadow&#xff1a;保存系统中的各个用户的密码 /etc/gshadow&am…

字节面试:百亿级数据存储,怎么设计?只是分库分表吗?

尼恩&#xff1a;百亿级数据存储架构起源 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;经常性的指导小伙伴们改造简历。 经过尼恩的改造之后&#xff0c;很多小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试机会&#xff0c…

【LeetCode】【5】最长回文子串

文章目录 [toc]题目描述样例输入输出与解释样例1样例2 提示Python实现动态规划 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给一个字符串s&#xff0c;找到s中最长的回文子串 样例输入输出与解释 样例1 输入…

数据结构时间复杂度是什么

时间复杂度&#xff08;Time Complexity&#xff09;是一个算法在输入规模变化时运行时间增长情况的度量方式。它通常用大 (O) 记号&#xff08;Big-O notation&#xff09;表示&#xff0c;描述的是最坏情况下算法运行时间的上限。时间复杂度帮助我们理解算法在处理不同规模的…

AI赋能C++:结构体

C中的结构体&#xff08;struct&#xff09;是一种复合数据类型&#xff0c;允许你组合不同类型的数据项&#xff08;成员变量&#xff09;到一个单一的单元中。结构体在概念上类似于类&#xff0c;但默认情况下&#xff0c;结构体的所有成员都是公有的&#xff08;public&…