需求
使用POI读取Excel文件中的图片数据。我的需求是导入一份Excel,读取Excel中的图片信息并将其上传至服务器,把图片上传的路径存入数据库,关键是WPS的嵌入式格式图片真的难读,用WPS打开可以看到图片,使用office的Excel打开就是一段代码无法预览图片。参考了很多大佬的博客,我自己也是慢慢摸索后完美实现需求!
实现
读取普通图片信息
直接上代码
import cn.hutool.json.JSONUtil;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class ExcelImportDemo1 {
public static void main(String[] args) throws IOException {
String path = "D:\\模板测试2.xlsx";// 替换为你自己的文件
String imageTargetPath = "D:\\download\\test\\";// 替换为你自己的输出路径
File file = new File(path);
// 获取图片数据
Map<String, PictureData> map = getPictureFromExcel(file, 1);
// 图片保存结果list
LinkedList<String> pictureList = new LinkedList<>();
// 遍历图片数据,将图片写入磁盘
for (Map.Entry<String, PictureData> entry : map.entrySet()) {
String key = entry.getKey();
PictureData pictureData = entry.getValue();
String extension = pictureData.suggestFileExtension();
// 构建图片文件名,使用行列作为文件名
String[] coordinates = key.split("-");
// 文件名规则 行号-列号.后缀名 列号不变
String imageFileName = coordinates[0] + "-" + coordinates[1] + "." + extension;
pictureList.add(imageFileName);
}
System.out.println(JSONUtil.toJsonStr(pictureList));
// 根据键的第一个数字进行分组
Map<Character, List<PictureData>> groupedImages = new HashMap<>();
for (Map.Entry<String, PictureData> entry : map.entrySet()) {
char firstDigit = entry.getKey().charAt(0);
groupedImages.computeIfAbsent(firstDigit, k -> new ArrayList<>()).add(entry.getValue());
}
// 打印分组结果
for (Map.Entry<Character, List<PictureData>> entry : groupedImages.entrySet()) {
char key = entry.getKey();
List<PictureData> images = entry.getValue();
for (PictureData image : images) {
byte[] data = image.getData();
System.out.println(data);
}
}
// 遍历图片数据,将图片写入磁盘
for (Map.Entry<String, PictureData> entry : map.entrySet()) {
String key = entry.getKey();
PictureData pictureData = entry.getValue();
String extension = pictureData.suggestFileExtension();
// 构建图片文件名,使用行列作为文件名
String[] coordinates = key.split("-");
String imageFileName = coordinates[0] + "-" + coordinates[1] + "." + extension;
// 将图片数据写入文件
FileOutputStream out = new FileOutputStream(imageTargetPath + File.separator + imageFileName);
out.write(pictureData.getData());
out.close();
}
}
private static String getCellValueAsString(Cell cell) {
String cellValue = "";
if (cell != null) {
switch (cell.getCellType()) {
case STRING:
cellValue = cell.getStringCellValue();
break;
case NUMERIC:
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
// 根据需要处理其他单元格类型
}
}
return cellValue;
}
/**
* 获取excel表中的图片
*
* @return
* @throws IOException
* @throws InvalidFormatException
* @throws EncryptedDocumentException
* @Param fis 文件输入流
* @Param sheetNum Excel表中的sheet编号
*/
public static Map<String