讀取代碼
// 前端傳過來的文件
MultipartFile file;
InputStream inputStream = file.getInputStream();
// 讀取excel數據,邊讀取邊處理;
EasyExcel.read(inputStream, ImportSkuIdList.class, new SkuIdExceListener(sendCouponCusRecordService)).sheet().doRead();
解析對象
public class ImportSkuIdList{
@ExcelProperty(index = 0)
/** 商品編號*/
private Long skuId;
// 省略get set
....
}
Listener
public class SkuIdExceListener extends AnalysisEventListener<ImportSkuIdList> {
private static final Logger LOGGER = LoggerFactory.getLogger(SkuIdExceListener.class);
// spring的方式需要通過構造函數傳進來
private SendCouponCusRecordService sendCouponCusRecordService;
/**
* 每隔100條存儲數據庫,實際使用中可以3000條,然后清理list ,方便內存回收
*/
private static final int BATCH_COUNT = 100;
private volatile int totalCount = 0;
List<ImportSkuIdList> list = new ArrayList<>();
/**
* 如果使用了spring,請使用這個構造方法。每次創建Listener的時候需要把spring管理的類傳進來
*
*/
public SkuIdExceListener(SendCouponCusRecordService sendCouponCusRecordService) {
this.sendCouponCusRecordService = sendCouponCusRecordService;
}
/**
* 這個每一條數據解析都會來調用
*
* @param data
* one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(ImportSkuIdList data, AnalysisContext context) {
totalCount ++;
list.add(data);
// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
if (list.size() >= BATCH_COUNT) {
dealData(context);
// 存儲完成清理 list
list.clear();
}
}
/**
* 所有數據解析完成了 都會來調用
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 這里也要保存數據,確保最后遺留的數據也存儲到數據庫
dealData(context);
LOGGER.info("所有數據解析完成!");
}
/**
* 加上存儲數據庫
*/
private void dealData(AnalysisContext context) {
LOGGER.info("當前正在處理第[{}]行數據,本次處理[{}]條數據,總共有:{}條數據",context.readRowHolder().getRowIndex(),list.size(),totalCount);
// 實際處理邏輯
sendCouponCusRecordService.dealUploadData(list);
}
}