El Apache POI 3.8 (último estable en el momento) crea un archivo XML temporal para cada hoja (cuando se usa SXSSF) pero no da la opción de eliminar estos archivos. Este hecho hace que esta API no sea buena para usar porque si estoy exportando 600MB de datos, tendré 2 archivos con 600MB y uno de ellos estará en la carpeta temporal hasta que se elimine.
Introduciendo el código, vemos que la clase SXSSFSheet
tiene una instancia de SheetDataWriter
. Esta última clase es responsable de escribir y mantener el archivo temporal representado por la instancia File
. El acceso a este objeto permitiría eliminar el archivo. Todas estas instancias son privadas, por lo que, teóricamente, no puede acceder a ellas. Sin embargo, a través de la reflexión, podemos acceder a la instancia File
para eliminar estos archivos útiles pero molestos.
Los siguientes métodos permiten hacer esto. Al llamar al deleteSXSSFTempFiles
, se eliminan todos los archivos temporales de ese libro de trabajo.
/**
* 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
}
}
}
}
porqué no mire todo el código base de SVN y construir esa con la hormiga? ¿O tomar una construcción nocturna reciente? – Gagravarr
@Gagravarr La versión actual es 3.9-beta1 y realmente quería evitar el uso de API beta para clientes ... –
Si desea usar nuevas funciones, entonces necesita usar nuevas versiones ... – Gagravarr