阅读 280

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

导出excel是咱Java开发的必备技能,下面这篇文章主要给大家介绍了关于Java通过导出超大Excel文件解决内存溢出问题的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

前言

将业务数据导出到Excel表中,导出任务数据量较大时,导出的项目就会内存溢出,本文通过Java操作Poi的SXSSFWorkbook类进行导出,解决内存溢出问题。

1.采用Poi中的SXSSFWorkbook

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

2.maven中引入Poi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- poi start -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<!-- poi end -->

3.测试过程


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

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

4.单元测试Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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();
            }
             
        }
         
    }
 
}

5.结论

导出excel数据量大时,采用SXSSFWorkbook进行操作,数据达到一定数据将写数据到临时文件,不会一直占用内存,因此不会报内存溢出

到此这篇关于Java通过导出超大Excel文件解决内存溢出问题的文章就介绍到这了

原文链接:https://juejin.cn/post/7011020885914025998

服务器评测 http://www.cncsto.com/ 

服务器测评 http://www.cncsto.com/ 

站长资源 https://www.cscnn.com/ 

小鱼创业 https://www.237fa.com/ 


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