EasyExcel導入excel的分析監(jiān)聽器

相關依賴(pom):

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

AnalysisEventListener<T>:

public abstract class AnalysisEventListener<T> implements ReadListener<T> {
    // 這是監(jiān)聽器的構造方法,一般我們可以通過構造方法傳入一些我們需要在解析excel時使用的數(shù)據(jù)
    //(在這里,AnalysisEventListener<T>實現(xiàn)ReadListener<T>)
    public AnalysisEventListener() {}
    // 調用invokeHeadMap來獲取表頭數(shù)據(jù)
    public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
        this.invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
    }
    // 獲取表頭數(shù)據(jù)
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {}
    // 讀取條額外信息:批注、超鏈接、合并單元格信息等
    public void extra(CellExtra extra, AnalysisContext context) {}
    // 在轉換異常 獲取其他異常下會調用本接口。拋出異常則停止讀取。如果這里不拋出異常則 繼續(xù)讀取下一行。
    public void onException(Exception exception, AnalysisContext context) throws Exception {throw exception;}
    public boolean hasNext(AnalysisContext context) {return true;}
}

相關常用方法:

// 有個很重要的點 DemoDataListener 不能被spring管理,要每次讀取excel都要new,然后里面用到spring可以構造方法傳進去
public class DemoDataListener extends AnalysisEventListener<DemoData> {
    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
    //每隔5條存儲數(shù)據(jù)庫,實際使用中可以3000條,然后清理list ,方便內存回收
    private static final int BATCH_COUNT = 5;
    List<DemoData> list = new ArrayList<DemoData>();
    //假設這個是一個DAO,當然有業(yè)務邏輯這個也可以是一個service。當然如果不用存儲這個對象沒用。
    private DemoDAO demoDAO;
    public DemoDataListener() {
        // 這里是demo,所以隨便new一個。實際使用如果到了spring,請使用下面的有參構造函數(shù)
        demoDAO = new DemoDAO();
    }
    //如果使用了spring,請使用這個構造方法。每次創(chuàng)建Listener的時候需要把spring管理的類傳進來
    public DemoDataListener(DemoDAO demoDAO) {
        this.demoDAO = demoDAO;
    }
    // 這個每一條數(shù)據(jù)解析都會來調用
    @Override
    public void invoke(DemoData data, AnalysisContext context) {
        list.add(data);
        // 在這里進行相關操作 
        // 達到BATCH_COUNT了,需要去存儲一次數(shù)據(jù)庫,防止數(shù)據(jù)幾萬條數(shù)據(jù)在內存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存儲完成清理 list
            list.clear();
        }
    }
    // 所有數(shù)據(jù)解析完成了 都會來調用
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 這里也要保存數(shù)據(jù),確保最后遺留的數(shù)據(jù)也存儲到數(shù)據(jù)庫
        //saveData();
    }
    
    // 加上存儲數(shù)據(jù)庫
    private void saveData() {
        demoDAO.save(list);
    }

Excel表中存在額外信息時

    // 讀取條額外信息:批注、超鏈接、合并單元格信息等
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        LOGGER.info("讀取到了一條額外信息:{}", JSON.toJSONString(extra));
        switch (extra.getType()) {
            case COMMENT:
                LOGGER.info("額外信息是批注,在rowIndex:{},columnIndex;{},內容是:{}", extra.getRowIndex(), extra.getColumnIndex(),
                    extra.getText());
                break;
            case HYPERLINK:
                if ("Sheet1!A1".equals(extra.getText())) {
                    LOGGER.info("額外信息是超鏈接,在rowIndex:{},columnIndex;{},內容是:{}", extra.getRowIndex(),
                        extra.getColumnIndex(), extra.getText());
                } else if ("Sheet2!A1".equals(extra.getText())) {
                    LOGGER.info(
                        "額外信息是超鏈接,而且覆蓋了一個區(qū)間,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{},"
                            + "內容是:{}",
                        extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
                        extra.getLastColumnIndex(), extra.getText());
                } else {
                    Assert.fail("Unknown hyperlink!");
                }
                break;
            case MERGE:
                LOGGER.info(
                    "額外信息是超鏈接,而且覆蓋了一個區(qū)間,在firstRowIndex:{},firstColumnIndex;{},lastRowIndex:{},lastColumnIndex:{}",
                    extra.getFirstRowIndex(), extra.getFirstColumnIndex(), extra.getLastRowIndex(),
                    extra.getLastColumnIndex());
                break;
            default:
        }
    }
    
    //在轉換異常 獲取其他異常下會調用本接口。拋出異常則停止讀取。如果這里不拋出異常則 繼續(xù)讀取下一行。
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        // 如果是某一個單元格的轉換異常 能獲取到具體行號
        // 如果要獲取頭的信息 配合invokeHeadMap使用
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception;
            LOGGER.error("第{}行,第{}列解析異常", excelDataConvertException.getRowIndex(),
                excelDataConvertException.getColumnIndex());
        }
    }
}

代碼來源:EasyExcel(一)導入excel的分析監(jiān)聽器_Zack_tzh的博客-CSDN博客_easyexcel監(jiān)聽器

個人Demo:

public class DemoDateListener extends AnalysisEventListener<Demo>{
      private ststic final Logger LOGGER = LoggerFactory.getLogger(DemoDateListener.class);

      private static final BATCH_COUNT = 1;
      Demo demo = new Demo();
      int count = 0;
      boolean headFlag = false;//表頭標識
      boolean headFlag1 = false;//表頭標識
      boolean headFlag2 = false;//數(shù)字標識

      private DemoService demoService;
      public DemoListener(DemoService demoservice){
        this.demoService=demoService
      }
      public void invoke(Demo data, AnalysisContext context) {

        System.out.println(JSON.toJSONString(data));
        if (data.getTest() != null) {
            if (data.getTest().equals("實驗對象"))
                headFlag = true;
        }
        if (headFlag && headFlag1) {
            demo = data;
            demo.setExcelType("2");
            insertData();
        }
        if (data.getTest() != null) {
            if (data.getTest().equals("實驗對象") || data.getTest().equals("實驗對象"))
                headFlag1 = true;
        }
    }
       public void doAfterAllAnalysed(AnalysisContext context) {
        LOGGER.info("所有數(shù)據(jù)解析完成!");
       }
      private void insertData() {
    }
}

按照需求不同,建立對應的listener。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容