Java 读取 Excel 中的图片
在 Java 中读取 Excel 文件中的图片,可以使用 Apache POI 或 EasyExcel 等库,以下是两种方法的实现方式:

使用 Apache POI
添加依赖
<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>
读取 Excel 中的图片
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class ExcelImageReader {
public static void main(String[] args) {
String filePath = "path/to/your/excel/file.xlsx";
try (FileInputStream fis = new FileInputStream(filePath);
Workbook workbook = new XSSFWorkbook(fis)) {
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
// 获取所有图片
Map<Integer, List<XSSFPictureData>> pictureDataMap = getSheetPictures(sheet);
// 遍历行和单元格
for (Row row : sheet) {
for (Cell cell : row) {
// 检查单元格是否有图片
if (pictureDataMap.containsKey(cell.getRowIndex())) {
List<XSSFPictureData> pictures = pictureDataMap.get(cell.getRowIndex());
for (XSSFPictureData pictureData : pictures) {
// 保存图片到文件
byte[] data = pictureData.getData();
String fileName = "image_" + cell.getRowIndex() + "_" + cell.getColumnIndex() + ".png";
Files.write(Paths.get(fileName), data);
System.out.println("Saved image: " + fileName);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static Map<Integer, List<XSSFPictureData>> getSheetPictures(Sheet sheet) {
Map<Integer, List<XSSFPictureData>> pictureDataMap = new HashMap<>();
if (sheet instanceof XSSFSheet) {
XSSFSheet xssfSheet = (XSSFSheet) sheet;
List<XSSFPictureData> pictures = xssfSheet.getRelations().stream()
.filter(r -> r instanceof XSSFPictureData)
.map(r -> (XSSFPictureData) r)
.toList();
for (XSSFPictureData picture : pictures) {
int pictureRow = picture.getAnchor().getRow1(); // 获取图片所在行
pictureDataMap.computeIfAbsent(pictureRow, k -> new ArrayList<>()).add(picture);
}
}
return pictureDataMap;
}
}
使用 EasyExcel
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
自定义监听器处理图片
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExcelImageReaderWithEasyExcel {
public static void main(String[] args) {
String filePath = "path/to/your/excel/file.xlsx";
try (FileInputStream fis = new FileInputStream(filePath)) {
ExcelReaderBuilder readerBuilder = EasyExcel.read(fis);
// 自定义监听器
AnalysisEventListener<Map<Integer, Object>> listener = new AnalysisEventListener<Map<Integer, Object>>() {
private Map<Integer, List<XSSFPictureData>> pictureDataMap = new HashMap<>();
@Override
public void invoke(Map<Integer, Object> data, AnalysisContext context) {
ReadSheetHolder sheetHolder = context.readSheetHolder();
List<XSSFPictureData> pictures = sheetHolder.getSheet().getRelations().stream()
.filter(r -> r instanceof XSSFPictureData)
.map(r -> (XSSFPictureData) r)
.toList();
for (XSSFPictureData picture : pictures) {
int pictureRow = picture.getAnchor().getRow1();
pictureDataMap.computeIfAbsent(pictureRow, k -> new ArrayList<>()).add(picture);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 处理完所有数据后的操作
for (Map.Entry<Integer, List<XSSFPictureData>> entry : pictureDataMap.entrySet()) {
int rowIndex = entry.getKey();
List<XSSFPictureData> pictures = entry.getValue();
for (XSSFPictureData picture : pictures) {
try {
byte[] data = picture.getData();
String fileName = "image_" + rowIndex + ".png";
Files.write(Paths.get(fileName), data);
System.out.println("Saved image: " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
readerBuilder.sheet().doRead(listener);
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事项
-
图片位置:上述代码中图片是按行位置获取的,如果需要更精确的位置信息(如列位置),需要进一步处理锚点信息。
-
图片格式:Excel 中的图片可能是 PNG、JPG 等格式,保存时可以根据图片数据的前几个字节判断格式。
-
性能考虑:Excel 文件很大,读取所有图片可能会消耗较多内存,可以考虑分批处理。
-
旧版 Excel:上述代码适用于 .xlsx 格式(Office 2007+),对于 .xls 格式需要使用 HSSFWorkbook 类。
-
EasyExcel 限制:EasyExcel 对图片的支持不如 Apache POI 完善,可能需要结合 POI 使用。
希望这些代码能帮助你实现从 Excel 文件中读取图片的功能!
