2017-04-20 18 views
1

私はJava Apache POIライブラリと巨大なExcelシートを扱っています。多くの行と列を持つ約10 MBのデータ。 1つのExcelファイルに8-10​​の異なるシートがあります。データはリッチテキスト形式ではありませんが、内部の関数や数式などでいっぱいです。 = SUM(A2:A4)など私は心配していません。エラー:XSSFWorkbookでGCオーバーヘッドの上限を超えました

この画像は説明のためのものです。実際のデータの関数は、道異なる、非常に複雑です:

enter image description here

データは文字列、数値およびブール値を含みます。私の懸念は、Excelで適用されているすべての数式や関数を除いて、通常のテキストとしてXSSFに値を読み込ませることだけです。したがって、上記の画像では、私が唯一の行の値と列i.e. 10,20,30 etc, Numbers, Total

Iフォーマットはシートをエクセルとすべての数式や関数を削除し、簡単なリッチテキスト形式でデータを保存する場合は、問題を読みたい、と言って私のコードが実行されます。しかし、私が上記のフォーマットで示されているようにExcelファイルを修正してデータを保存しないと、GCオーバーヘッド限界を超えてエラーが発生します。私は

は私はちょうど彼らが同じように数式や関数の完全なExcelファイルを読みたい欲しい

。私のアルゴリズムは、すべての数式を削除し、テキストを通常のリッチテキスト形式としてシートに保存するときに機能します。私が最初に渡された入力を単にFileInputStream使用

fis = new FileInputStream(path); 
opc = OPCPackage.open(fis); 
XSSFWorkbook workbook = new XSSFWorkbook(opc); 

よりもむしろ:オンラインその他のリソースで述べたように、私は

を試してみましたが、StackOverflowの上で、私は第一のコードの下で与えられたようなアプローチを試みたが何

それはOPCPackageを通して。それでも同じエラーが表示され、コードは実行されません。XSSFWorkbook workbook

次に、XSSFReaderで2番目のアプローチを使用しました。以下のコードは次のとおりです。

xssfReader = new XSSFReader(opc); 
    SharedStringsTable sst = xssfReader.getSharedStringsTable(); 
    XSSFReader.SheetIterator itr = (XSSFReader.SheetIterator)xssfReader.getSheetsData();     

    while(itr.hasNext()) { 
      InputStream sheetStream = itr.next(); 
      if(itr.getSheetName().equals(sheetName)) { 

       // no idea how to extract sheet like I would do in XSSFWorkbook 
       // I only get Sheet name of desired sheet 

    } // while ends here 

何も今のところ私のために働かないと私はXSSFWorkbookを使用している場合、それはGCオーバーヘッドの制限がエラーを超えスローされます。だから私は手動ですべての数式と関数を削除し、アルゴリズムの作品が問題に対処する効率的ではない方法です。どんな助けや提案も感謝しています。

EDIT:

リンクhereで指摘したように、私はより多くのメモリを割り当てる試みたが、そのはまだ出て働いていません。以下は、私がより多くのメモリを割り当てようとしているいくつかのスナップショットです。

enter image description here enter image description here

私はメモリを割り当てるには何か間違ったことをやっている場合は、私に知らせてください。私は必要な変更を行います。

新規編集

日食に私の実行構成に-Xmx8192mを追加することにより、以下のcenticのコメントで述べたように、私は私の問題を解決しました。私は現在、以下の答えですでに説明したように、SXSSFWorkbookを使用してメモリの問題を解決する他の方法を検討しています。

+0

[GCオーバヘッドの上限をApache POIで超過している可能性があります](http://stackoverflow.com/questions/33368612/gc-overhead-limit-exceeded-with-apache-poi) – huellif

+0

@huellifメモリを割り当てようとしましたしかし、それは動作していません。私も私の質問を編集しました。 – Dhruvify

+2

表示されるメモリ設定は、Eclipse IDEとJava Webstart用です。実際にアプリケーションをどのように起動していますか? Eclipse内でアプリケーションや単体テストとして使用する場合は、実際のコードが実行されているときに実際にそれらを適用する代わりに、実行設定でメモリ設定を調整する必要があります。 – centic

答えて

1

コメントを投稿:

表示されるメモリ設定はEclipse IDEとJava Webstart用です。実際にアプリケーションをどのように起動していますか? Eclipse内でアプリケーションや単体テストとして使用する場合は、実際のコードが実行されているときに実際にそれらを適用する代わりに、実行設定でメモリ設定を調整する必要があります。

+0

これは私の問題を解決しました。私は '-Xmx8192m'をEclipseの実行コンフィギュレーションに追加しました。ありがとう。 – Dhruvify

0

XSSFブックの代わりにSXSSFブックとしてファイルを開こうとしましたか?

fis = new FileInputStream(path); 
opc = OPCPackage.open(fis); 
XSSFWorkbook workbook = new XSSFWorkbook(opc); 
SXSSFWorkbook wb = new SXSSFWorkbook(workbook); 

https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.htmlを参照してください。自分のJavaDocから取らdirecty:答えとして「この行ののみ設定可能な部分は、いずれかの時点でメモリに保持されているように、メモリが不足することなく、非常に大きなファイルを書き込むことができます」

+0

はい私は正確にこれを試みましたが、 'XSSFWorkbook workbook = new XSSFWorkbook(opc);'コードの直後にコードがGC制限を超過しました。私はちょうどそのような理由を得ることはありません。エクセルファイルから式を削除しても問題ありません。私は膨大な量のデータを持っています。 – Dhruvify

+0

Hmm。これは機能しますか? FileInputStream fis =新しいFileInputStream(エクセルファイル); \t \tブックワークブック=新しいSXSSFWorkbook(200); \t \t workbook = WorkbookFactory.create(fis); – tomgeraghty3

+0

これを試してみましたが、 'workBook = WorkbookFactory.create(fis);という行の後に同じエラーが表示される – Dhruvify

関連する問題