Java?EasyExcel導(dǎo)入帶圖片的完整過程記錄
前言
項目中,要求批量導(dǎo)入 Excel 數(shù)據(jù)并讀取其中圖片,目前 EasyExcel 不支持讀取圖片,因此需要使用 Apache POI 進(jìn)行導(dǎo)入。然而Apache POI 需要開發(fā)者手動管理行、列、單元格等對象,相對較為底層且繁瑣。

作者隨即想到了一種方法,既能夠使用 EasyExcel 的簡便導(dǎo)入方式,又能夠識別圖片并進(jìn)行處理。
相關(guān)依賴
<!-- 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>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
Java 代碼展示
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.bi.my.vo.ExcelVo;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.result.R;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 數(shù)據(jù)+圖片導(dǎo)入
*
* @author wss
*/
@Slf4j
@RestController
@RequestMapping("/easy")
public class EasyExcelController {
/**
* 數(shù)據(jù)導(dǎo)入并識別圖片
*
* @param file file
* @return R<Object>
* @author wss
*/
@PostMapping("/import")
public R<Object> dataImport(@RequestParam("file") MultipartFile file) {
List<ExcelVo> excelVos = new ArrayList<>();
//數(shù)據(jù)處理
this.dataProcess(file, excelVos);
//圖像處理
this.imageProcess(file, excelVos);
//返回結(jié)果,這里也可以處理excelVos數(shù)據(jù),如往mysql存儲
return R.success(excelVos);
}
/**
* 圖片處理
*/
public void imageProcess(MultipartFile file, List<ExcelVo> excelVos) {
try {
XSSFWorkbook book = new XSSFWorkbook(file.getInputStream());
//方式1 獲取sheet數(shù)量,采用下標(biāo)方式遍歷讀取每個工作表數(shù)據(jù)
int sheetsNos = book.getNumberOfSheets();
for (int sheetNo = 0; sheetNo < sheetsNos; sheetNo++) {
Sheet sheet = book.getSheetAt(sheetNo);
//...省略,內(nèi)容為方式2
}
//方式2 獲取sheet數(shù)量,直接遍歷讀取每個工作表數(shù)據(jù)
for (Sheet sheet : book) {
XSSFSheet xssSheet = (XSSFSheet) sheet;
//獲取工作表中繪圖包
XSSFDrawing drawing = xssSheet.getDrawingPatriarch();
if (drawing == null) {
break;
}
//獲取所有圖像形狀
List<XSSFShape> shapes = drawing.getShapes();
//遍歷所有形狀
for (XSSFShape shape : shapes) {
//獲取形狀在工作表中的頂點位置信息(anchor錨點)
XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor();
//圖片形狀在工作表中的位置, 所在行列起點和終點位置
short c1 = anchor.getCol1();
int r1 = anchor.getRow1();
String key = r1 + "行," + c1 + "列";
if (shape instanceof XSSFPicture) {
try {
XSSFPicture pic = (XSSFPicture) shape;
//形狀獲取對應(yīng)的圖片數(shù)據(jù)
XSSFPictureData picData = pic.getPictureData();
//保存圖片到本地
byte[] data = picData.getData();
//TODO 這里上傳文件至oss并生成鏈接,這里不做過多描述,有疑問請參照oss服務(wù)調(diào)用
String fileName = "https://oss.cn/" + DateUtil.today() + "/" + IdUtil.simpleUUID() + "/" + picData.suggestFileExtension();
//fileTemplate.putObject(properties.getBucketName(), fileName, new ByteArrayInputStream(data));
//TODO 放入excel集合,這里行數(shù)要減去1,獲取圖片是從表頭開始(表頭位置為0),獲取excelVos是從數(shù)據(jù)開始(第一條數(shù)據(jù)位置為0)他們相差一個表頭,所以要減去1才能對應(yīng)
excelVos.get(r1 - 1).setPicture(fileName);
} catch (Exception e) {
log.error("asyncImportList XSSFClientAnchor key|{} error|{}", key, e.getMessage());
}
}
}
}
} catch (Exception e) {
log.error("asyncImportList XSSFWorkbook error|{}", e.getMessage());
}
}
/**
* 數(shù)據(jù)處理
*/
public void dataProcess(MultipartFile file, List<ExcelVo> excelVos) {
// 這里默認(rèn)讀取第一個sheet
try {
EasyExcel.read(file.getInputStream(), ExcelVo.class, new ReadListener() {
/**
* 單次緩存的數(shù)據(jù)量
*/
public static final int BATCH_COUNT = 100;
/**
*臨時存儲
*/
private List<ExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
@Override
public void invoke(Object object, AnalysisContext context) {
ExcelVo data = (ExcelVo) object;
cachedDataList.add(data);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存儲完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
}
/**
* 加上存儲數(shù)據(jù)庫
*/
private void saveData() {
log.info("已獲取數(shù)據(jù)|{}條", cachedDataList.size());
excelVos.addAll(cachedDataList);
}
}).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* 導(dǎo)入VO
*
* @author wss
*/
@Data
public class ExcelVo {
@ExcelProperty("序號")
private Integer ordinal;
@ExcelProperty("標(biāo)題")
private String title;
@ExcelProperty("圖片")
private String picture;
}
Excel 表格準(zhǔn)備
excel表頭需和實體字段相對應(yīng)

Postman 調(diào)用測試
打開圖片鏈接發(fā)現(xiàn)與excel中圖片一致,對應(yīng)數(shù)據(jù)一致,讀取圖片成功!

結(jié)尾
到這里,EasyExcel 導(dǎo)入帶圖片已完成!讀取圖片速度較慢,可以通過異步或其它方式優(yōu)化處理,根據(jù)自己需求修改即可,這里就不進(jìn)行說明了。
補充
項目中本人是通過@RequestExcel注解直接獲取的excel數(shù)據(jù),file專用于圖片讀取,即方法中不用再進(jìn)行數(shù)據(jù)處理,代碼更加簡化。
這篇文章主要是用來處理讀取圖片的,這里就不再詳細(xì)說明該注解了,感興趣的小伙伴可以查閱一下相關(guān)資料。
/**
* 數(shù)據(jù)導(dǎo)入并識別圖片
*
* @param file file
* @return R<Object>
* @author wss
*/
@PostMapping("/import")
public R<Object> dataImport(@RequestParam("file") MultipartFile file, @RequestExcel List<ExcelVo> excelVos) {
//圖像處理
this.imageProcess(file, excelVos);
//返回結(jié)果,這里也可以處理excelVos數(shù)據(jù),如往庫里存儲
return R.success(excelVos);
}到此這篇關(guān)于Java EasyExcel導(dǎo)入帶圖片的文章就介紹到這了,更多相關(guān)Java EasyExcel導(dǎo)入帶圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot中EasyExcel實現(xiàn)Excel文件的導(dǎo)入導(dǎo)出
- SpringBoot集成EasyExcel實現(xiàn)Excel導(dǎo)入的方法
- SpringBoot整合EasyExcel實現(xiàn)文件導(dǎo)入導(dǎo)出
- java使用EasyExcel導(dǎo)入導(dǎo)出excel
- Java+EasyExcel實現(xiàn)文件的導(dǎo)入導(dǎo)出
- EasyExcel實現(xiàn)導(dǎo)入+各種數(shù)據(jù)校驗功能
- Java使用EasyExcel實現(xiàn)Excel的導(dǎo)入導(dǎo)出
- Java使用easyExcel批量導(dǎo)入數(shù)據(jù)詳解
相關(guān)文章
Mybatis-flex整合達(dá)夢數(shù)據(jù)庫的實現(xiàn)示例
本文討論了國產(chǎn)達(dá)夢數(shù)據(jù)庫與Mybatis-flex框架的整合過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10
SpringBoot集成WebServlet出現(xiàn)自定義servlet請求失敗的問題解決方案
SpringBoot中以Bean方式注冊Servlet時遇到的問題,通過了解DispatcherServlet的原理,發(fā)現(xiàn)默認(rèn)路徑?jīng)_突是主要原因,本文介紹SpringBoot集成WebServlet出現(xiàn)自定義servlet請求失敗的問題解決方案,感興趣的朋友一起看看吧2025-03-03

