2012-03-19 21 views
6

xlsxファイルに65000行以上の結果セットを書き込む必要があります。だから私はApache POI 3.7を使用しようとしています。しかし、OutOfMemoryError:Javaヒープスペースのエラーが発生します。どのように私は問題を解決するように思わないJVMメモリを増やす以外にこの問題を解決するのですか?助けてください。Apache POI 3.7 OutOfMemoryError:xlsxファイルに大量の行を書き込むときのJavaヒープスペース

簡単なサンプルコード:

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にインポートすることで回避できますか? –

答えて

10

あなたはPOIプロジェクトはSXSSF APIで最近何をしたかをチェックアウトする場合があります。 How-Toにもセクションがあります。
あなたが提供したコード例では、データを作成して作成した後で忘れてしまいますので、これは完璧なものになります。 SXSSF拡張機能を使用すると、すぐにデータをファイルに書き込むことができます。これにより、メモリ占有量が少なくなります。

この機能はApache POI 3.7には存在しませんが、Apache POI 3.8 beta 3に追加されました。
最終バージョン3.8は現在投票中です。したがって、最終版を使用する必要がある場合は、それがリリースされるまであまり長くはならないはずです。

+0

3.8( 'poi-bin-3.8-20120326.tar.gz')をダウンロードしてテストしました。 100K行に問題はなく、メモリ使用量は200MBで一定です。以前はXSSFを使用していましたが、10K行で1GB必要でした。 HSSFはメモリの5倍のメモリを必要としましたが、それでも65Kでは1.5Gでした。 Turismo、あなたは私の一日を作った!今私は同じ 'usermodel'コードを使用しています。変更されたワークブッククラスは' org.apache.poi.xssf.streaming.SXSSFWorkbook'に変更されました。 – Jarekczek

0

私は同じ問題を抱えていますが、これは修正ではなく動作し、異なるExcelファイルを作成して手動でマージします。これは良い解決策ではありませんが、私にとっては緊急でした。

次の2つの異なる方法でこれを行うことができます:

1.-宵は3000行に達した後に新しいファイルを作成します。

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

をあなたがそれらを作成するためのステートメントにこれを追加することができますdinamically、一度あなたが最初の3000レコードに達したら、ファイルを保存して、次のレコードを書き続けます。

2.-たび未満3000件のレコードを取得し、再びプログラム全体を実行するために、結果セットまたはソースレコードを区切るが、別のクエリ帯:

between recNum = 1 and recNum <=100 

は、次の実行は次のようになります。

between recNum > 100 and recNum <= 200 

これは単なる例であり、これが役に立つと願っています。

関連する問題