国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Alibaba工具型技術(shù)系列】「EasyExcel技術(shù)專題」實(shí)戰(zhàn)研究一下 EasyExcel 如何從指定文件位置進(jìn)行讀取數(shù)據(jù)

這篇具有很好參考價(jià)值的文章主要介紹了【Alibaba工具型技術(shù)系列】「EasyExcel技術(shù)專題」實(shí)戰(zhàn)研究一下 EasyExcel 如何從指定文件位置進(jìn)行讀取數(shù)據(jù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

EasyExcel的使用背景

工作中總會(huì)遇到對(duì)Excel讀寫功能,之前接觸過(guò)EasyExcel,后續(xù)我們基本上用它代替了傳統(tǒng)的POI和JXL、甚至還有一個(gè)EasyPOI技術(shù)。

EasyExcel的時(shí)候痛點(diǎn)

使用的EasyExcel時(shí)候,一般場(chǎng)景下表頭比較傳統(tǒng),也不復(fù)雜,但是這次呢表頭稍微有點(diǎn)復(fù)雜,讀取數(shù)據(jù)要從指定的位置開(kāi)始,要從指定位置開(kāi)始讀取EasyExcel,所以呢在不斷的摸索之后,找到了合適的解決方法。

EasyExcel對(duì)比其他框架

平常用poi讀取excel數(shù)據(jù)量少,加上EasyExcel讀取Excel有點(diǎn)復(fù)雜,所以一直也沒(méi)在項(xiàng)目中使用EasyExcel,直到有一回要讀取的數(shù)據(jù)量太大,使用poi讀取Excel在創(chuàng)建Workbook -> WorkbookFactory.create(inputStream) 時(shí)就異常了,分配很多內(nèi)存也不好使,所以放棄使用poi轉(zhuǎn)使用EasyExcel。

Java解析、生成Excel比較有名的框架有Apache poi、jxl。但他們都存在一個(gè)嚴(yán)重的問(wèn)題就是非常的耗內(nèi)存,poi有一套SAX模式的API可以一定程度的解決一些內(nèi)存溢出的問(wèn)題,但POI還是有一些缺陷,比如07版Excel解壓縮以及解壓后存儲(chǔ)都是在內(nèi)存中完成的,內(nèi)存消耗依然很大。easyexcel重寫了poi對(duì)07版Excel的解析,能夠原本一個(gè)3M的excel用POI sax依然需要100M左右內(nèi)存降低到幾M,并且再大的excel不會(huì)出現(xiàn)內(nèi)存溢出,03版依賴POI的sax模式。

在上層做了模型轉(zhuǎn)換的封裝,讓使用者更加簡(jiǎn)單方便 --EasyExcel
使用EasyExcel讀取Excel時(shí)一直在想如何簡(jiǎn)化讀取方式,不用讀取每個(gè)Excel都創(chuàng)建一個(gè)XXDataListene監(jiān)聽(tīng)器類,剛開(kāi)始想,把DataListener加上泛型,共用一個(gè)DataListener,但是還涉及到如何傳遞Dao和每個(gè)Dao如何保存數(shù)據(jù),而且保存數(shù)據(jù)前可能還需要對(duì)數(shù)據(jù)進(jìn)行不同的處理。

EasyExcel的編程模式

EasyExcel開(kāi)源挺久了,但使用上感覺(jué)有點(diǎn)讓人望而生怯,剛開(kāi)始看官方文檔上讀取Excel挺簡(jiǎn)單的,只需要一行代碼,繼續(xù)細(xì)看的話還需要?jiǎng)?chuàng)建一個(gè)回調(diào)監(jiān)聽(tīng)器,有點(diǎn)復(fù)雜呀(每個(gè)Excel都需要?jiǎng)?chuàng)建一個(gè)單獨(dú)的回調(diào)監(jiān)聽(tīng)器類)。

EasyExcel讀取的指定位置

