使用POI在图片之后插入文字

首先要知道docx文件是zip形式保存的,文档内容会保存为xml格式。我们将一个docx文件后缀改为zip并打开,会发现里面又很多文件夹以及xml文件。

内容存在word文件夹下的document.xml文件中,charts文件夹保存图表,embeddings中的xlsx文件是图表的信息,图片则保存在media中。

使用浏览器打开document.xml文件,里面就是我们在文档中输入的内容。

<w:p>:段落,Paragraph
<w:pPr>:段落样式
<w:r>:文本,Run
<w:rPr>:文本样式
<w:t>:文本内容
<w:hdr>:页眉
<w:ftr>:页脚
<w:pict>:图片
<w:drawing>:

 进入正题,采用的主要想法是根据图片和文字的标签进行定位,然后
File file = new File(filePath);
in = new FileInputStream(file);
XWPFDocument doc = new XWPFDocument(in);//获取段落
List<XWPFParagraph> paraList = doc.getParagraphs();
//run.getEmbeddedPictures()方法只能获取嵌入式的图片
//doc.getAllPictures()获取全部图片
List<XWPFPictureData> pictures = doc.getAllPictures();
//将图片的byte放到map中,方便后面获取
Map<String, byte[]> picDataMap = new HashMap<>();
for (XWPFPictureData pic : pictures) {//relationId就是图片引用的ridString rid = pic.getParent().getRelationId(pic);picDataMap.put(rid, pic.getData());
}
for (XWPFParagraph para : paraList){//run是一段文本对象,一个段落(XWPFPaaragraph)的run会根据图片进行分割List<XWPFRun> runList = para.getRuns();for (int i = 0; i < runList.size(); i++) {//保存当前run需要插入的值和插入位置,在判断结束后统一插入Map<Integer, String> insertMap = new HashMap<>();//当前run没有文字时,需要插入的值:String insertValue = "";XWPFRun run = runList.get(i);//POI对word的处理:将word以xml格式读取后进行封装//getCTR方法获取xml信息String runXmlText = run.getCTR().xmlText();//判断当前文本对象<w:pict>为引用图片,<w:drawing>为嵌入图片:嵌入图片也可以通过run.getEmbeddedPictures()获取if (runXmlText.indexOf("<w:pict>") != -1) {//该方法利用indexOf获取当前文本包含图片的位置,如果为嵌入图片应使用r:embed获取位置。List<Integer> indexList = getRIdIndex(0, runXmlText, "r:id");List<Integer> wtIndexList = getWtIndex(0, runXmlText, "<w:t");for (int j = 0; j < indexList.size(); j++){//通过切割获取当前位置图片的ridint rIdIndex = indexList.get(j);int rIdEndIndex = runXmlText.indexOf("/>", rIdIndex);String rIdText = runXmlText.substring(rIdIndex, rIdEndIndex);String id = rIdText.split("\"")[1];//通过获取到的rid读取图片信息byte[] bytes = picDataMap.get(id);//当前图片流,可以对图片进行处理InputStream picIn = new ByteArrayInputStream(bytes);//value为要插入的文字String value = "要插入的值";if (!CommonUtil.checkNull(value)){//用于判断图片后面是否还有文本boolean hasEndWt = false;for (int k = 0; k < wtIndexList.size(); k++) {int wtIndex = wtIndexList.get(k);//当wt在pic之后进行插入if (wtIndex > rIdIndex) {//run.setText(value, pos);pos数量就是当前run中<w:t></w:t>的数量//防止多图问题,先把值和位置放到map中。在当前run中所有图片值确定之后在进行插入。if (!CommonUtil.checkNull(insertMap.get(k))){insertMap.put(k, insertMap.get(k) + value);} else{insertMap.put(k, value);}hasEndWt = true;break;}}//如果图片后没有文本if (!hasEndWt) {//防止多图问题,先把值和位置放到map中。在当前run中所有图片值确定之后在进行插入。insertValue += value;//通过测试来看可以不做下列判断,直接在当前run插入文本,但不确定文本是否都在图片后面。}}}}//在当前run进行插入if (!CommonUtil.checkNullOrEmpty(insertMap)){for (Map.Entry<Integer, String> entry : insertMap.entrySet()){int key = entry.getKey();String value = entry.getValue();run.setText(value + run.getText(key), key);}}if (!"".equals(insertValue)) {XWPFRun newRun = para.createRun();newRun.setText(insertValue);}}
}
out = new FileOutputStream(filePath);
doc.write(out);

————————————————
版权声明:本文为CSDN博主「学习要趁早z」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42677452/article/details/116267235

