首页 > 编程语言 >java读取wps嵌入式图片思路

java读取wps嵌入式图片思路

时间:2024-06-21 09:01:10浏览次数:12  
标签:xml Map java jar 嵌入式 wps throws 图片

  这个只写了思路具体代码在文章最后,不想了解得直接去拿代码

  1. 了解Excel数据结构

        Excel 文件格式后缀xls,xlsx 其实是一个压缩文件,是由多个文件夹以及xml 文件组合为一个文件,xml文件记录了Excel得内容以及样式等信息。加入在桌面新建一个xlsx文件,然后插入一个嵌入式图片,然后修改文件后缀为.zip ,然后解压我们得到以下一个文件夹

可以看到又几个文件夹以及xml,,poi 不能读取wps嵌入式图片,是因为这个是wps自己独有得并不属于office标准,cellImages.xml 等于是wps 独有得,加入图片新增一个悬浮图片得到得是

 会有一个drawings得文件夹这个是office支持得格式正常获取图片是可以得 ,直接在poi 得api 就可以获取到,自己去百度吧

<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<xdr:twoCellAnchor editAs="oneCell">
<xdr:from>
<xdr:col>6</xdr:col>
<xdr:colOff>0</xdr:colOff>
<xdr:row>4</xdr:row>
<xdr:rowOff>0</xdr:rowOff>
</xdr:from>
<xdr:to>
<xdr:col>21</xdr:col>
<xdr:colOff>548640</xdr:colOff>
<xdr:row>46</xdr:row>
<xdr:rowOff>7620</xdr:rowOff>
</xdr:to>
<xdr:pic>
<xdr:nvPicPr>
<xdr:cNvPr id="2" name="图片 1"/>
<xdr:cNvPicPr>
<a:picLocks noChangeAspect="1"/>
</xdr:cNvPicPr>
</xdr:nvPicPr>
<xdr:blipFill>
<a:blip r:embed="rId1"/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</xdr:blipFill>
<xdr:spPr>
<a:xfrm>
<a:off x="3703320" y="731520"/>
<a:ext cx="9806940" cy="7688580"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln w="9525">
<a:noFill/>
</a:ln>
</xdr:spPr>
</xdr:pic>
<xdr:clientData/>
</xdr:twoCellAnchor>
</xdr:wsDr>

 打开drawing1.xml 可以看到from 标签记录了图片得位置但是使用wps 生成得cellImages如图一所示

生成得是wps 得自定义标签这个没有from 不存储位置信息但是可以看到ID ID_6702DEA2ADBA44AE8C65065BD13FF23D 这个东西

wps 嵌入单元格信息是这样得,只要找出id和图片对应得信息就可以获取到图片

2.wps xml 中找对应关系

//这个是relations 

图片存储在以下得位置:

可以看出 ID 关联了rid ,rid 又和图片关联 比如你上传多个图片一样的,引用得其实是一张图片

3.poi 代码解析找出对应关系

 首先就要读取一下这个xml

我是使用xmlBean来解析cellimages.xml pio底层也是用这个

主要过程就是-》基于xml 生成xsd 文件->xsd 文件生成java 代码 -》java 代码解析xml 内容获取关系,rid1和图片路径得关系poi 已经支持不用做,获取图片信息得方法poi 也不用做利用poi的方法就可以获取(不会或者不了解xmlBean得可以自己去学习)

1.根据xml 文件成成xsd 文件  下载 Download trang-20091111.jar : trang « t « Jar File Download

java -jar trang.jar cellimages.xml cellimages.xsd

2.下载xmlBean

Apache Download Mirrors

下载完成后解压

利用scomp 指令生成对用得jar 包

XMLBeans Tools 这个是官方文档 

运行指令

scomp -out c:\xmltypes.jar c:\cellimages.xsd  -compiler C:\java\jdk1.6.0_10\bin\javac customer.xsdconfig

意思是根据xsd 生成java 解析xml 对应得jar customer.xsdconfig内容如下

<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">   <xb:namespace>   <xb:package>com.chenkang.demo.util.excel</xb:package>   </xb:namespace></xb:config>