要開(kāi)始讀取數(shù)據(jù),第8行才是真正的數(shù)據(jù),直接上代碼,headRowNumber(),不寫默認(rèn)是1,即就是從第二行開(kāi)始讀數(shù)據(jù)。

    /**
     * 讀取文件信息數(shù)據(jù)
     * @param filePath
     * @param headNum
     */
    public ContactInfoExcelDataListener read(String filePath , int headNum){
        EasyExcel.read(filePath, this).head(ContactInfoExcelEntity.class).autoCloseStream(true
                ).autoTrim(true).ignoreEmptyRow(true).sheet()
                // 這里可以設(shè)置1,因?yàn)轭^就是一行。如果多行頭,可以設(shè)置其他值。不傳入也可以,因?yàn)槟J(rèn)會(huì)根據(jù)DemoData 來(lái)解析,他沒(méi)有指定頭,也就是默認(rèn)1行
                .headRowNumber(Math.max(headNum,NumberUtils.BYTE_ZERO)).doRead();
        return this;
    }

    /**
     * 讀取文件信息數(shù)據(jù)
     * @param filePath
     */
    public ContactInfoExcelDataListener read(String filePath){
        EasyExcel.read(filePath, this).head(ContactInfoExcelEntity.class).autoCloseStream(true).autoTrim(true).ignoreEmptyRow(true).sheet()
                // 這里可以設(shè)置1,因?yàn)轭^就是一行。如果多行頭,可以設(shè)置其他值。不傳入也可以,因?yàn)槟J(rèn)會(huì)根據(jù)DemoData 來(lái)解析,他沒(méi)有指定頭,也就是默認(rèn)1行
               .doRead();
        return this;
    }

    /**
     * 讀取文件信息數(shù)據(jù)
     * @param inputStream
     * @param headNum
     */
    public ContactInfoExcelDataListener read(InputStream inputStream, int headNum){
        EasyExcel.read(inputStream, this).head(ContactInfoExcelEntity.class).autoCloseStream(true).autoTrim(true).ignoreEmptyRow(true).sheet()
                // 這里可以設(shè)置1,因?yàn)轭^就是一行。如果多行頭,可以設(shè)置其他值。不傳入也可以,因?yàn)槟J(rèn)會(huì)根據(jù)DemoData 來(lái)解析,他沒(méi)有指定頭,也就是默認(rèn)1行
                .headRowNumber(Math.max(headNum,NumberUtils.BYTE_ZERO)).doRead();
        return this;
    }
導(dǎo)入數(shù)據(jù)的流程

基本都會(huì)走到這里,全部放權(quán)交接給invoke方法,并且巧用作為我們鎖初始化操作的控制賦值,切記如果headNum = 0 此方法很有可能不會(huì)觸發(fā),慎用!

表頭校驗(yàn)

目前只是實(shí)現(xiàn)了相關(guān)的單節(jié)點(diǎn)同步鎖,如果未來(lái)擴(kuò)展了相關(guān)的分布式節(jié)點(diǎn),需要采用分布式鎖機(jī)制進(jìn)行控制!鎖范圍需要進(jìn)行控制

invokeHeadMap()方法

    /**
     * 調(diào)用頭部
     * @param map
     * @param analysisContext
     */
    @Override
    public void invokeHead(Map<Integer, CellData> map, AnalysisContext analysisContext) {
        log.info("【start read the excel head data】:{}",map);// 判斷標(biāo)記頭是否存在

        try {
            int titleRows = map.size();
            // 頭部的中斷處理機(jī)制!
            failureDataCount = preValidate?orginalHead.size() != titleRows?NumberUtils.INTEGER_ONE:
                    NumberUtils.BYTE_ZERO:NumberUtils.BYTE_ZERO;
            // 進(jìn)行置位
            if(preValidate && (failureDataCount.intValue() == NumberUtils.INTEGER_ONE)){
                causeByHeadFormatAbort = Boolean.TRUE;
            }
            if(!isMockFlag) {
                // TODO 基本不會(huì)走到這里:一般我們?nèi)绻枰梢允褂么朔椒ㄗ鳛槌跏蓟Y源使用的目的!
                //Preconditions.checkNotNull(clueLogic,"not support clueLogic is inject this class subject!");
                if (Objects.isNull(clueLogic)) {
                    clueLogic = SpringUtils.getBean(ClueLogic.class);
                }
                customerImportVO = new CustomerImportVO();
                // 此部分主要是為了減少不必要的內(nèi)存空間的申請(qǐng)
                tempDataList = Lists.newArrayListWithExpectedSize(batchSizeUnit);
            }
//            syncLockController.lock();
        } catch (Exception e) {
            log.error("invoke the analysis the title head info data is failure!",e);
            throw new UnsupportedOperationException("invoke the analysis the title head info data is failure!",e);
        }
        log.info("【finished read the excel head data】");
    }
