最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java EasyExcel導(dǎo)出報(bào)內(nèi)存溢出的解決辦法

 更新時(shí)間:2024年10月28日 12:06:26   作者:威哥愛編程  
使用EasyExcel進(jìn)行大數(shù)據(jù)量導(dǎo)出時(shí)容易導(dǎo)致內(nèi)存溢出,特別是在導(dǎo)出百萬級(jí)別的數(shù)據(jù)時(shí),你有遇到過這種情況嗎,以下是小編整理的解決該問題的一些常見方法,需要的朋友可以參考下

EasyExcel大數(shù)據(jù)量導(dǎo)出常見方法

1. 分批寫入

  • EasyExcel支持分批寫入數(shù)據(jù),可以將數(shù)據(jù)分批加載到內(nèi)存中,分批寫入Excel文件,避免一次性將大量數(shù)據(jù)加載到內(nèi)存中。
  • 示例代碼
     String fileName = "large_data.xlsx";
     ExcelWriter excelWriter = EasyExcel.write(fileName).build();
     WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();

     // 假設(shè)每次寫入10000條數(shù)據(jù)
     int batchSize = 10000;
     List<Data> dataList;
     int pageIndex = 0;
     do {
         // 分頁獲取數(shù)據(jù)
         dataList = getDataByPage(pageIndex++, batchSize);
         excelWriter.write(dataList, writeSheet);
     } while (dataList.size() == batchSize);

     // 關(guān)閉資源
     excelWriter.finish();

2. 設(shè)置合適的JVM內(nèi)存

  • 針對(duì)大數(shù)據(jù)導(dǎo)出場(chǎng)景,可以嘗試增大JVM的內(nèi)存分配,例如:
java -Xms512M -Xmx4G -jar yourApp.jar
  • 解釋
    • -Xms512M:設(shè)置初始堆大小為512MB。
    • -Xmx4G:設(shè)置最大堆大小為4GB。

3. 減少數(shù)據(jù)對(duì)象的復(fù)雜性

  • 導(dǎo)出數(shù)據(jù)時(shí),盡量簡(jiǎn)化數(shù)據(jù)對(duì)象,避免不必要的嵌套和多余字段的加載,以減少對(duì)象占用的內(nèi)存空間。

4. 關(guān)閉自動(dòng)列寬設(shè)置

  • EasyExcel的自動(dòng)列寬功能會(huì)占用大量?jī)?nèi)存,特別是在數(shù)據(jù)量較大的情況下。關(guān)閉自動(dòng)列寬可以節(jié)省內(nèi)存。
  • 示例代碼
     EasyExcel.write(fileName)
             .registerWriteHandler(new SimpleWriteHandler()) // 不使用自動(dòng)列寬
             .sheet("Sheet1")
             .doWrite(dataList);

5. 使用Stream導(dǎo)出(適合大數(shù)據(jù))

  • 利用OutputStream分批寫入數(shù)據(jù),減少內(nèi)存消耗。通過BufferedOutputStream可以進(jìn)一步提高性能。
  • 示例代碼
     try (OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName))) {
         ExcelWriter excelWriter = EasyExcel.write(out).build();
         WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();
         int pageIndex = 0;
         List<Data> dataList;
         do {
             dataList = getDataByPage(pageIndex++, batchSize);
             excelWriter.write(dataList, writeSheet);
         } while (dataList.size() == batchSize);
         excelWriter.finish();
     } catch (IOException e) {
         e.printStackTrace();
     }

6. 選擇合適的數(shù)據(jù)導(dǎo)出工具

  • 如果數(shù)據(jù)量非常大,可以考慮切換到支持更高性能的導(dǎo)出工具(如Apache POI的SXSSFWorkbook),適合導(dǎo)出百萬級(jí)別數(shù)據(jù)量,但配置和使用會(huì)更復(fù)雜。

亮點(diǎn)來了,那要如何使用 POI 的 SXSSFWorkbook來導(dǎo)出百萬級(jí)別的數(shù)據(jù)量呢?

Apache POI的SXSSFWorkbook 實(shí)現(xiàn)百萬級(jí)別數(shù)據(jù)量的導(dǎo)出案例