利用word的xml格式,使用POI在图片位置插入文字相关推荐

  1. poi在指定位置插入图片,图片可以浮动内容上方下方

    在使用poi操作docx模板文件时,总会出现需要插入类似印章签名的图片.poi直接插入图片是插入内嵌图片 这个图片是占位置的. 会撑高当前的那一行类似效果 行使得制作出来的word样式辣眼睛. 一般印 ...

  2. word文档的生成以及echarts图片的插入

    word文档的生成以及echarts图片的插入 word文档的生成 pom.xml引入 代码流程-easy result 结语 word文档的生成 上一篇博客我们提到了echarts图片的生成过程!现 ...

  3. Walkthrough: Word 2007 XML 格式

    本页内容 简介 Word 2007 文档包 Word XML格式的开放打包约定 解析Word 2007文件 确定Word 2007文档中的非XML部件 从文档中分离内容 理解数据存储 结论 简介 Mi ...

  4. POI操作Word中的表格XWPFTable,在指定位置插入行

    最近由于客户使用Word文档展示表格中的数据,我TM...Excel它不香嘛,为什么要用Word去展示表格呢??? 但是呢.客户就是上帝,上帝让我们干嘛我们就要干嘛. 1:有这样一个需求,在已有的Wo ...

  5. c语言数组指定位置插入和删除_Apache POI在指定位置插入表格

    接到的需求是在模板表格的指定位置再插入表格.比如在模板的${proTable}处插入表格. 依赖的包 org.apache.poi poi 3.15org.apache.poi poi-ooxml 3 ...

  6. c# 在 word指定位置插入文字和图片(替换 书签)

    使用  Microsoft.Office.Interop.Word  进行插入, word 文件中 插入 "书签" . 在com组件中引用  Microsoft.Word.xxx. ...

  7. OpenXML之word的XML格式分析

    一. <?xmlversion="1.0" encoding="UTF-8"standalone="yes"?> 这是XML文档 ...

  8. 利用iTextSharp组件给PDF文档添加图片水印,文字水印

    最近在做关于PDF文档添加水印的功能,折腾了好久,终于好了.以下做个记录: 首先会用到iTextSharp组件,大家可以去官网下载,同时我也会在本文中附加进来. 代码中添加引用为:   usingSy ...

  9. java 导出word xml格式_关于Java导出Word文件

    做个很多个项目里基本上都涉及了word.Excel导入导出,虽然其中的要求有些小差异,不过总的方向上变化不大,所以做一些总结: 一).利用freemarker,制作xml模版导出word Xml模版部 ...

最新文章

  1. 亚洲杯:打平韩国即可小组第一 国足会继续带来惊喜吗?
  2. 记录SpringBoot集成Shiro使用Redis作缓存遇到的一个问题(Key-Value)互换
  3. Nifi出现Failed to send StandardFlowFileRecord xxxx to Hbase due to Failed 3 actions解决
  4. 计算机网络安全管理协议,河西学院校园网络安全管理协议
  5. linux server.xml日志参数,Linux Log4j+Kafka+KafkaLog4jAppender 日志收集
  6. Qt文档阅读笔记-Q_GADGET官方解析及实例
  7. 【RUST官方语言中文翻译】前言
  8. ASP.NET网站发布-允许更新此预编译站点
  9. java如何关闭线程池_如何优雅的关闭Java线程池
  10. MFC消息映射机制概述
  11. Android Studio for Experts(Android Dev Summit2015)
  12. 问题四十五:怎么画ray tracing图形中的blending and joining surface
  13. vue基础(三)——vue实例化对象
  14. 基于加速度计的倾角检测算法-C语言程序
  15. JDK下载、安装和环境配置
  16. 诺贝尔奖你知道多少呢?
  17. java的environment_Java - 环境设置(Environment Setup)
  18. COSCon'22 论坛集锦 1+16个论坛就等你了!
  19. HDU3666_差分约束
  20. Uniform Buffer

热门文章

  1. 2021-10-17 每天几个LCEDA小知识——滚轮缩放技巧
  2. 计算支付宝借呗的年化收益
  3. java架构师什么学校好_Java架构师之路:年薪八十万的架构师课程
  4. 【PC】关掉Chrome浏览器“由贵单位管理”
  5. NLP之PLUG:阿里达摩院发布最大中文预训练语言模型PLUG的简介、架构组成、模型训练、使用方法之详细攻略
  6. 总结:UTC与GMT
  7. 四面阿里斩获offer定级P7,2021最新最全阿里巴巴68道高级面试题
  8. 荣耀智慧屏观影体验:视听俱佳震撼享受
  9. 趣信同城开启线上服务模式
  10. js之ajax与cors