使用jxl導出大數據量EXCEL時內存溢出的解決辦法

POI或者JXL在導出大量數據的時候,因爲它們將每個單元格生都成一個Cell對象,因此很容易致使內存溢出。app

一、經過jx1最新版本的採用臨時文件寫入EXCEL功能,設定臨時文件的位置,能夠有效的避免內存溢出:this

           wbSetting.setUseTemporaryFileDuringWrite(true);   
           wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時文件夾的位置

二、EXCEL獲取的list集合先讀取數據總行數,再經過ROWNUM進行控制,設定每次讀取多少行數據,好比一個List設定爲50000;excel

            WorkbookSettings wbSetting = new WorkbookSettings();   
            wbSetting.setUseTemporaryFileDuringWrite(true);   
            wbSetting.setTemporaryFileDuringWriteDirectory(new File(excelPath));//臨時文件夾的位置
            workbook = Workbook.createWorkbook(new File(fullPath),wbSetting);
            int returnCount=0;
            if(null!=pager)
            {
                returnCount = BrasDatabase.getReturnCount(pager.getStartTime(),
                        pager.getEndTime(), pager);
            }

            if (returnCount > 0) {    
                pager.setPageSize(50000);
                pager.setTotalRows(returnCount);// 獲取總行數
                pager.setNewTotalPages(pager.getTotalRows()); // 總頁數
                for (int i = 1; i <= pager.getTotalPages(); i++) {
                    pager.setCurrentPage(i); // 當前頁面d
                    List<BrasAuth> list = BrasDatabase
                            .getBrasAuthResultByIpToExcelList(pager
                                    .getStartTime(), pager.getEndTime(), pager);
                    this.createExcel(list,excelFilePath);
                    list.clear();
                }
            }


三、在寫入EXCEL的時候,將讀取的LIST分割,每50000條數據生成一個EXCEL的sheet(一個sheet最多能存儲60000多行數據),再寫入,寫入的時候,若是設置了採用臨時文件寫入的話,jx1會自動採用生成臨時文件的方式寫入EXCEL:orm

       for(int i=1;i<=list.size();i++)
        {
            if(i%50000==0)
            {
                sheetName=format.format(new Date());
                toExcel(list.subList(reNum, i),sheetName);
                reNum=i;
            }
        }對象

------------------------------------------------------------------------------------------------------------------------------圖片

寫文本格式的Excel文件,而不是用POI等生成二進制的文件, 能夠避免建立大批量的對象時內存溢出.代碼以下能夠做爲參考: 
第一種格式,CSV,最簡單的,格式最差,最基本的行列,不能合併,不能設置着色, 
第二種,HTML格式的,如:"<TABLE>....</TABLE>"這樣的文本,後輟名改成XLS就能夠了,能夠設置跨行列的合併,能夠着色,圖片沒試過,估計是能夠的,還能夠設置單元格對齊,單元格的格式等內存

public static boolean createExcelFileByStream(String path, List list) {  
        try {  
         //定義表頭 
         String userxlsinfo = "序號\t用戶ID\t姓名\t手機\t留言信息";  
            File file = new File("c:\\streamExcel.xls");  
            if (file.isFile()) {  
                file.mkdir();  
            }  
            FileOutputStream out = new FileOutputStream(file);  
            OutputStreamWriter osw = new OutputStreamWriter(out, "GB2312");  
            BufferedWriter bw = new BufferedWriter(osw);  
            // 建立表頭   
            String sheader = userxlsinfo;  
            sheader += "\r\n";  
            bw.write(sheader);  
            if (list != null) {  
             // List list 此處能夠遍歷list對象 
                for (int i = 0; i < 5; i++) {  
                    StringBuffer mess = new StringBuffer();  
                    // 用戶信息   
                    mess.append((i + 1) + "\t");  
                    mess.append((i + 1) + "\t");  
                    mess.append((i + 1) + "\t");  
                    mess.append((i + 1) + "\t");  
                    mess.append((i + 1) + "\t");  
                    
                    mess.append("\r\n");      
                    System.out.println(i);  
                    bw.write(mess.toString());  
                }  
            }  
            bw.close();  
            osw.close();  
            out.close();  
            return true;  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } 
        return false;  
    }  



注意:表頭部分和數據部分的間隔必定要用'\t ' 若是改用','號則導出文件用excel打開展現會有問題get

相關文章
相關標籤/搜索