引言
许多数据文件中可能包含嵌入式图片,这些图片对于数据分析和可视化非常重要。然而,从 wps 在 excel 中读取这些图片可能会有一些技术挑战。在本文中,我将展示如何从 wps excel 文件中读取嵌入的图片,并提供代码示例。
提取图片资源的方法
以下是用于从 wps excel 文件中读取图片资源的方法。我们使用了 apache poi 库来处理 excel 文件,并使用了 cn.hutool.json 库来处理 xml 数据。这些库可以帮助我们解析 excel 文件中的嵌入式图片。

主函数
首先,我们定义了主函数 main,用于测试图片提取功能:
public static void main(string[] args) {
picturesutils picturesutils = new picturesutils();
byte[] filedata = picturesutils.getfilestream(new file("你的文件路径"));
map<string, xssfpicturedata> pictures = picturesutils.getpictures(filedata);
pictures.foreach((id, xssfpicturedata) -> {
system.out.println("id:" + id);
string filename = xssfpicturedata.getpackagepart().getpartname().getname();
system.out.println("filename:" + filename);
file file = new file("d:\\" + filename);
file dir = file.getparentfile();
dir.mkdirs();
try {
files.write(path.of(file.getpath()), xssfpicturedata.getdata());
} catch (ioexception e) {
e.printstacktrace();
}
});
}在这个函数中,我们创建了一个 picturesutils 实例,并从文件路径中获取文件数据。然后,我们调用 getpictures 方法来提取图片资源,并遍历结果将图片写入本地文件。
获取浮动图片
接下来,我们展示了如何从 excel 文件中获取浮动图片:
public static map<string, xssfpicturedata> getfloatingpictures(xssfsheet xssfsheet) {
map<string, xssfpicturedata> mapfloatingpictures = new hashmap<>();
xssfdrawing drawingpatriarch = xssfsheet.getdrawingpatriarch();
if (drawingpatriarch != null) {
list<xssfshape> shapes = drawingpatriarch.getshapes();
for (xssfshape shape : shapes) {
if (shape instanceof xssfpicture picture) {
xssfclientanchor anchor = (xssfclientanchor) picture.getanchor();
xssfpicturedata picturedata = picture.getpicturedata();
string key = anchor.getrow1() + "-" + anchor.getcol1();
mapfloatingpictures.put(key, picturedata);
}
}
}
return mapfloatingpictures;
}该方法接收一个 xssfsheet 对象,并返回一个包含浮动图片的映射。它遍历工作表中的所有形状,并将图片数据存储在映射中。
处理图片数据
最后,我们展示了如何处理 excel 文件中的图片数据,包括嵌入式图片和浮动式图片:
public map<string, xssfpicturedata> getpictures(byte[] data) {
try {
map<string, string> mapconfig = processzipentries(new bytearrayinputstream(data));
map<string, xssfpicturedata> mappictures = processpictures(new bytearrayinputstream(data), mapconfig);
iterator<sheet> sheetiterator = workbookfactory.create(new bytearrayinputstream(data)).sheetiterator();
while (sheetiterator.hasnext()) {
mappictures.putall(getfloatingpictures((xssfsheet) sheetiterator.next()));
}
return mappictures;
} catch (ioexception e) {
return new hashedmap<>();
}
}在该方法中,我们使用 processzipentries 和 processpictures 方法来处理 zip 文件中的条目和图片数据。然后,通过遍历 excel 文件中的所有工作表,获取浮动图片。
完整代码
实际在程序中读取的内容为=dispimg(“id_03bc802ddab24510a9883db157eac0f8”,1)公式
将公式中的id提取出来id_03bc802ddab24510a9883db157eac0f8,最后就可以使用下面方法拿到当前id获取到的图片资源 jdk版本17
import cn.hutool.json.jsonarray;
import cn.hutool.json.jsonobject;
import cn.hutool.json.xml;
import lombok.extern.slf4j.slf4j;
import org.apache.commons.collections4.map.hashedmap;
import org.apache.commons.io.ioutils;
import org.apache.commons.lang3.stringutils;
import org.apache.poi.openxml4j.opc.packagepartname;
import org.apache.poi.ss.usermodel.sheet;
import org.apache.poi.ss.usermodel.workbook;
import org.apache.poi.ss.usermodel.workbookfactory;
import org.apache.poi.xssf.usermodel.*;
import java.io.*;
import java.nio.charset.standardcharsets;
import java.nio.file.files;
import java.nio.file.path;
import java.util.hashmap;
import java.util.iterator;
import java.util.list;
import java.util.map;
import java.util.zip.zipentry;
import java.util.zip.zipinputstream;
/**
* @author bianhl
* @version 1.0
* @description 获取图片资源
* @date 2024年4月28日08:44:42
*/
@slf4j
public class picturesutils {
public static void main(string[] args) {
picturesutils picturesutils = new picturesutils();
byte[] filedata = picturesutils.getfilestream(new file("你的文件路径"));
map<string, xssfpicturedata> pictures = picturesutils.getpictures(filedata);
pictures.foreach((id, xssfpicturedata) -> {
system.out.println("id:" + id);
string filename = xssfpicturedata.getpackagepart().getpartname().getname();
system.out.println("filename:" + filename);
file file = new file("c:\\users\\xxx\\desktop\\" + filename);
file dir = file.getparentfile();
dir.mkdirs();
try {
files.write(path.of(file.getpath()), xssfpicturedata.getdata());
} catch (ioexception e) {
e.printstacktrace();
}
});
}
/**
* 获取浮动图片,以 map 形式返回,键为行列格式 x-y。
*
* @param xssfsheet wps 工作表
* @return 浮动图片的 map
*/
public static map<string, xssfpicturedata> getfloatingpictures(xssfsheet xssfsheet) {
map<string, xssfpicturedata> mapfloatingpictures = new hashmap<>();
xssfdrawing drawingpatriarch = xssfsheet.getdrawingpatriarch();
if (drawingpatriarch != null) {
list<xssfshape> shapes = drawingpatriarch.getshapes();
for (xssfshape shape : shapes) {
if (shape instanceof xssfpicture picture) {
xssfclientanchor anchor = (xssfclientanchor) picture.getanchor();
xssfpicturedata picturedata = picture.getpicturedata();
string key = anchor.getrow1() + "-" + anchor.getcol1();
mapfloatingpictures.put(key, picturedata);
}
}
}
return mapfloatingpictures;
}
/**
* 处理 wps 文件中的图片数据,返回图片信息 map。
*
* @param stream 输入流
* @param mapconfig 配置映射
* @return 图片信息的 map
* @throws ioexception
*/
private map<string, xssfpicturedata> processpictures(bytearrayinputstream stream, map<string, string> mapconfig) throws ioexception {
map<string, xssfpicturedata> mappictures = new hashedmap<>();
workbook workbook = workbookfactory.create(stream);
list<xssfpicturedata> allpictures = (list<xssfpicturedata>) workbook.getallpictures();
for (xssfpicturedata picturedata : allpictures) {
packagepartname partname = picturedata.getpackagepart().getpartname();
string uri = partname.geturi().tostring();
if (mapconfig.containskey(uri)) {
string strid = mapconfig.get(uri);
mappictures.put(strid, picturedata);
}
}
return mappictures;
}
/**
* 获取 wps 文档中的图片,包括嵌入式图片和浮动式图片。
*
* @param data 二进制数据
* @return 图片信息的 map
* @throws ioexception
*/
public map<string, xssfpicturedata> getpictures(byte[] data) {
try {
map<string, string> mapconfig = processzipentries(new bytearrayinputstream(data));
map<string, xssfpicturedata> mappictures = processpictures(new bytearrayinputstream(data), mapconfig);
iterator<sheet> sheetiterator = workbookfactory.create(new bytearrayinputstream(data)).sheetiterator();
while (sheetiterator.hasnext()) {
mappictures.putall(getfloatingpictures((xssfsheet) sheetiterator.next()));
}
return mappictures;
} catch (ioexception e) {
return new hashedmap<>();
}
}
/**
* 处理 zip 文件中的条目,更新图片配置信息。
*
* @param stream zip 输入流
* @return 配置信息的 map
* @throws ioexception
*/
private map<string, string> processzipentries(bytearrayinputstream stream) throws ioexception {
map<string, string> mapconfig = new hashedmap<>();
zipinputstream zipinputstream = new zipinputstream(stream);
zipentry zipentry;
while ((zipentry = zipinputstream.getnextentry()) != null) {
try {
final string filename = zipentry.getname();
if ("xl/cellimages.xml".equals(filename)) {
processcellimages(zipinputstream, mapconfig);
} else if ("xl/_rels/cellimages.xml.rels".equals(filename)) {
return processcellimagesrels(zipinputstream, mapconfig);
}
} finally {
zipinputstream.closeentry();
}
}
return new hashedmap<>();
}
/**
* 处理 zip 文件中的 cellimages.xml 文件,更新图片配置信息。
*
* @param zipinputstream zip 输入流
* @param mapconfig 配置信息的 map
* @throws ioexception
*/
private void processcellimages(zipinputstream zipinputstream, map<string, string> mapconfig) throws ioexception {
string content = ioutils.tostring(zipinputstream, standardcharsets.utf_8);
jsonobject jsonobject = xml.tojsonobject(content);
if (jsonobject != null) {
jsonobject cellimages = jsonobject.getjsonobject("etc:cellimages");
if (cellimages != null) {
jsonarray cellimagearray = null;
object cellimage = cellimages.get("etc:cellimage");
if (cellimage != null && cellimage instanceof jsonarray) {
cellimagearray = (jsonarray) cellimage;
} else if (cellimage != null && cellimage instanceof jsonobject cellimageobj) {
if (cellimageobj != null) {
cellimagearray = new jsonarray();
cellimagearray.add(cellimageobj);
}
}
if (cellimagearray != null) {
processimageitems(cellimagearray, mapconfig);
}
}
}
}
/**
* 处理 cellimagearray 中的图片项,更新图片配置信息。
*
* @param cellimagearray 图片项的 jsonarray
* @param mapconfig 配置信息的 map
*/
private void processimageitems(jsonarray cellimagearray, map<string, string> mapconfig) {
for (int i = 0; i < cellimagearray.size(); i++) {
jsonobject imageitem = cellimagearray.getjsonobject(i);
if (imageitem != null) {
jsonobject pic = imageitem.getjsonobject("xdr:pic");
if (pic != null) {
processpic(pic, mapconfig);
}
}
}
}
/**
* 处理 pic 中的图片信息,更新图片配置信息。
*
* @param pic 图片的 jsonobject
* @param mapconfig 配置信息的 map
*/
private void processpic(jsonobject pic, map<string, string> mapconfig) {
jsonobject nvpicpr = pic.getjsonobject("xdr:nvpicpr");
if (nvpicpr != null) {
jsonobject cnvpr = nvpicpr.getjsonobject("xdr:cnvpr");
if (cnvpr != null) {
string name = cnvpr.getstr("name");
if (stringutils.isnotempty(name)) {
string strimageembed = updateimageembed(pic);
if (strimageembed != null) {
mapconfig.put(strimageembed, name);
}
}
}
}
}
/**
* 获取嵌入式图片的 embed 信息。
*
* @param pic 图片的 jsonobject
* @return embed 信息
*/
private string updateimageembed(jsonobject pic) {
jsonobject blipfill = pic.getjsonobject("xdr:blipfill");
if (blipfill != null) {
jsonobject blip = blipfill.getjsonobject("a:blip");
if (blip != null) {
return blip.getstr("r:embed");
}
}
return null;
}
/**
* 处理 zip 文件中的 relationship 条目,更新配置信息。
*
* @param zipinputstream zip 输入流
* @param mapconfig 配置信息的 map
* @return 配置信息的 map
* @throws ioexception
*/
private map<string, string> processcellimagesrels(zipinputstream zipinputstream, map<string, string> mapconfig) throws ioexception {
string content = ioutils.tostring(zipinputstream, standardcharsets.utf_8);
jsonobject jsonobject = xml.tojsonobject(content);
jsonobject relationships = jsonobject.getjsonobject("relationships");
if (relationships != null) {
jsonarray relationshiparray = null;
object relationship = relationships.get("relationship");
if (relationship != null && relationship instanceof jsonarray) {
relationshiparray = (jsonarray) relationship;
} else if (relationship != null && relationship instanceof jsonobject relationshipobj) {
if (relationshipobj != null) {
relationshiparray = new jsonarray();
relationshiparray.add(relationshipobj);
}
}
if (relationshiparray != null) {
return processrelationships(relationshiparray, mapconfig);
}
}
return null;
}
/**
* 处理 relationshiparray 中的关系项,更新配置信息。
*
* @param relationshiparray 关系项的 jsonarray
* @param mapconfig 配置信息的 map
* @return 配置信息的 map
*/
private map<string, string> processrelationships(jsonarray relationshiparray, map<string, string> mapconfig) {
map<string, string> maprelationships = new hashedmap<>();
for (int i = 0; i < relationshiparray.size(); i++) {
jsonobject relaitem = relationshiparray.getjsonobject(i);
if (relaitem != null) {
string id = relaitem.getstr("id");
string value = "/xl/" + relaitem.getstr("target");
if (mapconfig.containskey(id)) {
string strimageid = mapconfig.get(id);
maprelationships.put(value, strimageid);
}
}
}
return maprelationships;
}
/**
* @param file 数据文件
* @return {@link byte[]}
* @description
* @author bianhl
* @date 2024/4/26 13:52
*/
private byte[] getfilestream(file file) {
try (inputstream inputstream = new fileinputstream(file)) {
// 创建 bytearrayoutputstream 来暂存流数据
bytearrayoutputstream bytearrayoutputstream = new bytearrayoutputstream();
// 将 inputstream 读取到 bytearrayoutputstream 中
byte[] buffer = new byte[1024];
int length;
while ((length = inputstream.read(buffer)) != -1) {
bytearrayoutputstream.write(buffer, 0, length);
}
// 将 bytearrayoutputstream 的内容获取为字节数组
return bytearrayoutputstream.tobytearray();
} catch (ioexception e) {
return null;
}
}
}输出结果:

拿到的图片数据

以上就是利用java实现读取wps excel中嵌入的图片的详细内容,更多关于java读取excel嵌入的图片的资料请关注代码网其它相关文章!
发表评论