如何高效讀寫百萬級的Excel?

高效讀取百萬級數據

上一篇介紹的高效寫文件之后,最近抽時間研究了下Excel文件的讀取。概括來講,poi讀取excel有兩種方式:用戶模式和事件模式

然而很多業務場景中的讀取Excel仍然采用用戶模式,但是這種模式需要創建大量對象,對大文件的支持非常不友好,非常容易OOM。但是對于事件模式而言,往往需要自己實現listener,并且需要根據自己需要解析不同的event,所以用起來比較復雜。

<font color = "red">基于此,EasyExcel封裝了常用的Excel格式文檔的事件解析,并且提供了接口供開發小哥擴展定制化,實現讓你解析Excel不再費神的目的。</font>

Talk is cheap, show me the code.

使用姿勢

pom

    <groupId>com.github.Dorae132</groupId>
<artifactId>easyutil.easyexcel</artifactId>
<version>1.1.0</version>

普通姿勢

看看下邊的姿勢,是不是覺得只需要關心業務邏輯了

ExcelUtils.excelRead(ExcelProperties.produceReadProperties("C:\\Users\\Dorae\\Desktop\\ttt\\",
            "append_0745704108fa42ffb656aef983229955.xlsx"), new IRowConsumer<String>() {
                @Override
                public void consume(List<String> row) {
                    System.out.println(row);
                    count.incrementAndGet();
                    try {
                        TimeUnit.MICROSECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }, new IReadDoneCallBack<Void>() {
                @Override
                public Void call() {
                    System.out.println(
                            "end, count: " + count.get() + "\ntime: " + (System.currentTimeMillis() - start));
                    return null;
                }
            }, 3, true);

定制姿勢

什么?你想定制context,添加handler?請看下邊!你只需要實現一個Abstract03RecordHandler然后regist到context(關注ExcelVersionEnums中的factory)就可以了。

public static void excelRead(IHandlerContext context, IRowConsumer rowConsumer, IReadDoneCallBack callBack,
        int threadCount, boolean syncCurrentThread) throws Exception {
    // synchronized main thread
    CyclicBarrier cyclicBarrier = null;
    threadCount = syncCurrentThread ? ++threadCount : threadCount;
    if (callBack != null) {
        cyclicBarrier = new CyclicBarrier(threadCount, () -> {
            callBack.call();
        });
    } else {
        cyclicBarrier = new CyclicBarrier(threadCount);
    }
    for (int i = 0; i < threadCount; i++) {
        THREADPOOL.execute(new ConsumeRowThread(context, rowConsumer, cyclicBarrier));
    }
    context.process();
    if (syncCurrentThread) {
        cyclicBarrier.await();
    }
}

框架結構

如圖,為整個EasyExcel的結構,其中(如果了解過設計模式,或者讀過相關源碼,應該會很容易理解):

  1. 綠色為可擴展接口,
  2. 上半部分為寫文件部分,下辦部分為讀文件。
圖 1-1

總結

至此,EasyExcel的基本功能算是晚上了,歡迎各路大神提Issue過來。??

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,514評論 1 92
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,081評論 6 13
  • Swift1> Swift和OC的區別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,132評論 1 32
  • 東方的朝霞奮力升騰 掙脫地平線的黑暗 使我們熱血沸騰 樹上的鳥兒歌聲那么療亮 使的早起的人們心情舒暢 早飛的鳥兒有...
    山東聊城李超閱讀 359評論 1 2
  • 體驗入:不論發生什么事,遇到什么困境,一定要堅定信念,尋找方法! 找核心:利用資源! 轉身用:不論最后的結果是否完...
    命運我手中明天會更好閱讀 71評論 0 0