使用 SXSSF POI 编写大型 Excel 工作表

Posted

技术标签:

【中文标题】使用 SXSSF POI 编写大型 Excel 工作表【英文标题】:Writing large Excel sheet using SXSSF POI 【发布时间】:2015-09-22 12:40:11 【问题描述】:

我正在使用 POI () 的流式工作表编写一个大型 Excel 表(超过一百万条记录),但我得到了java.lang.OutOfMemoryError: Java heap space。这是我的代码:

 public void exportExcel() 
            try 
                SXSSFWorkbook workbook = new SXSSFWorkbook();
                Sheet sheet = workbook.createSheet(); 

                List<Oject> list = dao.getList();
                Cell cell = null;
                if (!list.isEmpty()) 

                Row row = sheet.createRow(0);
                cell = row.createCell(0);
                cell.setCellValue("s1");

                cell = row.createCell(1);
                cell.setCellValue("s2");

                cell = row.createCell(2);
                cell.setCellValue("s3");

                cell = row.createCell(3);
                cell.setCellValue("s4");

                cell = row.createCell(4);
                cell.setCellValue("s5");

                cell = row.createCell(5);
                cell.setCellValue("s6");

                cell = row.createCell(6);
                cell.setCellValue("s7");

                cell = row.createCell(7);
                cell.setCellValue("s8");

                cell = row.createCell(8);
                cell.setCellValue("s9");

                cell = row.createCell(9);
                cell.setCellValue("s10");

                cell = row.createCell(10);
                cell.setCellValue("s11");

                cell = row.createCell(11);
                cell.setCellValue("s12");

                cell = row.createCell(12);
                cell.setCellValue("s13");

                cell = row.createCell(13);
                cell.setCellValue("s14");

                cell = row.createCell(14);
                cell.setCellValue("s15");

                cell = row.createCell(15);
                cell.setCellValue("s16");

                cell = row.createCell(16);
                cell.setCellValue("s17");

                cell = row.createCell(17);
                cell.setCellValue("s18");

                cell = row.createCell(18);
                cell.setCellValue("s19");

                cell = row.createCell(19);
                cell.setCellValue("s20");

                cell = row.createCell(20);
                cell.setCellValue("s21");

                cell = row.createCell(21);
                cell.setCellValue("s22");

                cell = row.createCell(22);
                cell.setCellValue("s23");

                cell = row.createCell(23);
                cell.setCellValue("s24");

                cell = row.createCell(24);
                cell.setCellValue("s25");

                cell = row.createCell(25);
                cell.setCellValue("s26");

                cell = row.createCell(26);
                cell.setCellValue("s27");

                cell = row.createCell(27);
                cell.setCellValue("s28");

                cell = row.createCell(28);
                cell.setCellValue("s29");

                cell = row.createCell(29);
                cell.setCellValue("s30");

                cell = row.createCell(30);
                cell.setCellValue("s31");

                cell = row.createCell(31);
                cell.setCellValue("s32");

                cell = row.createCell(32);
                cell.setCellValue("s33");

                cell = row.createCell(33);
                cell.setCellValue("s34");

                cell = row.createCell(34);
                cell.setCellValue("s35");

                cell = row.createCell(35);
                cell.setCellValue("s36");

                cell = row.createCell(36);
                cell.setCellValue("s37");

                for (int i = 0; i < list.size(); i++) 

                    row = sheet.createRow(i + 1);

                    cell = row.createCell(0);
                    if (list.get(i).getOne == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getOne);
                    

                    cell = row.createCell(1);
                    if (list.get(i).getTwo() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getTwo());
                    

                    cell = row.createCell(2);
                    if (list.get(i).getThree() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getThree());
                    

                    cell = row.createCell(3);
                    if (list.get(i).getFour() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getFour().toString());
                    

                    cell = row.createCell(4);
                    if (list.get(i).getFive() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getFive());
                    

                    cell = row.createCell(5);
                    if (list.get(i).getSix() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getSix());
                    

                    cell = row.createCell(6);
                    if (list.get(i).getSeven() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getSeven());
                    

                    cell = row.createCell(7);
                    if (list.get(i).getEight() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getEight());
                    

                    cell = row.createCell(8);
                    if (list.get(i).getNine() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getNine());
                    

                    cell = row.createCell(9);
                    if (list.get(i).getTen() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getTen().toString());
                    

                    cell = row.createCell(10);
                    if (list.get(i).getD() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getD());
                    

                    cell = row.createCell(11);
                    if (list.get(i).getF() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getF().toString());
                    

                    cell = row.createCell(12);
                    if (list.get(i).getV() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getV().toString());
                    

                    cell = row.createCell(13);
                    if (list.get(i).getVa() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVa().toString());
                    

                    cell = row.createCell(14);
                    if (list.get(i).getFo() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getFo().toString());
                    

                    cell = row.createCell(15);
                    if (list.get(i).getVar() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVar().toString());
                    

                    cell = row.createCell(16);
                    if (list.get(i).getVarm() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVarm().toString());
                    

                    cell = row.createCell(17);
                    if (list.get(i).getFor() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getFor().toString());
                    

                    cell = row.createCell(18);
                    if (list.get(i).getVarp() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVarp().toString());
                    

                    cell = row.createCell(19);
                    if (list.get(i).getVau() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVau().toString());
                    

                    cell = row.createCell(20);
                    if (list.get(i).getFoi() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getFoi().toString());
                    

                    cell = row.createCell(21);
                    if (list.get(i).getVaro() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVaro());
                    

                    cell = row.createCell(22);
                    if (list.get(i).getVo() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getvo().toString());
                    

                    cell = row.createCell(23);
                    if (list.get(i).getF5() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getF5().toString());
                    

                    cell = row.createCell(24);
                    if (list.get(i).getV5() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getV5().toString());
                    

                    cell = row.createCell(25);
                    if (list.get(i).getVm5() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getVm5().toString());
                    

                    cell = row.createCell(26);
                    if (list.get(i).getDo() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getDo().toString());
                    

                    cell = row.createCell(27);
                    if (list.get(i).getDmow() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getDmow().toString());
                    

                    cell = row.createCell(28);
                    if (list.get(i).getCut() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getCut());
                    

                    cell = row.createCell(29);
                    if (list.get(i).getDre() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getDre().toString());
                    

                    cell = row.createCell(30);
                    if (list.get(i).getCli() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getCli());
                    

                    cell = row.createCell(31);
                    if (list.get(i).getDn() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getDn().toString());
                    

                    cell = row.createCell(32);
                    if (list.get(i).getCod() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getCod());
                    

                    cell = row.createCell(33);
                    if (list.get(i).getCk() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getCk());
                    

                    cell = row.createCell(34);
                    if (list.get(i).getRem() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getRem().toString());
                    

                    cell = row.createCell(35);
                    if (list.get(i).getPs() == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getPs().toString());
                    

                    cell = row.createCell(36);
                    if (list.get(i).getTyp) == null) 
                        cell.setCellValue("");
                     else 
                        cell.setCellValue(list.get(i).getTyp().toString());
                    

                

            

            FacesContext facesContext = FacesContext.getCurrentInstance();
            ExternalContext externalContext = facesContext.getExternalContext()
           externalContext.setResponseContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"Lim_" + new Date().toString() + ".xlsx\"");

            workbook.write(externalContext.getResponseOutputStream());
            facesContext.responseComplete();
            workbook.dispose();
         catch (Exception e) 
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", null));
            e.printStackTrace();
        
    