數(shù)據(jù)處理
invoke()方法

一條一條數(shù)據(jù)解析 invoke()方法 ,方法里面是我業(yè)務(wù)邏輯,數(shù)據(jù)校驗(yàn)。invoke 就是每行具體的數(shù)據(jù)值

    /**
     * 調(diào)用操作處理控制機(jī)制
     * @param excelEntity
     * @param context
     */
    @Override
    public void invoke(ContactInfoExcelEntity excelEntity, AnalysisContext context) {
        log.info("----【start read the excel main data:{}】----",excelEntity);
        if(batchSizeUnit <= tempDataList.size()){
            CustomerImportVO customerImportVO = clueLogic.startCallTaskProxy(contactInfoImportParam,tempDataList);
            // 合并計(jì)算結(jié)果->更新為最新的結(jié)果
            this.customerImportVO.merge(customerImportVO);
            tempDataList.clear();
            tempDataList = Lists.newArrayListWithExpectedSize(batchSizeUnit);
        }else{
            tempDataList.add(excelEntity);
        }
        log.info("【finished read the excel main data】");
    }
執(zhí)行中斷
hasNextdoAfterAllAnalysed()方法
    /**
     * 是否擁有下一次執(zhí)行
     * [@param](https://my.oschina.net/u/2303379) context
     * [@return](https://my.oschina.net/u/556800)
     */
    [@Override](https://my.oschina.net/u/1162528)
    public boolean hasNext(AnalysisContext context) {
        return causeByHeadFormatAbort?Boolean.FALSE:isSupportAbort? failureDataCount <= 0 :Boolean.TRUE;
    }
數(shù)據(jù)完成
doAfterAllAnalysed()方法

所有數(shù)據(jù)解析完, doAfterAllAnalysed()方法,里面寫的有保存數(shù)據(jù)方法。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-811190.html

    /**
     * 執(zhí)行結(jié)束的回調(diào)機(jī)制
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("【doAfterAllAnalysed the process】");
        try {
            CustomerImportVO customerImportVO = clueLogic.startCallTaskProxy(contactInfoImportParam,tempDataList);
            this.customerImportVO.merge(customerImportVO);
            finisheDataResult = Boolean.TRUE;
        }catch (Exception e){
            log.error("execute finially the flush data is failure!");
            //TODO 收尾的數(shù)據(jù)信息如何做到一致性和完成補(bǔ)償!
            finisheDataResult =  Boolean.FALSE;
        } finally {
            tempDataList.clear();
//            syncLockController.unlock();
        }
    }

總結(jié)一下

  • 快速讀寫:EasyExcel 支持 Excel 2003 和 Excel 2007 格式,并提供高效的讀寫性能。它使用了 NIO(新輸入/輸出)技術(shù),使得讀寫操作更加快速。
  • 簡(jiǎn)單易用:EasyExcel 的 API 設(shè)計(jì)簡(jiǎn)潔明了,易于使用。開(kāi)發(fā)者只需編寫少量代碼,即可完成 Excel 文件的讀寫操作。它還支持鏈?zhǔn)骄幊?,使代碼更加簡(jiǎn)潔。
  • 支持自定義:EasyExcel 提供了豐富的自定義選項(xiàng),允許開(kāi)發(fā)者根據(jù)需要調(diào)整 Excel 文件的格式、樣式等。它還支持自定義公式、條件格式等功能,滿足各種業(yè)務(wù)需求。
  • 靈活的配置:EasyExcel 支持多種配置方式,如屬性配置、注解配置等。開(kāi)發(fā)者可以根據(jù)項(xiàng)目需求選擇合適的配置方式,使得 Excel 文件的處理更加靈活。

到了這里,關(guān)于【Alibaba工具型技術(shù)系列】「EasyExcel技術(shù)專題」實(shí)戰(zhàn)研究一下 EasyExcel 如何從指定文件位置進(jìn)行讀取數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包