目录
- 通过apache.poi 获取excel中所有的图片(不限制插入的方式是浮动式还是嵌入到单元格)
- 通过apache.poi 获取excel中
指定列行
,浮动式(只能是浮动式,其他的获取不到)
插入的所有图片 - 通过apache.poi 获取excel中
指定列
,嵌入的单元格(只能是嵌入式的,其他的获取不到)
插入的所有图片 - 结合两种
介绍
插入图片的到excel中的时候,其实是分为两种插入形式的,浮动式和嵌入到单元格,如下图
通过apache.poi 获取excel中所有的图片(不限制插入的方式是浮动式还是嵌入到单元格)
pic.xlsx
内容,共五张图片
代码大概思路如下,获取pic.xlsx
文件中所有图片,然后保存到/picTemp
文件夹路径下
依赖包代码:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.1.1</version>
</dependency>
业务代码:
package org.example.officeexcel;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class ExcelImageExtractorTest {
/**
* 提取Excel文件中的所有的图片(浮动式的,嵌入式的)
*/
@Test
public void test1() {
String excelFilePath = "/Users/luojiwen/Desktop/temp/0919/pic.xlsx";
String outputDir = "/Users/luojiwen/Desktop/temp/0919/picTemp/";
try (FileInputStream fis = new FileInputStream(new File(excelFilePath));
Workbook workbook = new XSSFWorkbook(fis)) {
// 获取工作簿中的所有嵌入图片
List<? extends PictureData> pictures = workbook.getAllPictures();
// 导出每个图片
int pictureIndex = 1;
for (PictureData pictureData : pictures) {
String ext = pictureData.suggestFileExtension();
String imageName = "image" + pictureIndex + "." + ext;
FileOutputStream fos = new FileOutputStream(new File(outputDir + imageName));
fos.write(pictureData.getData());
fos.close();
pictureIndex++;
}
System.out.println("图片导出完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
控制台输出:
五张图片都提取出来了,效果输出:
通过apache.poi 获取excel中指定列行
,浮动式(只能是浮动式,其他的获取不到)
插入的所有图片
最好设置一下图片的属性,不然你看到的和他实际上所处的单元格可能并不是一致的,比如,你看到的是在第一列第一行的单元格内,实际上,他可能并不在。
这是我的pic.xlsx
内容,共六张图片
我想获取指定的某一个单元格,如我想获取最下面的盆栽
图片,他在第一列(A列)第三行,因为代码中下标是从零开始,所有我们指定的坐标就是(0,2)代表第一列第三行。
代码大概思路如下,获取pic.xlsx
文件中所有图片,然后保存到/picTemp1
文件夹路径下,正常来说只会有一张图片
业务功能代码:
/**
* 提取指定单元格(下标从零开始,(0,1:第一列第二行))中的图片(只有浮动式的且要设置图片的属性为大小和位置随改变)
*/
@Test
public void test2(){
String excelFilePath = "/Users/luojiwen/Desktop/temp/0919/pic.xlsx";
String outputDir = "/Users/luojiwen/Desktop/temp/0919/picTemp1/";
int targetColumnIndex = 0; // 例如:提取第A列(索引从0开始)
int targetRowIndex = 2; // 例如:提取第1行(索引从0开始)
try (FileInputStream fis = new FileInputStream(new File(excelFilePath));
XSSFWorkbook workbook = new XSSFWorkbook(fis)) {
// 遍历每个工作表
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
XSSFSheet sheet = workbook.getSheetAt(i);
// 获取每个工作表中的绘图对象
XSSFDrawing drawing = sheet.getDrawingPatriarch();
if (drawing == null) continue; // 如果没有绘图对象则跳过
List<XSSFShape> shapes = drawing.getShapes();
int pictureIndex = 1;
for (XSSFShape shape : shapes) {
if (shape instanceof XSSFPicture) {
XSSFPicture picture = (XSSFPicture) shape;
XSSFPictureData pictureData = picture.getPictureData();
XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();
// 获取图片位置
int col1 = anchor.getCol1();
int col2 = anchor.getCol2();
int row1 = anchor.getRow1();
int row2 = anchor.getRow2();
// 检查图片是否位于目标单元格中
if (targetColumnIndex >= col1 && targetColumnIndex <= col2 && targetRowIndex >= row1 && targetRowIndex <= row2) {
String ext = pictureData.suggestFileExtension();
String imageName = "sheet" + i + "_cell_" + row1