千家信息网

Java如何通过导出超大Excel文件解决内存溢出问题

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,这篇文章将为大家详细讲解有关Java如何通过导出超大Excel文件解决内存溢出问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.采用Poi中的SXSSFWork
千家信息网最后更新 2025年02月04日Java如何通过导出超大Excel文件解决内存溢出问题

这篇文章将为大家详细讲解有关Java如何通过导出超大Excel文件解决内存溢出问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1.采用Poi中的SXSSFWorkbook

在实现excel导出时,在数据量过大的情况下,总是容易发生内存溢出的情况。可以使用POI提供的 SXSSFWorkbook 类来避免内存溢出。

2.maven中引入Poi

                                                        org.apache.poi                        poi                        4.1.2                                                        org.apache.poi                        poi-ooxml                        4.1.2                                                        org.apache.poi                        poi-ooxml-schemas                        4.1.2                                

3.测试过程

先使用普通的写法测试(XSSFWorkbook),编写writeNormalExcelTest测试方法,写入的行数太多时,会报内存溢出(在设置-server -Xmx64m -Xms64m -Xmn32m的情况下)。

接着编写SXSSFWorkbook操作excel的测试,测试方法writeHugeExcelTest(同样在设置-server -Xmx64m -Xms64m -Xmn32m的情况下),结果证明无内存溢出,能完好的导出1000000行测试数据,整个Java类代码如下:

4.单元测试Java代码

package cn.gzsendi.exceltest;import java.io.FileOutputStream;import java.io.IOException;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.streaming.SXSSFWorkbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.junit.Test;public class HugeExcelExportTest {                private int totalRowNumber = 1000000; //写入的excel数据行数        private int totalCellNumber = 40; //excel每行共40列                //普通的写入excel的方法,会消耗内存,写入的行数太大时,会报内存溢出        @Test        public void writeNormalExcelTest(){                   Workbook wb = null;           FileOutputStream out = null;                           try {                   long startTime = System.currentTimeMillis();                               wb = new XSSFWorkbook();               Sheet sheet = wb.createSheet("Sheet 1");                               //定义Row和Cell变量, Rows从0开始.               Row row;               Cell cell;                               for (int rowNumber = 0; rowNumber < totalRowNumber; rowNumber++) {                       row = sheet.createRow(rowNumber);                   for (int cellNumber = 0; cellNumber < totalCellNumber; cellNumber++) {                           cell = row.createCell(cellNumber);                       cell.setCellValue(Math.random()); //写入一个随机数                   }                                       //打印测试,                   if(rowNumber % 10000 ==0) {                           System.out.println(rowNumber);                   }               }                       //Write excel to a file               out = new FileOutputStream("d:\\temp\\normalExcel_" + totalRowNumber + ".xlsx");               wb.write(out);               long endTime = System.currentTimeMillis();                               System.out.println("process " + totalRowNumber + " spent time:" + (endTime - startTime) + " ms.");                    } catch (Exception e) {                                   e.printStackTrace();                            } finally {                                                            try {                                if(out != null) out.close();                        } catch (IOException e) {                                e.printStackTrace();                        }                                        try {                            if(wb != null) wb.close();                        } catch (IOException e) {                                e.printStackTrace();                        }                                }                        }                //结合临时文件压缩等写入excel,默认超过100行就写到临时文件,不会报内存溢出        @Test        public void writeHugeExcelTest(){        SXSSFWorkbook wb = null;        FileOutputStream out = null;                try {                                long startTime = System.currentTimeMillis();                            wb = new SXSSFWorkbook();//默认100行,超100行将写入临时文件            wb.setCompressTempFiles(false); //是否压缩临时文件,否则写入速度更快,但更占磁盘,但程序最后是会将临时文件删掉的            Sheet sheet = wb.createSheet("Sheet 1");                        //定义Row和Cell变量, Rows从0开始.                Row row;                Cell cell;                                for (int rowNumber = 0; rowNumber < totalRowNumber; rowNumber++) {                                                row = sheet.createRow(rowNumber);                        for (int cellNumber = 0; cellNumber < totalCellNumber; cellNumber++) {                        cell = row.createCell(cellNumber);                        cell.setCellValue(Math.random()); //写入一个随机数                    }                                                                        //打印测试,                    if(rowNumber % 10000 ==0) {                            System.out.println(rowNumber);                    }                                        }                            //Write excel to a file                out = new FileOutputStream("d:\\temp\\hugeExcel_" + totalRowNumber + ".xlsx");                wb.write(out);                long endTime = System.currentTimeMillis();                                System.out.println("process " + totalRowNumber + " spent time:" + (endTime - startTime) + " ms.");                    } catch (Exception ex) {                            ex.printStackTrace();                    } finally {                            if (wb != null) {                    wb.dispose();// 删除临时文件,很重要,否则磁盘可能会被写满            }                        try {                                if(out != null) out.close();                        } catch (IOException e) {                                e.printStackTrace();                        }                                        try {                            if(wb != null) wb.close();                        } catch (IOException e) {                                e.printStackTrace();                        }                            }                        }}

关于"Java如何通过导出超大Excel文件解决内存溢出问题"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

0