首页 文章

Apache POI:SXSSFWorkbook.dispose()不存在

提问于
浏览
8

我'm using apache'用于编写XLSX文件的POI API . 因为我需要写大文件,所以this m跟随this指南 . 请注意,在示例结尾处有一个调用

wb.dispose

此wb实例引用SXSSFWorkbook实例 . 我在我的代码中使用相同但它抱怨dispose方法不存在 . 我下载了源代码,方法不存在 . 但是,转到他们的SVN并检查该类的代码我们可以看到那里的方法:

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

我已经尝试重新编译他们的代码,但是我遇到了很多错误......

2 回答

  • 12

    截至2012-12-03,POI 3.9可作为稳定版本提供 . dispose()方法在此版本的 SXSSFWorkbook 中可用 .

    (当然,问到这个问题时情况并非如此 . )

  • 7

    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
                }
            }
        }
    }
    

相关问题