使用Apache POI的SXSSFWorkbook可以處理大數(shù)據(jù)量的Excel導(dǎo)出,因?yàn)?code>SXSSFWorkbook基于流式寫入,不會(huì)將所有數(shù)據(jù)加載到內(nèi)存中,而是使用臨時(shí)文件進(jìn)行緩存,這樣可以顯著減少內(nèi)存消耗,適合百萬級(jí)別數(shù)據(jù)的導(dǎo)出。下面我們來看一個(gè)完整的實(shí)現(xiàn)示例。

代碼如下

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class LargeDataExportExample {

    public static void main(String[] args) {
        // 文件輸出路徑
        String filePath = "vg_large_data_export.xlsx";
        
        // 導(dǎo)出百萬級(jí)數(shù)據(jù)
        exportLargeData(filePath);
    }

    private static void exportLargeData(String filePath) {
        // 每次寫入的批次大小
        final int batchSize = 10000;
        // 數(shù)據(jù)總條數(shù)
        final int totalRows = 1_000_000;

        // 創(chuàng)建SXSSFWorkbook對(duì)象,內(nèi)存中只保留100行,超過的部分會(huì)寫入臨時(shí)文件
        SXSSFWorkbook workbook = new SXSSFWorkbook(100);
        workbook.setCompressTempFiles(true); // 啟用臨時(shí)文件壓縮

        // 創(chuàng)建工作表
        Sheet sheet = workbook.createSheet("Large Data");

        // 創(chuàng)建標(biāo)題行
        Row headerRow = sheet.createRow(0);
        String[] headers = {"ID", "Name", "Age"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }

        int rowNum = 1; // 數(shù)據(jù)開始的行號(hào)

        try {
            // 按批次寫入數(shù)據(jù)
            for (int i = 0; i < totalRows / batchSize; i++) {
                // 模擬獲取每批數(shù)據(jù)
                List<Data> dataList = getDataBatch(rowNum, batchSize);
                
                // 將數(shù)據(jù)寫入到Excel中
                for (Data data : dataList) {
                    Row row = sheet.createRow(rowNum++);
                    row.createCell(0).setCellValue(data.getId());
                    row.createCell(1).setCellValue(data.getName());
                    row.createCell(2).setCellValue(data.getAge());
                }

                // 處理完成一批數(shù)據(jù)后,可以選擇清除緩存數(shù)據(jù),防止內(nèi)存溢出
                ((SXSSFSheet) sheet).flushRows(batchSize); // 清除已寫的行緩存
            }

            // 將數(shù)據(jù)寫入文件
            try (FileOutputStream fos = new FileOutputStream(filePath)) {
                workbook.write(fos);
            }
            System.out.println("數(shù)據(jù)導(dǎo)出完成:" + filePath);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 關(guān)閉workbook并刪除臨時(shí)文件
            workbook.dispose();
        }
    }

    /**
     * 模擬分頁獲取數(shù)據(jù)
     */
    private static List<Data> getDataBatch(int startId, int batchSize) {
        List<Data> dataList = new ArrayList<>(batchSize);
        for (int i = 0; i < batchSize; i++) {
            dataList.add(new Data(startId + i, "Name" + (startId + i), 20 + (startId + i) % 50));
        }
        return dataList;
    }

    // 數(shù)據(jù)類
    static class Data {
        private final int id;
        private final String name;
        private final int age;

        public Data(int id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }
    }
}

來解釋一下代碼

  • SXSSFWorkbookSXSSFWorkbook(100)表示內(nèi)存中最多保留100行數(shù)據(jù),超過的部分會(huì)寫入臨時(shí)文件,節(jié)省內(nèi)存。
  • 批次處理:通過batchSize控制每批次寫入的數(shù)據(jù)量,以減少內(nèi)存消耗。totalRows設(shè)置為1,000,000表示導(dǎo)出100萬條數(shù)據(jù)。
  • 模擬數(shù)據(jù)生成getDataBatch方法模擬分頁獲取數(shù)據(jù),每次返回一批數(shù)據(jù)。
  • 清除緩存行:每次寫入一批數(shù)據(jù)后,通過flushRows(batchSize)將緩存的行從內(nèi)存中清除,以控制內(nèi)存占用。
  • 壓縮臨時(shí)文件workbook.setCompressTempFiles(true)啟用臨時(shí)文件壓縮,進(jìn)一步減少磁盤空間占用。

需要注意的事項(xiàng)

  • 臨時(shí)文件:SXSSFWorkbook會(huì)在系統(tǒng)臨時(shí)文件夾中生成臨時(shí)文件,需要確保磁盤空間足夠。
  • 資源釋放:完成數(shù)據(jù)寫入后需要調(diào)用workbook.dispose()以清理臨時(shí)文件。
  • 性能優(yōu)化:可根據(jù)機(jī)器內(nèi)存調(diào)整batchSizeSXSSFWorkbook緩存行數(shù),避免頻繁刷新和內(nèi)存溢出。

