爲獲取導入百分比,使用easyexcel獲取導入excel表總行數

背景

分批讀取大量數據的excel文件,每次讀取1000行數據,然後插入數據庫,並且去執行一個方法,執行完畢後更新此行數據的狀態。需要獲取已更新數據的佔比,即計算百分比。

因爲是分批讀取的,我們不可以直接用已更新狀態數量/數據庫中總數。因爲可能一次讀取的1000行數據更新狀態很快,直接1000/1000 * 100=100%了。

但實際上excel文件中實際有1w行數據,那麼我們要獲取excel的總行數。

方法

使用easyexcel獲取總行數,記錄一下,

在創建監聽器時,重寫invoke方法時,使用下面代碼獲取總行數(含表頭):

public void invoke(DemoData data, AnalysisContext context) {
// 獲取總行數(含表頭)
Integer rowNumber = context.readSheetHolder().getApproximateTotalRowNumber();
}

目前只能獲取大概的條數(每個excel都會記錄一個總條數,但是這個總條數由於各種空行等原因,不一定正確),無法精確獲取,要精確獲取的自己在監聽器裏面一條條統計

監聽器舉例:

// 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然後裏面用到spring可以構造方法傳進去
@Slf4j
public class DemoDataListener implements AnalysisEventListener<DemoData> {

/**
* 批處理閾值100
*/
private static final int BATCH_COUNT = 100;
/**
* 緩存的數據
*/
private List<DemoData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
* 假設這個是一個DAO,當然有業務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。
*/
private DemoDAO demoDAO;

public DemoDataListener() {
// 這裏是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數
demoDAO = new DemoDAO();
}

/**
* 如果使用了spring,請使用這個構造方法。每次創建Listener的時候需要把spring管理的類傳進來
*
* @param demoDAO
*/
public DemoDataListener(DemoDAO demoDAO) {
this.demoDAO = demoDAO;
}

/**
* 這個每一條數據解析都會來調用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(DemoData data, AnalysisContext context) {
Integer rowNumber = analysisContext.readSheetHolder().getApproximateTotalRowNumber();
// 設置execl最多2000行(含表頭)
if (rowNumber > 2000) {
throw new ExcelAnalysisException("超出總行數限制,總行數爲:" + rowNumber);
}
log.info("解析到一條數據:{}", JSON.toJSONString(data));
cachedDataList.add(data);
// 達到BATCH_COUNT了,需要去存儲一次數據庫,防止數據幾萬條數據在內存,容易OOM
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// 存儲完成清理 list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}

/**
* 所有數據解析完成了 都會來調用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 這裏也要保存數據,確保最後遺留的數據也存儲到數據庫
saveData();
log.info("所有數據解析完成!");
}

/**
* 加上存儲數據庫
*/
private void saveData() {
log.info("{}條數據,開始存儲數據庫!", cachedDataList.size());
demoDAO.save(cachedDataList);
log.info("存儲數據庫成功!");
}
}

  

本篇文章如有幫助到您,請給「翎野君」點個贊,感謝您的支持。

首發鏈接: https://www.cnblogs.com/lingyejun/p/17866220.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章