然后后得到一个jar 包项目值引入依赖

4.开始代码解析

   /**
     * {ID_581F75328A584939A51CC44E17945975:rid1,ID_6702DEA2ADBA44AE8C65065BD13FF23D:rid1}
     * 行rid 以及图片id关系
     *
     * @param cellImagePart cellImagePart
     * @return Map
     * @throws Exception 异常
     */
    public static Map<String, String> getRidAndPidMap(PackagePart cellImagePart) throws Exception {
        CellImagesDocument cellImagesDocument = CellImagesDocument.Factory.parse(cellImagePart.getInputStream());
        CellImagesDocument.CellImages cellImages = cellImagesDocument.getCellImages();
        Map<String, String> result = new HashMap<>(4);
        cellImages.getCellImageList().forEach(cellImage -> {
            result.put(cellImage.getPic().getNvPicPr().getCNvPr().getName().getStringValue(), cellImage.getPic().getBlipFill().getBlip().getEmbed());
        });
        return result;
    }

这个就是解析cellImages.xml 来获取rid 和id 得关系

    /**
     *   //relationships 绑定了rid 和 图片 路径得地址
     * 获取rid和path的关系
     * @param packagePart cellImagePart
     * @return Map
     * @throws Exception 异常
     */
    public static Map<String, String> getRidAndPathMap(PackagePart packagePart) throws Exception {
        Map<String, String> ridAndPathMap = new HashMap<>(4);
        PackageRelationshipCollection relationships = packagePart.getRelationships();
        relationships.forEach(relationship -> ridAndPathMap.put(relationship.getId(), relationship.getTargetURI().getPath()));
        return ridAndPathMap;
    }

这个是获取rid 和图片路径得关系

    /**
     *图片ID和 XSSFPictureData
     *
     * @param workbook workbook
     * @return List<Map < String, String>>
     * @throws Exception 异常
     */
    public static Map<String, XSSFPictureData> getPictureMap(XSSFWorkbook workbook) throws Exception {
        OPCPackage opcPackage = workbook.getPackage();
        List<PackagePart> partsByContentType = opcPackage.getPartsByContentType("application/vnd.wps-officedocument.cellimage+xml");
        PackagePart packagePart = partsByContentType.get(0);
        List<XSSFPictureData> allPictures = workbook.getAllPictures();
        Map<String,XSSFPictureData> result = new HashMap<>(4);
        Map<String, String> ridAndPidMap = getRidAndPidMap(packagePart);
        Map<String, String> ridAndPathMap = getRidAndPathMap(packagePart);
        ridAndPidMap.forEach((key, value) -> {
            String path = ridAndPathMap.get(value);
            Optional<XSSFPictureData> first = allPictures.stream().filter(pictureData -> pictureData.getPackagePart().getPartName().getName().equals(path)).findFirst();
            result.put(key,first.orElse(null));
        });
        return result;

    }

这一步是来最终映射id 和图片得关系 为什么

List<XSSFPictureData> allPictures = workbook.getAllPictures();

这个能获取图片呢是因为无论是悬浮图片还是嵌入图片他最终都是读取到得是

这个路径

只是说找不到映射关系 再详细得可以去看下源码

最后测试:


    public static void main(String[] args) throws Exception {
        File file = new File("C:\\Users\\18151\\Desktop\\test.xlsx");
        XSSFWorkbook sheets = new XSSFWorkbook(file);
        XSSFSheet sheetAt = sheets.getSheetAt(0);
        String id=sheetAt.getRow(1).getCell(1).getStringCellValue();
        Map<String, XSSFPictureData> pictureMap = WpsImageUtil.getPictureMap(sheets);
        System.out.println(pictureMap);
        System.out.println(pictureMap.get(StringExtractor.extractID(id)));
    }

 读取文件,获取到cellValue得到得是

=DISPIMG("ID_C13878DEBED44D23AED14F38392FD788",1) 根据工具类拿到id ,然后再根据映射关系获取到得pictureData 这个直接getData()就是文件流该上传完成业务还是干嘛得都可以

