Java POI讀取大型Excel文件速度慢如何優(yōu)化?

Java POI讀取大型Excel文件速度慢如何優(yōu)化?

Java POI處理大型excel文件效率優(yōu)化策略

使用Java POI處理大型Excel文件時(shí),常常面臨讀取速度緩慢的問題,甚至可能導(dǎo)致內(nèi)存溢出錯(cuò)誤。這是因?yàn)镻OI默認(rèn)將整個(gè)文件加載到內(nèi)存中。本文將介紹兩種主流優(yōu)化方法,有效提升大型Excel文件讀取效率。

核心問題:內(nèi)存占用過高

POI默認(rèn)加載整個(gè)Excel文件到內(nèi)存,大型文件會(huì)導(dǎo)致內(nèi)存占用過高,嚴(yán)重影響讀取速度,甚至引發(fā)OutOfMemoryError。因此,需要采用分段讀取策略,避免一次性加載整個(gè)文件。

立即學(xué)習(xí)Java免費(fèi)學(xué)習(xí)筆記(深入)”;

優(yōu)化方案:

方案一:使用xlsx-streamer庫(kù)實(shí)現(xiàn)分段讀取

xlsx-streamer基于POI,通過分段緩存機(jī)制,將數(shù)據(jù)分批加載到內(nèi)存,顯著降低內(nèi)存占用。它在創(chuàng)建Workbook對(duì)象時(shí)使用StreamingReader創(chuàng)建緩沖區(qū),批量讀取文件內(nèi)容。

首先,引入xlsx-streamer和poi-ooxml依賴:

<dependency>     <groupId>org.apache.poi</groupId>     <artifactId>poi-ooxml</artifactId>     <version>${poi.version}</version> </dependency> <dependency>     <groupId>com.monitorjbl</groupId>     <artifactId>xlsx-streamer</artifactId>     <version>2.1.0</version> </dependency>

以下代碼演示如何使用xlsx-streamer讀取大型Excel文件:

public static void readLargeExcel(File file) throws Exception {     InputStream inputStream = new FileInputStream(file);     long start = System.currentTimeMillis();     try (Workbook workbook = StreamingReader.builder()             .rowCacheSize(10000) // 緩存行數(shù)             .bufferSize(4096)    // 緩沖區(qū)大小             .open(inputStream)) {          Sheet sheet = workbook.getSheetAt(0);         log.info("Excel讀取完成,耗時(shí):{}毫秒", System.currentTimeMillis() - start);         for (Row row : sheet) {             System.out.println("讀取第" + row.getRowNum() + "行數(shù)據(jù):");             for (Cell cell : row) {                 System.out.print(cell.getStringCellValue() + " ");             }             System.out.println();         }         System.out.println("讀取結(jié)束行數(shù):" + sheet.getLastRowNum());     } }

在處理數(shù)十萬行數(shù)據(jù)時(shí),此方法能顯著縮短讀取時(shí)間。

方案二:使用EasyExcel庫(kù)

EasyExcel是阿里巴巴開源的高效Excel處理工具,基于POI進(jìn)行了優(yōu)化,有效避免大文件讀取內(nèi)存溢出。它提供簡(jiǎn)潔的API,方便進(jìn)行讀寫操作。

添加EasyExcel依賴:

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

以下代碼演示如何使用EasyExcel讀取Excel文件,提供兩種讀取方式:對(duì)象封裝map讀?。?/p>

public static void readExcelByEasyExcel(File file) {     long start = System.currentTimeMillis();     List<ExcelData> excelDataList = EasyExcel.read(file).head(ExcelData.class).sheet(0).doReadSync();     excelDataList.forEach(System.out::println);     log.info("Excel讀取完成,耗時(shí):{}毫秒", System.currentTimeMillis() - start); }  public static void readExcelByEasyExcel1(File file) {     long start = System.currentTimeMillis();     List<Map<String, Object>> listMap = EasyExcel.read(file).sheet(0).doReadSync();     listMap.forEach(x -> System.out.println(JSON.toJSONString(x)));     log.info("Excel讀取完成,耗時(shí):{}毫秒", System.currentTimeMillis() - start); }

選擇哪種方案取決于具體需求和項(xiàng)目環(huán)境。xlsx-streamer側(cè)重于POI增強(qiáng),EasyExcel提供更全面的功能和更友好的API。 根據(jù)實(shí)際情況選擇最合適的方案。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊11 分享