2012-03-19 32 views
6

我需要寫在XLSX文件超過65000行的一個結果。所以我試圖使用Apache POI 3.7。但是我得到OutOfMemoryError錯誤:Java堆空間。我如何解決這個問題,除了增加JVM內存,似乎沒有解決問題。請幫忙。的Apache POI 3.7的OutOfMemoryError:Java堆空間中寫入到大沒有行的時候XLSX文件

簡單示例代碼:

public static void main(String[] args) throws IOException { 
     Workbook wb = new XSSFWorkbook(); 
     CreationHelper createHelper = wb.getCreationHelper(); 
     Sheet sheet = wb.createSheet("new sheet"); 

     // Create a row and put some cells in it. Rows are 0 based. 
     for (int i=0;i<65000;i++){ 
      Row row = sheet.createRow((int) i); 
     // Create a cell and put a value in it. 
     Cell cell = row.createCell(0); 
     cell.setCellValue(1); 

     // Or do it on one line. 
     row.createCell(1).setCellValue(1.2); 
     row.createCell(2).setCellValue(
       createHelper.createRichTextString("This is a string")); 
     row.createCell(3).setCellValue(true); 
     } 


     // Write the output to a file 
     FileOutputStream fileOut = new FileOutputStream("test1.xls"); 
     fileOut.flush(); 
     wb.write(fileOut); 
     fileOut.close(); 
    } 
+0

我不知道這個問題可以通過寫一個CSV文件並導入到Excel 2007規避? – 2013-08-05 01:28:22

回答

10

你可能想看看什麼POI項目與SXSSF API最近做了。 How-To也有一個部分。
爲你提供這將是完美的結合,你剛剛創建的數據,然後創建之後忘記它的示例代碼。通過SXSSF擴展,您可以立即開始將數據寫入文件。這使內存佔用降低。

請注意,此功能在Apache POI 3.7中不存在,但在Apache POI 3.8 beta 3中添加。
最終版本3.8正在進行投票。所以如果你不得不使用最終版本,那麼在發佈之前不應該太長。

+0

我下載3.8('POI彬3.8-20120326.tar.gz')和製造測試。 100K行沒有任何問題和200MB的內存使用,這似乎是不變的。以前,在XSSF中,我需要1GB用於10K行。 HSSF的內存需要少5倍,但仍然很高,65K爲1.5G。 Turismo,你讓我的一天!現在,我使用的是相同的'usermodel'代碼,只改變了工作簿類'org.apache.poi.xssf.streaming.SXSSFWorkbook'。 – Jarekczek 2012-11-07 07:31:40

0

我有同樣的問題,這不是一個修復,但它的工作原理,創造出不同的Excel文件,然後手動將它們合併,我知道這是不是一個很好的解決方案,但因爲這是我迫切別無選擇。

您可以通過兩種不同的方式做到這一點:

1.-創建一個新的文件,一旦yoi已經達到了3000行:

XSSFWorkbook wb = new XSSFWorkbook(); 
fileOut = new FileOutputStream("file1.xlsx"); 
fileOut = new FileOutputStream("file2.xlsx");... 

您可以添加到這個for語句來創建它們一旦你達到了前3000條記錄保存文件,並繼續寫在下一個。

2:界定結果集或源記錄,以獲得小於3000條記錄,並再次運行整個程序,但使用不同的查詢範圍內的每個時間:

between recNum = 1 and recNum <=100 

下一次運行將是:

between recNum > 100 and recNum <= 200 

這只是一個例子,希望這對您有用。

相關問題