16

Java を使用してプログラムで Excel (.xls MS Excel 2003 形式) ファイルに書き込もうとしています。Excel出力ファイルには、シート数に分割する予定の〜200,000行が含まれる場合があります(Excelの制限により、シートあたり64k行)。

Apache POI API を使用してみましたが、API オブジェクト モデルが原因でメモリを大量に消費しているようです。メモリ内のワークブック オブジェクトにセル/シートを追加する必要があり、すべてのデータが追加されると、ワークブックをファイルに書き込むことができます。これは、Apache が API を使用して Excel ファイルを作成することを推奨する方法のサンプルです。

Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("new sheet");

//Create a row and put some cells in it
Row row = sheet.createRow((short)0);

// Create a cell and put a value in it.
Cell cell = row.createCell(0);
cell.setCellValue(1);

// Write the output to a file
FileOutputStream fileOut = new FileOutputStream("workbook.xls");
wb.write(fileOut);
fileOut.close();

明らかに、約 2 万行 (各行に 10 ~ 20 列) を書き込むと、恐ろしい "java.lang.OutOfMemoryError: Java heap space" が表示されます。

XmsおよびXmxパラメーターをXms512mおよびXmx1024として使用して、JVMの初期ヒープサイズと最大ヒープサイズを増やしてみました。ファイルに 15 万行以上を書き込むことはまだできません。

ディスクに書き込む前にファイル全体をメモリに構築するのではなく、Excel ファイルにストリーミングする方法を探しています。これにより、多くのメモリ使用量が節約されることが期待されます。代替の API またはソリューションをいただければ幸いですが、私は Java の使用に制限されています。ありがとう!:)

4

9 に答える 9

7

既存のすべての Java API は、ドキュメント全体を一度に RAM に構築しようとします。代わりに、新しい xslx ファイル形式に準拠する XML ファイルを作成してみてください。開始するには、Excel で目的の形式の小さなファイルを作成して保存することをお勧めします。次に、それを開いて構造を調べ、必要な部品を交換します。

ウィキペディアには、全体的な形式に関する優れた記事があります

于 2009-09-28T09:31:56.207 に答える
4

ヒープ スペースの例外を克服するために、ファイルを複数の Excel ファイルに分割する必要がありました。22列の約5k行がそれについてだと考えたので、5k行ごとにファイルを終了し、新しいファイルを開始し、それに応じてファイルを数えるようにロジックを作成しました。

20k 以上の行を書き込む必要がある場合、データを表す 4 つ以上の異なるファイルが存在します。

于 2009-12-21T12:17:27.013 に答える
3

繭プロジェクトのHSSFシリアライザーをご覧ください。

HSSFシリアライザーはSAXイベントをキャッチし、MicrosoftExcelで使用されるXLS形式のスプレッドシートを作成します

于 2009-09-28T12:41:43.610 に答える
2

JExcelApi もありますが、より多くのメモリを使用します。.csv ファイルを作成し、Excel で開く必要があると思います。多くのデータを渡すことができますが、「優れた魔法」を行うことはできません。

于 2009-09-28T09:31:02.000 に答える
2

CSV 形式の使用を検討してください。このようにして、メモリによって制限されることはもうありません。おそらく、CSV のデータを事前に入力している間だけかもしれませんが、これは効率的に行うこともできます。たとえば、DB から行のサブセットを照会し、LIMIT/OFFSET代わりにすぐにファイルに書き込む行を書き込む前に、DB テーブルの内容全体を Java のメモリに格納します。Excel の 1 つの「シート」の行数の制限は、約 100 万行に増加します。

とはいえ、データが実際に DB からのものである場合、Java がこれに適したツールであるかどうかを再考します。ほとんどの適切な DB には、間違いなくこのタスクをはるかに効率的に実行できる CSV へのエクスポート機能があります。たとえば MySQL の場合、LOAD DATA INFILEこのコマンドを使用できます。

于 2009-12-09T16:53:50.863 に答える
0

このメモリの問題は、セルにデータを挿入するとき、またはデータの計算/生成を実行するときに発生しますか?

定義済みの静的テンプレート形式で構成されるファイルを Excel にロードする場合は、テンプレートを保存して複数回再利用することをお勧めします。通常、テンプレートのケースは、日次販売レポートなどを作成するときに発生します...

それ以外の場合は、新しい行、境界線、列などを最初から作成する必要があるたびに.

これまでのところ、私が見つけた唯一の選択肢は Apache POI です。

「明らかに、約 20,000 行 (各行に 10 ~ 20 列) を書き込むと、恐ろしい "java.lang.OutOfMemoryError: Java heap space" が表示されます。」

「エンタープライズIT」

あなたができることは、バッチデータ挿入を実行することです。queuetask テーブルを作成し、毎回 1 ページを生成した後、数秒間休んでから、2 番目の部分を続行します。キュー タスク中の動的データ変更が心配な場合は、最初に主キーを Excel に取得できます (ユーザー ビューから列を非表示にしてロックすることにより)。最初の実行では主キーが挿入され、2 回目以降のキューの実行ではメモ帳から読み取られ、部分ごとにタスクが実行されます。

于 2009-09-28T09:22:49.123 に答える
0

私たちは非常によく似た同じ量のデータを処理しましたが、POI はリソースを大量に消費するため、JExcelapi に切り替える必要がありました。JexcelApi を試してみてください。大きな Excel ファイルを操作する必要がある場合でも、後悔することはありません。

于 2009-09-28T10:13:54.027 に答える