2012-10-03 4 views
8

아파치의 POI API를 사용하여 XLSX 파일을 작성하고 있습니다. 큰 파일을 작성해야하므로 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 개 있고 그 중 하나가 삭제 될 때까지 임시 폴더에 있기 때문에이 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 
      } 
     } 
    } 
}