以上就是Java EasyExcel導(dǎo)出報(bào)內(nèi)存溢出的解決辦法的詳細(xì)內(nèi)容,更多關(guān)于Java EasyExcel導(dǎo)出內(nèi)存溢出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mybatisplus如何存儲(chǔ)List、Map

    Mybatisplus如何存儲(chǔ)List、Map

    這篇文章主要介紹了Mybatisplus如何存儲(chǔ)List、Map問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 淺談java線程join方法使用方法

    淺談java線程join方法使用方法

    這篇文章主要介紹了淺談java線程join方法使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 在maven中引入本地jar包的步驟

    在maven中引入本地jar包的步驟

    這篇文章主要介紹了在maven中引入本地jar包的步驟,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Spring配置文件的超詳細(xì)圖文介紹

    Spring配置文件的超詳細(xì)圖文介紹

    Spring配置文件是一個(gè)或多個(gè)標(biāo)準(zhǔn)的XML文檔,下面這篇文章主要給大家介紹了關(guān)于Spring配置文件的超詳細(xì)圖文介紹,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • SpringBoot 集成消息隊(duì)列實(shí)戰(zhàn)指南(RabbitMQ/Kafka):異步通信與解耦,落地高可靠消息傳遞

    SpringBoot 集成消息隊(duì)列實(shí)戰(zhàn)指南(RabbitMQ/Kafka):異步通信與解耦,落地高可靠消息傳遞

    本文介紹了SpringBoot集成RabbitMQ與Kafka的實(shí)戰(zhàn),涵蓋生產(chǎn)者、消費(fèi)者、路由和可靠性保障等核心能力,幫助快速實(shí)現(xiàn)異步通信場(chǎng)景,解決服務(wù)耦合和流量削峰問題,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • SpringBoot2.x 整合 AntiSamy防御XSS攻擊的簡(jiǎn)單總結(jié)

    SpringBoot2.x 整合 AntiSamy防御XSS攻擊的簡(jiǎn)單總結(jié)

    本文主要對(duì)SpringBoot2.x集成AntiSamy防御XSS攻擊進(jìn)行簡(jiǎn)單總結(jié),其中SpringBoot使用的2.4.5版本,通過示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-08-08
  • Java中的線程同步與ThreadLocal無鎖化線程封閉實(shí)現(xiàn)

    Java中的線程同步與ThreadLocal無鎖化線程封閉實(shí)現(xiàn)

    這篇文章主要介紹了Java中的線程同步與ThreadLocal無鎖化線程封閉實(shí)現(xiàn),Synchronized關(guān)鍵字與ThreadLocal變量的使用是Java中線程控制的基礎(chǔ),需要的朋友可以參考下
    2016-03-03
  • spring-gateway配置的實(shí)現(xiàn)示例

    spring-gateway配置的實(shí)現(xiàn)示例

    本文詳細(xì)介紹了Spring?Cloud?Gateway的核心配置結(jié)構(gòu),分為全局配置和路由配置兩大部分,下面就來詳細(xì)的介紹一下spring-gateway配置的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2025-12-12
  • Maven優(yōu)雅的添加第三方Jar包的方法

    Maven優(yōu)雅的添加第三方Jar包的方法

    下面小編就為大家?guī)硪黄狹aven優(yōu)雅的添加第三方Jar包的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • Spring MVC完全注解方式配置web項(xiàng)目

    Spring MVC完全注解方式配置web項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了Spring MVC完全注解方式配置web項(xiàng)目的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10

最新評(píng)論

仁化县| 临夏市| 万载县| 琼海市| 高碑店市| 县级市| 宁津县| 崇州市| 绿春县| 伊金霍洛旗| 金平| 望都县| 浦城县| 武鸣县| 县级市| 灌阳县| 辉县市| 嵊州市| 舟山市| 松阳县| 佳木斯市| 龙南县| 漯河市| 黎城县| 赫章县| 竹山县| 林甸县| 伊春市| 罗江县| 陆丰市| 屯留县| 当阳市| 姜堰市| 两当县| 金乡县| 永吉县| 盐边县| 搜索| 乌兰县| 弋阳县| 林周县|