2012-10-03 32 views
8

私はXLSXファイルを書き込むためにapacheのPOI APIを使用しています。大きなファイルを書く必要があるので、私はStreaming API(SXSSF)を使用しています。 これを行うには、私はthisのガイドに従っています。この例の最後には、Apache POI:SXSSFWorkbook.dispose()が存在しません

wb.dispose 

への呼び出しがあります。このwbインスタンスは、SXSSFWorkbookインスタンスを参照しています。私は自分のコードで同じものを使用していますが、存在しないdisposeメソッドについては不平を言います。ソースコードをダウンロードしましたが、その方法はありません。しかし、我々はそこに方法を見ることができる彼らのSVNに行くと、そのクラスのコードをチェック:

https://svn.apache.org/repos/asf/poi/trunk/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFWorkbook.java

を...

+0

SVNから全体のコードベースをチェックアウトし、アリとのことをビルドしないのはなぜは?または最近の夜間ビルドをつかむ? – Gagravarr

+0

@Gagravarr現在のバージョンは3.9-beta1なので、私は本当にcostumersのためのベータAPIの使用を避けたいと思っていました... –

+0

新しい機能を使いたい場合は、新しいリリースを使う必要があります... – Gagravarr

答えて

7

2012-12-03現在、POI 3.9は安定版として入手できます。 dispose()メソッドは、このリリースのSXSSFWorkbookで利用できます。

もちろん、これは質問を頼まれた場合ではなかった。)は

12

私はすでに自分のコードを再コンパイルしようとしたが、私は、エラーの多くを得ますApache POI 3.8(当時最新の安定版)は、各シート(SXSSF使用時)用の一時XMLファイルを作成しますが、これらのファイルを削除するオプションはありません。この事実は、600MBのデータをエクスポートすると600MBのファイルが2つあり、そのうちの1つが削除されるまでテンポラリフォルダに格納されるため、このAPIは使いにくいものになります。

コードを調べると、クラスSXSSFSheetのインスタンスはSheetDataWriterであることがわかります。この最後のクラスは、Fileインスタンスによって表されるテンポラリファイルの書き込みおよびメンテナンスを行います。このオブジェクトにアクセスすると、ファイルを削除できます。 これらのインスタンスはすべてプライベートなので、理論的にはアクセスできません。ただし、反映することで、Fileインスタンスにアクセスしてこの便利で迷惑なファイルを削除することができます。

以下の方法でこれを行うことができます。 deleteSXSSFTempFilesを呼び出すと、そのブックのすべての一時ファイルが削除されます。

/** 
* Returns a private attribute of a class 
* @param containingClass The class that contains the private attribute to retrieve 
* @param fieldToGet The name of the attribute to get 
* @return The private attribute 
* @throws NoSuchFieldException 
* @throws IllegalAccessException 
*/ 
public static Object getPrivateAttribute(Object containingClass, String fieldToGet) throws NoSuchFieldException, IllegalAccessException { 
    //get the field of the containingClass instance 
    Field declaredField = containingClass.getClass().getDeclaredField(fieldToGet); 
    //set it as accessible 
    declaredField.setAccessible(true); 
    //access it 
    Object get = declaredField.get(containingClass); 
    //return it! 
    return get; 
} 

/** 
* Deletes all temporary files of the SXSSFWorkbook instance 
* @param workbook 
* @throws NoSuchFieldException 
* @throws IllegalAccessException 
*/ 
public static void deleteSXSSFTempFiles(SXSSFWorkbook workbook) throws NoSuchFieldException, IllegalAccessException { 

    int numberOfSheets = workbook.getNumberOfSheets(); 

    //iterate through all sheets (each sheet as a temp file) 
    for (int i = 0; i < numberOfSheets; i++) { 
     Sheet sheetAt = workbook.getSheetAt(i); 

     //delete only if the sheet is written by stream 
     if (sheetAt instanceof SXSSFSheet) { 
      SheetDataWriter sdw = (SheetDataWriter) getPrivateAttribute(sheetAt, "_writer"); 
      File f = (File) getPrivateAttribute(sdw, "_fd"); 

      try { 
       f.delete(); 
      } catch (Exception ex) { 
       //could not delete the file 
      } 
     } 
    } 
} 
関連する問題