接上一篇介紹的高效寫文件以後,最近抽時間研究了下Excel文件的讀取。歸納來說,poi讀取excel有兩種方式:用戶模式和事件模式。html
然而不少業務場景中的讀取Excel仍然採用用戶模式,可是這種模式須要建立大量對象,對大文件的支持很是不友好,很是容易OOM。可是對於事件模式而言,每每須要本身實現listener,而且須要根據本身須要解析不一樣的event,因此用起來比較複雜。git
基於此,EasyExcel封裝了經常使用的Excel格式文檔的事件解析,而且提供了接口供開發小哥擴展定製化,實現讓你解析Excel再也不費神的目的。github
Talk is cheap, show me the code.設計模式
<groupId>com.github.Dorae132</groupId>
<artifactId>easyutil.easyexcel</artifactId>
<version>1.1.0</version>
複製代碼
看看下邊的姿式,是否是以爲只須要關心業務邏輯了?app
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的結構,其中(若是瞭解過設計模式,或者讀過相關源碼,應該會很容易理解):ide
至此,EasyExcel的基本功能算是晚上了,歡迎各路大神提Issue過來。🍗spa