由于列表的大小不同,我需要了解问题,我的堆大小是 512m

【问题讨论】:

你在用eclipse吗。 你迭代了几十个方法,你应该阅读“push and pop”和你的变量的生命周期。为什么你要静态访问所有 createCell() 方法而不是 createCell(i); 我正在使用 netbeans,我知道单元格的数量,所以我不需要遍历它们 【参考方案1】:

当您使用new SXSSFWorkbook(); 创建流式工作簿时,您会隐式指定无限制 行访问权限。这通常不是你想要写的。我建议在构造函数中添加一个整数参数,例如

SXSSFWorkbook workbook = new SXSSFWorkbook(100);

这应该会大大减少内存消耗。您甚至可以使用1 作为数字,只要您只按顺序写入行即可。

【讨论】:

还是同样的问题,知道我做错了什么吗? 尝试从您的 JSF 代码中提取 Excel 编写代码并在相同的内存限制下直接运行它。如果这样可行,您可能需要更改您的 JSF 配置或代码,因为 JSF 很可能会尝试将您的大型工作表存储在内存中,以便它可以在发送之前设置一个大小标题。

以上是关于使用 SXSSF POI 编写大型 Excel 工作表的主要内容,如果未能解决你的问题,请参考以下文章

HSSFXSSF和SXSSF区别以及Excel导出优化

java poi Excel大数据量导入怎么提高速度

基于SXSSF (Streaming Usermodel API)的写文件

如何使用 Apache POI (SXSSF) 为特定单元格设置数据(数字)格式区域设置?

对POI开源库excel大概泛(overview)了解

编写大型 Excel 电子表格