java读取wps嵌入式图片思路

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

  1. 了解Excel数据结构

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

可以看到又几个文件夹以及xml,,poi 不能读取wps嵌入式图片,是因为这个cellimages是wps自己独有得并不属于office标准,新增一个悬浮图片然后解压得到以下一个文件列表

会有一个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博客

相关推荐
rgbhi8 小时前
VSTO WPS调试注册列表
wps
wtsolutions8 小时前
JSON导入WPS表格,JSON转wps,json2wps, WPS 插件使用指南
json·wps·wtsolutions
secondyoung12 小时前
WPS宏使用:一键批量调整图片与表格格式
经验分享·word·lua·markdown·wps·vb
wtsolutions12 小时前
WPS另存为JSON,WPS导出JSON, WPS表格转换成JSON : Excel to JSON WPS插件使用指南
json·excel·wps·插件·加载项·wtsolutions
【ql君】qlexcel14 小时前
WPS单元格满足条件时自动变色,单元格值大于某值变色
wps·条件格式·单元格·变色
lifallen2 天前
Word/WPS 制表位分析:如何设置公式居中和编号右对齐
word·wps
wtsolutions2 天前
JSON转Excel工具新增WPS插件功能,将JSON转换成WPS表格工作表数据
json·excel·wps·插件·转换·加载项·wtsolutions
wtsolutions3 天前
Excel to JSON by WTSolutions 4.0.0 版本更新公告
json·excel·wps·插件·转换·加载项·wtsolutions
wtsolutions3 天前
Excel to JSON by WTSolutions 4.0.0 Update Announcement
json·excel·wps·addin·wtsolutions·conversion
程序员学长李白3 天前
WPS绿色纯净版(无联网功能) v10.1.0.6876
经验分享·电脑·wps·推荐