完整得代码详见

java 利用poi读取wps嵌入式图片,自测-CSDN博客

标签:xml,Map,java,jar,嵌入式,wps,throws,图片
From: https://blog.csdn.net/weixin_38845058/article/details/139843457

相关文章

  • 秋招Java后端开发冲刺——基础篇2
    Java语言基础一、基本数据类型(8个)整型:byte(1字节)、short(2字节)、int(4字节)、long(8字节,使用时一定要在数值后面加上L)注:整型类型的最高位表示数据符号位,因此实际上数据的表示范围为(−......
  • 《JAVA 程序设计语言学习心得》
    在信息科技高速发展的当下,我怀着对编程世界的强烈好奇和探索欲望,开启了JAVA程序设计语言的学习之旅。一、学习JAVA程序设计语言的背景和动机随着数字化时代的来临,编程技能在各个领域的重要性日益凸显。我意识到掌握一门强大的编程语言,不仅能够提升自己的逻辑思维和解决问......
  • 基于Java的图书管理系统源码( GUI+JavaSwing+MySql )
    基于Java的图书管理系统源码(GUI+JavaSwing+MySql)1、使用JavaSwing,Mysql实现2、IDEA编写,eclipse也可以运行(测试使用的IDEA24.1.3)3、测试环境:JDK1.8(JDK20),MySQL5.54、本项目实现了注册、登录、图书馆数据维护、新书订购、借阅管理、系统维护等功能=============......
  • 在Java中public class与class的区别(详细解释)
    在Java中,class 关键字用于定义一个类。当你使用 class关键字定义一个类时,它可以是公开的(即可以从其他包中访问)或包私有的(即只能在定义它的包内部访问)。在编写程序时,为了明确指定一个类为公开的,我们可以使用public 关键字来修饰 class。下面是publicclass 和 class(没有......
  • java的日志记录框架
    1.什么是日志日志是记录应用程序运行时所产生的事件信息的工具。2.日志的分类(1)SQL日志(2)异常日志(3)业务日志3.日志的主要用途问题追踪、状态监控、安全审计4.使用log4j2日志的步骤a.配置log4j2配置文件b.创建日志容器log对象c.使用log对象对应的危险等级提示来记录日......
  • 基于Springboot的CSGO赛事管理系统(有报告)。Javaee项目,springboot项目。
    演示视频:基于Springboot的CSGO赛事管理系统(有报告)。Javaee项目,springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Vue+Maven+Layui+Elementui来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统......
  • 基于SSM的宠物医院管理系统的设计与实现(有报告)。Javaee项目。ssm项目。
    演示视频:基于SSM的宠物医院管理系统的设计与实现(有报告)。Javaee项目。ssm项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringMvc+Mybatis+Vue+Layui+Elementui+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。......
  • 嵌入式Linux中platform平台设备模型的框架(实现LED驱动)
    在前面讨论的所有LED驱动程序中,把全部设备信息和驱动代码都写在了一个文件中,从本质上看,这种开发方式与单片机的开发并没有太大的区别,一旦硬件信息发生变化,就必须要修改驱动程序的源码。然而,Linux作为一个发展成熟、功能齐全、结构复杂的操作系统,它对于代码的可维护性、复用性非常......
  • 【全网最全最详细】JavaSE基础面试题(下)
    目录二十七、什么是BIO、NIO、AIO?二十八、SimpleDateFormat是线程安全的吗?二十九、如何解决SimpleDateFormat线程不安全的问题?三十、while(true)和for循环哪个性能好?三十一、Arrays.sort是使用什么排序算法实现的?三十二、String是如何实现不可变的?三十三、字符串常量......
  • 2024华为OD机试真题- 计算三叉搜索树的高度-(C++/Java/Python)-C卷D卷-100分
     2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++) 题目描述定义构造三叉搜索树规则如下:每个节点都存有一个数,当插入一个新的数时,从根节点向下寻找,直到找到一个合适的空节点插入。查找的规则是:1.如果数小于节点的数减去500,则将数插入节点的左子树2.如果数大于节点的......