apache poi_5.2.5 实现对表格单元格的自定义变量名进行图片替换
apache poi_5.2.5 实现对表格单元格的自定义变量名进行图片替换
实现思路
1.首先定位到自定义变量名
2.然后先清除自定义变量名,可利用setText(null,0)来清除
3.在自定义变量名的位置添加图片,使用下面的代码
4.对于图片布局有要求的,利用CTAnchor进行实现
addNewWrapNone;//根据setBehindDoc,来确定浮于文字上方还是下方
addNewWrapSquare;//四周型布局
【注:默认是嵌入型,文字会遮挡部分图片。】
依赖包
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.5</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.5</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>5.2.5</version></dependency>
代码实现
public static void main(String[] args) throws Exception {String wenshuUrl = "D:\\demo1.docx";File file = new File(wenshuUrl);byte[] bytes = Files.readAllBytes(Paths.get(file.toURI()));ByteArrayInputStream in = new ByteArrayInputStream(bytes);XWPFDocument doc = new XWPFDocument(in);String pic = "D:\\demo1.png";File file2 = new File(pic);byte[] bytes2 = Files.readAllBytes(Paths.get(file2.toURI()));ByteArrayInputStream bis2 = new ByteArrayInputStream(bytes2);for (int i = 0; i < doc.getTables().size(); i++) {for (int rowIndex = 0; rowIndex < doc.getTables().get(i).getRows().size(); rowIndex++) {XWPFTableRow row = doc.getTables().get(i).getRow(rowIndex);row.getTableCells().stream().forEach(cell -> {for (XWPFParagraph paragraph : cell.getParagraphs()) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {try {addPicture(run, bis2,pic,500,400);} catch (InvalidFormatException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (SAXException e) {throw new RuntimeException(e);} catch (XmlException e) {throw new RuntimeException(e);}}}});}}OutputStream output = new FileOutputStream("D:\\afteradd1.doc");doc.write(output);output.close();}/*** 添加图片(布局环绕模式)* @param run* @param stream 图片流* @param filename 文件路径* @param width 图片的宽度* @param height 图片的高度*/private static void addPicture(XWPFRun run, InputStream stream, String filename, int width, int height ) throws InvalidFormatException, IOException, SAXException, XmlException {run.addPicture(stream, getPictureTypeByFileName(filename), filename, Units.toEMU(width), Units.toEMU(height));CTDrawing drawing = run.getCTR().getDrawingArray(0);CTGraphicalObject graphicalObject = drawing.getInlineArray(0).getGraphic();//这个是relationId,即图片位置的idlong id = drawing.getInlineArray(0).getDocPr().getId();//设置一个浮动模式CTAnchor anchor = drawing.addNewAnchor();//创建一个包含浮动模式的xml字符串String xml = "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\"><a:graphicData uri=\"" + CTPicture.type.getName().getNamespaceURI() + "\"><pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" /></a:graphicData></a:graphic>";//将xml字符串转换为InputSource对象InputSource is = new InputSource(new StringReader(xml));//生成Document对象,用于将Document doc = DocumentHelper.readDocument(is);anchor.set(XmlToken.Factory.parse(doc.getDocumentElement(),DEFAULT_XML_OPTIONS));//设置浮动位置,0表示紧贴文字anchor.setDistT(0L);anchor.setDistR(0L);anchor.setDistB(0L);anchor.setDistL(0L);anchor.setLocked(false);anchor.setLayoutInCell(true);anchor.setSimplePos2(false);anchor.setAllowOverlap(true);anchor.setRelativeHeight(0);//图片的布局环绕模式anchor.addNewWrapSquare();CTPosH ctPosH = anchor.addNewPositionH();//STRelFromH 水平方向的位置相对于谁进行调整 character:文字ctPosH.setRelativeFrom(STRelFromH.CHARACTER);//调整水平方向的位置,从左往右递增,0代表紧贴文字ctPosH.setPosOffset( Units.toEMU(0));CTPosV ctPosV = anchor.addNewPositionV();//STRelFromV 垂直方向的位置相对于谁进行调整 PARAGRAPH:字段ctPosV.setRelativeFrom(STRelFromV.PARAGRAPH);//调整垂直方向的位置,从上往下数值递增ctPosV.setPosOffset( Units.toEMU(-10));CTPoint2D ctPoint2D = anchor.addNewSimplePos();ctPoint2D.setX(0);ctPoint2D.setY(0);anchor.addNewCNvGraphicFramePr();CTNonVisualDrawingProps docPr = anchor.addNewDocPr();docPr.setId(id);docPr.setName("Drawing " + id);docPr.setDescr(filename);CTPositiveSize2D extent = anchor.addNewExtent();extent.setCx(Units.toEMU(width));extent.setCy(Units.toEMU(height));anchor.setGraphic(graphicalObject);//添加浮动属性drawing.setAnchorArray(new CTAnchor[]{anchor});//删除行内属性drawing.removeInline(0);}public static int getPictureTypeByFileName(String fileName) {if (StringUtils.isEmpty(fileName)) {throw new RuntimeException("文件名称不能为空!");}String suffix = fileName.substring(fileName.lastIndexOf("."));switch (suffix) {case ".jpg":case ".jpeg":return XWPFDocument.PICTURE_TYPE_JPEG;case ".wmf":return XWPFDocument.PICTURE_TYPE_WMF;case ".png":case ".PNG":return XWPFDocument.PICTURE_TYPE_PNG;case ".gif":return XWPFDocument.PICTURE_TYPE_GIF;case ".tiff":return XWPFDocument.PICTURE_TYPE_TIFF;case ".bmp":return XWPFDocument.PICTURE_TYPE_BMP;default:throw new RuntimeException("不支持的文件类型:" + suffix);}}
相关文章:
apache poi_5.2.5 实现对表格单元格的自定义变量名进行图片替换
apache poi_5.2.5 实现对表格单元格的自定义变量名进行图片替换 实现思路 1.首先定位到自定义变量名 2.然后先清除自定义变量名,可利用setText(null,0)来清除 3.在自定义变量名的位置添加图片,使用下面的代码 4.对于图片布局有要求的,利用C…...

Kafka--Kafka日志索引详解以及生产常见问题分析与总结
一、Kafka的Log日志梳理 这一部分数据主要包含当前Broker节点的消息数据(在Kafka中称为Log日志)。这是一部分无状态的数据,也就是说每个Kafka的Broker节点都是以相同的逻辑运行。这种无状态的服务设计让Kafka集群能够比较容易的进行水平扩展。比如你需要用一个新…...

Vue3-23-组件-依赖注入的使用详解
什么是依赖注入 个人的理解 : 依赖注入,是在 一颗 组件树中,由 【前代组件】 给 【后代组件】 提供 属性值的 一种方式 ;这种方式 突破了 【父子组件】之间通过 props 的方式传值的限制,只要是 【前代组件】提供的 依…...

css 美化滚动条
当div内容溢出容器定义的高度时,滚动条显示,并美化默认的滚动条样式 div 容器 <divclass"content">内容 </div>css 样式 /* 问话区域 滚动条 */ .content {overflow: auto;height: 662px;padding: 25px;scrollbar-width: thin; /* 设置滚动条宽度 */bo…...
Tomcat介绍及使用:构建强大的Java Web应用服务器
引言: 在现代软件开发中,Web应用已经成为了不可或缺的一部分。而为了构建高效、稳定的Web应用服务器,选择合适的工具和技术至关重要。Tomcat作为一款开源的Java Web应用服务器,凭借其丰富的功能和灵活的配置,成为了开发…...

怎么定义一套完成标准的JAVA枚举类型
一、背景 在java代码中,接口返回有各种各样的状态,比如400 401 200 500 403等常见的http状态码,也有我们自定义的很多业务状态码。如果系统比较复杂,制定一套完整的标准的状态码是非常有必要的,这样比较方面BUG排查。…...

Apache Seatunnel本地源码构建编译运行调试
Apache Seatunnel本地源码构建编译运行调试 文章目录 1. 环境准备1.1 Java环境1.2 Maven1.3 IDEA1.4 Docker环境1.5 Mysql8.0.281.6 其它环境准备 2. 源码包下载3. idea项目配置3.1 项目导入3.2 maven配置3.3 项目JDK配置3.4 项目启动参数配置3.4.1 seatunnel项目启动参数配置3…...

构建高效持久层:深度解析 MyBatis-Plus(02)
目录 引言1. 逻辑删除1.1 概述1.2 逻辑删除的优势1.3.为什么使用逻辑删除1.4 综合案例 2. 乐观锁和悲观锁2.1.什么是乐观锁和悲观锁2.2.乐观锁和悲观锁的区别2.3.综合案例 3. 分页插件总结 引言 在现代软件开发中,数据库操作是不可或缺的一环。为了提高系统的性能、…...

Gitlab仓库推送到Gitee仓库的一种思路
文章目录 Gitlab仓库推送到Gitee仓库的一种思路1、创建Gitee的ssh公钥(默认已有Gitlab的ssh公钥)2、添加Gitlab远程仓库地址3、添加Gitee远程仓库地址4、拉取Gitlab远程仓库指定分支到本地仓库指定分支(以test分支为例)5、推送本地…...

快速能访问服务器的文件
1、背景 访问ubuntu上的文件 2、方法 python3 -m http.server 8081 --directory /home/ NAS 共享访问协议 — NFS、SMB、FTP、WebDAV 各有何优势?http://1 Ubuntu 搭建文件服务器(Nginx)...

Diary26-Vue综合案例1-书籍购物车
Vue综合案例1-书籍购物车 案例要求: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewpor…...

【EasyExcel实践】万能导出,一个接口导出多张表以及任意字段(可指定字段顺序)-简化升级版
文章目录 前言正文一、项目简介二、核心代码2.1 pom.xml 依赖配置2.2 ExcelHeadMapFactory2.3 ExcelDataLinkedHashMap2.4 自定义注解 ExcelExportBean2.5 自定义注解 ExcelColumnTitle2.6 建造器接口 Builder2.7 表格工具类 ExcelUtils2.8 GsonUtil2.9 模版类 ExportDynamicCo…...

解决 Hive 外部表分隔符问题的实用指南
简介: 在使用 Hive 外部表时,分隔符设置不当可能导致数据导入和查询过程中的问题。本文将详细介绍如何解决在 Hive 外部表中正确设置分隔符的步骤。 问题描述: 在使用Hive外部表时,可能会遇到分隔符问题。这主要是因为Hive在读…...
一文学会 Apache Zeppelin
Zeppelin资料 Zeppelin项目信息 Zeppelin官网 http://zeppelin.apache.org/Zeppelin源码地址 https://github.com/apache/zeppelinZeppelin JIRA: https://issues.apache.org/jira/projects/ZEPPELIN/summaryZeppelin文档 Flink on Zeppelin 文档集中地 https://www.yuque.co…...

ROS学习笔记(七)---参数服务器
ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序(简例) 03. ROS学习笔记(三)—好用的终端Terminator 04. ROS学习笔记(四)—使用 VScode 启动launch文件运行多个节点 05. ROS学习笔…...

【RTOS学习】源码分析(信号量和互斥量 事件组 任务通知)
🐱作者:一只大喵咪1201 🐱专栏:《RTOS学习》 🔥格言:你只管努力,剩下的交给时间! 目录 🍓信号量和互斥量🍅创建🍅Take🍅Give &#x…...
1316:【例4.6】数的计数(Noip2001) 代码+解析
1316:【例4.6】数的计数(Noip2001) 【题目描述】 我们要求找出具有下列性质数的个数(包括输入的自然数n )。先输入一个自然数n(n≤1000),然后对此自然数按照如下方法进行处理:不作任何处理;在它的左边加上一…...

征集倒计时 | 2023年卓越影响力榜单-第四届中国产业创新奖报名即将截止
第四届「ISIG中国产业智能大会」将于2024年3月16日在上海举办。2024 ISIG 以“与科技共赢,与产业共进”为主题,共设立RPA超自动化、 低代码、AIGC大模型、流程挖掘四大主题峰会。届时,大会组委会将颁发2023年度卓越影响力榜单—第四届中国产业…...

vue的语法模板与数据绑定的说明
vue的两大模板语法: 1.插值语法 2.指定语法 插值语法:{{}} 功能:用于解析标签体的内容 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性 指定语法: 功能:用于解析标签(包括:标签属性、标…...

VueCron使用方法
1)什么是vueCron Vue Cron 是基于 Vue.js 的定时任务管理组件,它提供了一种简单易用的方式来设定和管理定时任务。Vue Cron 提供了一个类似于 Linux crontab 的界面,用户可以通过它来创建、编辑和删除定时任务。 2)安装依赖及应…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...