我正在使用apache的POI API来编写XLSX文件。由于我需要编写大文件,我正在使用Streaming API(SXSSF)。 为此,我正在关注this指南。请注意,在示例结尾处有一个对
的调用wb.dispose
此wb实例引用SXSSFWorkbook实例。我在我的代码中使用相同但它抱怨dispose方法不存在。我下载了源代码,方法不存在。但是,转到他们的SVN并检查该类的代码,我们可以看到那里的方法:
我已经尝试重新编译他们的代码,但是我收到了很多错误...
答案 0 :(得分:12)
Apache POI 3.8(当时最新稳定版)为每个工作表创建一个临时XML文件(使用SXSSF时),但不提供删除这些文件的选项。这个事实使得这个API不好用,因为如果我输出600MB的数据,那么我将有2个600MB的文件,其中一个将在临时文件夹中删除。
深入研究代码,我们发现类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
}
}
}
}
答案 1 :(得分:7)
截至2012-12-03,POI 3.9可作为稳定版本提供。此版本中的SXSSFWorkbook
中提供了dispose()
方法。
(当然,问到这个问题时情况并非如此。)