2012-10-03 33 views
8

Tôi đang sử dụng API POI của apache để ghi các tệp XLSX. Vì tôi cần viết các tệp lớn, tôi đang sử dụng API phát trực tuyến (SXSSF). Để thực hiện việc này, tôi đang theo dõi hướng dẫn this. Lưu ý rằng vào cuối ví dụ, có một cuộc gọi đếnApache POI: SXSSFWorkbook.dispose() không tồn tại

wb.dispose 

Ví dụ wb này đề cập đến một cá thể SXSSFWorkbook. Tôi đang sử dụng cùng trong mã của tôi nhưng nó than phiền về phương pháp vứt bỏ không tồn tại. Tôi đã tải xuống mã nguồn và phương thức không có ở đó. Tuy nhiên, đi đến SVN của họ và kiểm tra xem lớp mã chúng ta có thể thấy phương pháp đó:

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

Tôi đã cố gắng để biên dịch lại mã của họ nhưng tôi nhận được rất nhiều lỗi ...

+0

Tại sao không kiểm toàn bộ codebase từ SVN và xây dựng rằng với kiến? Hoặc lấy một bản dựng hàng đêm gần đây? – Gagravarr

+0

@Gagravarr Phiên bản hiện tại là 3.9-beta1 và tôi thực sự thực sự muốn tránh sử dụng API beta cho costumers ... –

+0

Nếu bạn muốn sử dụng các tính năng mới, thì bạn cần sử dụng các bản phát hành mới ... – Gagravarr

Trả lời

7

Kể từ 2012-12-03, POI 3.9 có sẵn dưới dạng bản phát hành ổn định. Phương pháp dispose() có sẵn trong SXSSFWorkbook trong bản phát hành này.

(Tất nhiên, đây không phải là trường hợp khi câu hỏi được hỏi.)

12

Các Apache POI 3.8 (ổn định mới nhất tại thời điểm đó) tạo một tệp XML tạm thời cho mỗi trang tính (khi sử dụng SXSSF) nhưng không cung cấp tùy chọn xóa các tệp này. Thực tế này làm cho API này không tốt để sử dụng vì nếu tôi xuất 600MB dữ liệu thì tôi sẽ có 2 tệp với 600MB và một trong số chúng sẽ nằm trong thư mục tạm thời cho đến khi nó bị xóa.

Tìm hiểu mã, chúng tôi thấy rằng lớp SXSSFSheet có phiên bản SheetDataWriter. Lớp cuối cùng này chịu trách nhiệm viết và duy trì tệp tạm thời được thể hiện bằng cá thể File. Việc truy cập đối tượng này sẽ cho phép xóa tệp. Tất cả các trường hợp này là riêng tư, về mặt lý thuyết, bạn không thể truy cập chúng. Tuy nhiên, thông qua phản ánh, chúng ta có thể truy cập cá thể File để xóa các tệp hữu ích nhưng gây phiền nhiễu này!

Dưới đây là các phương pháp cho phép thực hiện việc này. Bằng cách gọi số deleteSXSSFTempFiles, tất cả các tệp tạm thời của sổ làm việc đó sẽ bị xóa.

/** 
* 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 
      } 
     } 
    } 
} 
Các vấn đề liên quan