9

jXLS数年前、 と を使用して大きな Excel ファイルを作成していたときに問題が発生しましたPOI XSSF。私の記憶が正しければ、XSSFディスク上に1GB以上の一時ファイルのようなものを作成して、10MBのExcelファイルを作成すると思います。そのため、使用をやめjXLS、代わりに Excel ファイルを作成していましたが、今日、またはSXSSFを使用する新しい理由があります。jXLSJETT

との両方jXLSJETTWeb サイトは、パフォーマンスがはるかに優れていることをほのめかしているようですが、POIのWeb サイトでは、より高いメモリ フットプリントが必要であるXSSFと一般的に述べられています。XSSFこのメモリ フットプリントの増加は、最近の 10% のオーバーヘッドに相当するものなのか、それとも数年前の 10,000% のオーバーヘッドのままなのか、疑問に思っています。

POI 3.9 では、非常に悪いメモリの問題は修正されていXSSFますか? orと一緒に使用することについて心配する必要はありませんjXLSJETT? または、避けるべき特定の落とし穴がありますか? セル スタイルの再利用には注意しています。

4

1 に答える 1

7

あなたの質問に答えると、はい、POI は、XLSX ファイルのサイズよりもはるかに大きい大きな XLSX ファイルで作業する場合、常に非常に大量のメモリを使用します。これがすぐに変わるとは思いませんが、それには明らかな理由があります。XLSX は基本的に圧縮された XML ファイルの集まりであり、XML は非常によく圧縮されています (約 10 倍)。この XML を圧縮せずにメモリに格納するだけでも、メモリ消費量が 10 倍になるため、データ構造のオーバーヘッドをすべて追加すると、XLSX ファイル サイズよりもメモリ消費量が 10% 増加するとは考えられません。

さて、良いニュースは、コメントで述べたように、Apache POI がSXSSFを導入して、非常に優れたパフォーマンスと低いメモリ使用量でスプレッドシート内の非常に大量のデータをストリーミングできるようになったことです。この方法で生成された XLSX ファイルは依然としてハード ディスク上でストリーミングされ、最終的にかなりのスペースを消費する可能性がありますが、少なくとも数十万行を書き込むときに OOME のリスクはありません。

問題は、JETT を SXSSF で直接動作させることができないことです。これは、テンプレートの入力を実行するためにドキュメント全体をメモリにロードする必要があるためです。JETT の作成者は、このトピックについてここですぐに説明しました。

私は同じ問題を抱えていたので、最終的に 2 段階の XLSX 作成を行いました。

  1. ヘッダーとフォーマットを生成する標準の JETT XLSX テンプレート。最初のシートの最後の行には、セルごとに $$tokens$$ を持つセルが含まれています。大量の行を挿入するために JETT を使用しません。

  2. JETT が作業を完了したら、ワークブックを再度開き、最初のスプレッドシートの最後の行にある $$tokens$$ を読み取って削除し、SXSSF を使用して行ごとにデータのストリーミングを開始します。

もちろん、このアプローチには制限があります。 POI API を使用して自分で処理しない限り、コピーすることはできません。個人的には、XLSX ファイルの列全体をフォーマットすることを好みます。これは、ストリーミングされたデータに適用されます。

これは、SXSSF で挿入されたデータを使用してグラフを表示する場合にも機能します。関数 OFFSET および COUNTA を使用して名前付き範囲を定義し、Excel で XLSX を開いたときに更新されるピボット テーブルとピボット グラフを作成できます。

于 2015-05-12T09:33:15.087 に答える