J2EE Web アプリケーションで POI を使用してワークブックを生成しています。ただし、POI で 25,000 行 (それぞれ約 15 列) のワークブックを作成するには、約 3 分かかることがわかりました。これは POI のパフォーマンスの問題ですか、それともそれほど時間がかかるのは正当なことですか? パフォーマンスが向上することが知られている他の API はありますか?
5 に答える
標準の POI API の代わりに「ストリーミング」POI API を使用すると、POI を使用して大きなファイルを書き込むパフォーマンスが大幅に低下する可能性があります。実際、デフォルトでは、POI はすべてのデータを最後に一度に書き込む前にすべてのデータをメモリに保持します。これのメモリフットプリントは、大きなファイルの場合、途方もなく大きくなる可能性があります. ストリーミング API を使用する代わりに、メモリの使用方法とデータのディスクへの書き込み方法を段階的に制御できます。
ストリーミング ワークブックを作成するには、次のようなものを使用します。
SXSSFWorkbook book = new SXSSFWorkbook();
book.setCompressTempFiles(true);
SXSSFSheet sheet = (SXSSFSheet) book.createSheet();
sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk
// ...
POI がそのようなファイルを生成するのにこれほどの時間がかかるのを見て、私は非常に驚きました。約 18 秒で 30000 行 x 10 セルのシートを生成しました (公平を期すために、書式設定はありません)。次のいずれかが原因である可能性があります。
- ここで説明されているように、POI ログがオンになっている可能性があります
- あなたはスワップメモリから実行しています
- VM の使用可能なヒープが非常に少ない可能性があります
他の答えがどれもうまくいかない場合は、Andy Khan の JExcel が優れているかどうかを確認してください。Java で Excel を処理する場合、POI よりもはるかに優れていることがわかりました。
Apache POI と JExcel ライブラリを比較しました。JExcel は Apache POI よりも最大 4 倍高速であるように見えますが、メモリ消費量は多かれ少なかれ同じようです。
@Test
public void createJExcelWorkbook() throws Exception {
WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls"));
WritableSheet sheet = workbook.createSheet("sheet", 0);
for ( int i=0; i < 65535; i++) {
for ( int j=0; j < 10; j++) {
Label label = new Label(j, i, "some text " + i + " " + j);
sheet.addCell(label);
}
}
workbook.write();
workbook.close();
}
@Test
public void createPoiWorkbook() throws Exception {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("sheet");
for ( int i=0; i < 65535; i++) {
Row row = sheet.createRow(i);
for ( int j=0; j < 10; j++) {
Cell cell = row.createCell(j);
cell.setCellValue("some text " + i + " " + j);
}
}
FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls");
wb.write(fileOut);
fileOut.close();
}
JExcel バージョン 2.6.12 と Apache POI バージョン 3.7 でテストしました。より正確な数値を取得するには、最新のライブラリ バージョンを自分でダウンロードし、上記の簡単なテストを実行する必要があります。
<dependency org="org.apache.poi" name="poi" rev="3.7"/>
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/>
注: Apache POI には、シートあたり 65535 行の制限があります。
また、Web アプリでも POI を使用しており、パフォーマンスの問題はありませんが、生成されたドキュメントはお客様のドキュメントよりもはるかに小さくなっています。ここでPOIが本当の問題かどうかを最初に確認します。J2EE オーバーヘッドなしでこれらのドキュメントを生成し (単体テスト)、パフォーマンスを測定してみてください。また、J2EE サーバーの負荷とメモリの使用状況を監視して、最適化されていないシステム設定が原因で問題が発生しているかどうかを確認することもできます。