解决 poi3.8版本在word中插入图片不展示的问题

解决 poi3.8版本在word中插入图片不展示的问题

  • 1. 前言
  • 2. 问题描述
  • 3. 解决问题
    • 3.1 方案1——自定义XWPFDocument
      • 3.1.1 解决代码
      • 3.1.2 参考
    • 3.2 方案2——使用开源框架xdocreport
  • 4. 其他

1. 前言

  • 本次使用的是poi3.8版本,引入的依赖如下:

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.8</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.8</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-scratchpad</artifactId>
      <version>3.8</version>
    </dependency>
    
  • word里插入图片的代码如下:

    package org.example.example1.poi38;
    
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.util.Units;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * @Description
     * @Author susu
     * @Date 2024/3/8
     */
    public class TestWordImage2NotDealBug {
        public static void main(String[] args) throws IOException {
            // 读取本地的一个现有的Word文档,并创建对应的文档对象
            String fileInPath = "/Users/susu/file_test/poi3.8-test/test_word_in_1.docx";
            String imagePath = "/Users/susu/file_test/poi3.8-test/susu.jpg"; // 图片文件路径
            String fileOutPath = "/Users/susu/file_test/poi3.8-test/test_word_out_1.docx";
    
            FileInputStream fileInputStream = new FileInputStream(fileInPath);
            XWPFDocument document = new XWPFDocument(fileInputStream);
    
            try {
                XWPFParagraph imageParagraph = document.createParagraph();
                XWPFRun imageRun = imageParagraph.createRun();
    
                FileInputStream imageStream = new FileInputStream(imagePath);
    //            imageRun.addPicture(imageStream,XWPFDocument.PICTURE_TYPE_PNG,"susu.png,", Units.toEMU(100), Units.toEMU(100));
                imageRun.addPicture(imageStream,XWPFDocument.PICTURE_TYPE_JPEG,"susu.jpg,", Units.toEMU(100), Units.toEMU(100));
    
                FileOutputStream fos = new FileOutputStream(fileOutPath);
                document.write(fos);
                fos.close();
            } catch (InvalidFormatException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    

2. 问题描述

  • Java使用poi3.8版本在word中插入图片不展示,使用XWPFDocument类的方法addPictureData()插入图片时虽然不报异常,word也能打开生成的文件,但图片却无法显示出来,如果将word文件用解压缩文件打开,也能看到里面包含的图片文件,但在word中无法正常显示。(图片插入成功,有占位就是不展示),效果如下:
    在这里插入图片描述

3. 解决问题

3.1 方案1——自定义XWPFDocument

3.1.1 解决代码

  • 自定义的 XWPFDocument.java代码如下:
    package org.example.example1.poi38;
    
    
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.xmlbeans.XmlException;
    import org.apache.xmlbeans.XmlToken;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
    import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @Description 解决 poi3.8 图片bug问题
     * @Author susu
     * @Date 2024/3/8
     */
    public class MyXWPFDocument extends XWPFDocument {
        public MyXWPFDocument() {
            super();
        }
    
        public MyXWPFDocument(OPCPackage opcPackage) throws IOException {
            super(opcPackage);
        }
    
        public MyXWPFDocument(InputStream in) throws IOException {
            super(in);
        }
    
        public void createPicture(String blipId,int id, int width, int height) {
            final int EMU = 9525;
            width *= EMU;
            height *= EMU;
    
            CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();
    
            String picXml = "" +
                    "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                    "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                    "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                    "         <pic:nvPicPr>" +
                    "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                    "            <pic:cNvPicPr/>" +
                    "         </pic:nvPicPr>" +
                    "         <pic:blipFill>" +
                    "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                    "            <a:stretch>" +
                    "               <a:fillRect/>" +
                    "            </a:stretch>" +
                    "         </pic:blipFill>" +
                    "         <pic:spPr>" +
                    "            <a:xfrm>" +
                    "               <a:off x=\"0\" y=\"0\"/>" +
                    "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                    "            </a:xfrm>" +
                    "            <a:prstGeom prst=\"rect\">" +
                    "               <a:avLst/>" +
                    "            </a:prstGeom>" +
                    "         </pic:spPr>" +
                    "      </pic:pic>" +
                    "   </a:graphicData>" +
                    "</a:graphic>";
    
            //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
            XmlToken xmlToken = null;
            try {
                xmlToken = XmlToken.Factory.parse(picXml);
            } catch(XmlException xe) {
                xe.printStackTrace();
            }
            inline.set(xmlToken);
            //graphicData.set(xmlToken);
    
            inline.setDistT(0);
            inline.setDistB(0);
            inline.setDistL(0);
            inline.setDistR(0);
    
            CTPositiveSize2D extent = inline.addNewExtent();
            extent.setCx(width);
            extent.setCy(height);
    
            CTNonVisualDrawingProps docPr = inline.addNewDocPr();
            docPr.setId(id);
            docPr.setName("Picture " + id);
            docPr.setDescr("Generated");
        }
    
    }
    
    
  • 测试代码如下:
    package org.example.example1.poi38;
    
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * @Description
     * @Author susu
     * @Date 2024/3/8
     */
    public class TestWordImage2DealBug {
        public static void main(String[] args) throws IOException {
            // 读取本地的一个现有的Word文档,并创建对应的文档对象
            String fileInPath = "/Users/susu/file_test/poi3.8-test/test_word_in_1.docx";
            FileInputStream fileInputStream = new FileInputStream(fileInPath);
    
            // 使用自定义的 MyXWPFDocument
            MyXWPFDocument document = new MyXWPFDocument(fileInputStream);
    
            try {
                String imagePath = "/Users/susu/file_test/poi3.8-test/susu.jpg"; // 图片文件路径
                FileInputStream imageStream = new FileInputStream(imagePath);
                String picId = document.addPictureData(imageStream, XWPFDocument.PICTURE_TYPE_JPEG);
                document.createPicture(picId, document.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_JPEG), 200, 150);
    
                String fileOutPath = "/Users/susu/file_test/poi3.8-test/test_word_out_1.docx";
                FileOutputStream fos = new FileOutputStream(fileOutPath);
                document.write(fos);
                fos.close();
            } catch (InvalidFormatException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    }
    
    
  • 测试效果如下(可以看到图片已成功插入):
    在这里插入图片描述

3.1.2 参考

  • 参考:
    https://www.xuebuyuan.com/577192.html.

    https://bz.apache.org/bugzilla/show_bug.cgi?id=49765#c14.

3.2 方案2——使用开源框架xdocreport

  • 只需导入 xdocreport 依赖,代码不用改变,原先图片不展示的代码再测试就没问题了。如下:
    在这里插入图片描述

  • xdocreport 内部依赖了 poi ,如果xdocreport之后,可以不用导入poi,但是如果还想继续poi3.8版本,则需要指定poi版本,继续导入poi3.8,依赖如下:

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.8</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>3.8</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-scratchpad</artifactId>
      <version>3.8</version>
    </dependency>
    
    <!--引入这个之后,poi3.8就没有图片的bug了-->
    <dependency>
      <groupId>fr.opensagres.xdocreport</groupId>
      <artifactId>org.apache.poi.xwpf.converter.pdf</artifactId>
      <version>1.0.6</version>
    </dependency>
    
  • 对比一下导入 xdocreport 之后依赖的变化,如下:
    在这里插入图片描述

4. 其他

  • 如果你的项目很老,升级很闹心,那就暂且用上面方法解决吧!
  • 当然如果你用的不是不好升级的老系统,可以考虑更高级的poi版本,也可以了解一下 Poi-tl ,poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,主要是官网文档真的很友好,很详细,相当不错,官网如下:
    https://deepoove.com/poi-tl/#_why_poi_tl.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【爬虫】实战-爬取Boss直聘信息数据

专栏文章索引&#xff1a;爬虫 所用工具&#xff1a; 自动化工具&#xff1a;DrissionPage 目录 一、找到目标数据(2个确定)​ 1.确定目标网页 2.确定目标网址 二、编写代码​ 三、查看数据​ 五、总结 一、找到目标数据(2个确定) 1.确定目标网页 打开目标网站 网站&am…

Llama 2 模型

非常清楚&#xff01;&#xff01;&#xff01;Llama 2详解 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/649756898?utm_campaignshareopn&utm_mediumsocial&utm_psn1754103877518098432&utm_sourcewechat_session一些补充理解&#xff1a; 序列化&#xff…

Git学习笔记之标签

Git 可以给仓库历史中的某一个提交打上标签&#xff0c;以示重要。 比较有代表性的 是人们会使用这个功能来标记发布结点&#xff08; v1.0 、 v2.0 等等&#xff09;。 1、列出标签 列出已有的标签: git tag按照通配符列出标签需要 -l 或 --list 选项。如果你只想要完整的标…

真机笔记(1)第一阶段知识讲解

目录 第一阶段讲解&#xff1a; 1.1 机房 1.2 分类&#xff1a; 1.3 机房建设标准 1.3.1 安全性: 1.3.2 供电&#xff1a; 1.3.3 空气调节&#xff1a;&#xff08;恒温恒湿&#xff09; 1.3.4 电磁防护&#xff1a; 2.1 机柜 2.2 分类 2.3 机柜的高度单位 3.1 设备…

VUE3.0(一):vue3.0简介

Vue 3 入门指南 什么是vue Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界…

故障诊断模型 | 环境基于健康指标(Health indicator)的滚动轴承故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | 环境基于健康指标(Health indicator)的滚动轴承故障诊断 基于健康指标的滚动轴承故障诊断方法是一种重要的机械故障诊断技术,它通过对滚动轴承运行过程中的健康指标进行监测和分析,来判…

asp.net mvc 重新引导视图路径,改变视图路径

asp.net mvc 重新引导视图路径&#xff0c;改变视图路径 使用指定的控制器上下文和母版视图名称来查找指定的视图 通过本文学习&#xff0c;你可以根据该技法&#xff0c;去实现&#xff0c;站点自定义皮肤&#xff0c;手机站和电脑站&#xff0c;其他设备站点&#xff0c;在不…

创龙教仪基于瑞芯微3568的ARM Cortex A-55教学实验箱 适用于人工智能 传感器 物联网等领域

适用课程 Cortex-A55 ARM嵌入式实验箱主要用于《ARM 系统开发》、《ARM 应用开发》《物联网通信技术》、《嵌入式系统设计》、《移动互联网技术》、《无线传感器网络》、《物联网设计方法与应用》、《人工智能》等课程。 适用专业 Cortex-A55 ARM嵌入式实验箱主要面向电子信…

python拍卖行系统的设计与实现flask-django-nodejs-php

此系统设计主要采用的是python语言来进行开发&#xff0c;采用django/flask框架技术&#xff0c;框架分为三层&#xff0c;分别是控制层Controller&#xff0c;业务处理层Service&#xff0c;持久层dao&#xff0c;能够采用多层次管理开发&#xff0c;对于各个模块设计制作有一…

OpenAI GPT商店面临质量与合规问题;黄仁勋预测:十年内AI将实时生成游戏画面

&#x1f989; AI新闻 &#x1f680; OpenAI GPT商店面临质量与合规问题 摘要&#xff1a;OpenAI旗下的GPT商店因存在大量涉嫌侵权内容、助长学术不诚实行为及违规内容等问题而引起关注。其中包括未经授权使用迪士尼、漫威角色生成内容的GPT模型&#xff0c;以及声称能绕过剽…

PointNet++论文复现(一)【PontNet网络模型代码详解 - 分类部分】

PontNet网络模型代码详解 - 分类部分 专栏持续更新中!关注博主查看后续部分! 分类模型的训练: ## e.g., pointnet2_ssg without normal features python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg python test_classification.py…

【测试开发学习历程】MySQL增删改操作 + 备份与还原 + 索引、视图、存储过程

前言&#xff1a; SQL内容的连载&#xff0c;到这里就是最后一期啦&#xff01; 如果有小伙伴要其他内容的话&#xff0c;我会追加内容的。&#xff08;前提是我有学过&#xff0c;或者能学会&#xff09; 接下来&#xff0c;我们就要开始python内容的学习了 ~ ~ 目录 1 …

Airgorah:一款功能强大的WiFi安全审计工具

关于Airgorah Airgorah是一款功能强大的WiFi安全审计工具&#xff0c;该工具可以轻松发现和识别连接到无线接入点的客户端&#xff0c;并对特定的客户端执行身份验证攻击测试&#xff0c;捕捉WPA握手包&#xff0c;并尝试破解接入点的密码。在该工具的帮助下&#xff0c;广大研…

.NET Core 服务实现监控可观测性最佳实践

前言 本次实践主要是介绍 .Net Core 服务通过无侵入的方式接入观测云进行全面的可观测。 环境信息 系统环境&#xff1a;Kubernetes编程语言&#xff1a;.NET Core ≥ 2.1日志框架&#xff1a;Serilog探针类型&#xff1a;ddtrace 接入方案 准备工作 DataKit 部署 DataK…

平衡隐私与效率,Partisia Blockchain 解锁数字安全新时代

原文&#xff1a;https://cointelegraph.com/news/exploring-multiparty-computations-role-in-the-future-of-blockchain-privacy&#xff1b; https://medium.com/partisia-blockchain/unlocking-tomorrow-outlook-for-mpc-in-2024-and-beyond-cb170e3ec567 编译&#xff1…

Jupyter R绘图 汉字显示乱码的解决办法

1.Jupyte中&#xff0c;R绘图&#xff0c;汉字显示乱码 2.如何解决&#xff1f; (1)R中安装showtext 登录linux服务器 #R > install.packages(“showtext”) … 出错 (2)退出R,安装freetype-config #apt install libfreetype6-dev 出错 &#xff08;3&#xff09;进入R&…

么样才能用最便捷的方式为Mac提速呢?

Mac是现代人日常工作时必不可少的工具&#xff0c;尤其是在居家办公已经屡见不鲜的当下。视频会议、文档传送、视频剪辑等等。它在工作中扮演的角色越来越重要&#xff0c;所以也导致了它的流畅程度可以在很大程度上影响人们一整天的工作效率和心情。 但是影响Mac的运行和响应速…

excel文件可以转成word文件吗?汇帮PDF转换器帮你实现excel转word

将Excel文件转换为Word文档是一个相对简单的任务&#xff0c;但在执行过程中需要注意一些细节&#xff0c;以确保转换后的文档格式正确、内容清晰。下面将详细介绍用汇帮PDF转换器将Excel转Word的步骤和注意事项。 一、Excel文件准备 在进行转换之前&#xff0c;首先确保Excel…

新能源汽车BMS应用设计

新能源汽车BMS应用设计 电池管理系统&#xff08;BMS&#xff09; 概述 电池管理系统&#xff08;BMS&#xff09;为一套保护动力电池使用安全的控制系统&#xff0c;时刻监控电池的使用状态&#xff0c;通过必要措施缓解电池组的不一致性&#xff0c;为新能源车辆的使用安全…

ideaSSM 学员信息管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 学员信息管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…