使用xlsx(XSSF)的POI OutOfMemory异常

时间:2012-05-23 13:45:57

标签: apache-poi xlsx out-of-memory

我们正在尝试将POI 3.8用于我们的应用程序中的excel组件,该组件必须处理大型excel文件的创建。我很高兴使用SXSSF流媒体方法,这种方法速度快且内存占用率极低。但是,我无法进行数据验证并且必须使用XSSF。

在XSSF中,当我尝试打开xlsx文件(~5 MB)时,内存会弹起并且主要导致OutOfMemory。我的问题是,

  1. 是否可以使用SXSSF进行DataValidation(如从下拉列表中选择)。这对我来说是一种祝福。

  2. 有没有办法使用XSSF进行数据验证,但内存占用量较少。

  3. 是否有针对xlsx数据验证的备用java解决方案,该解决方案快速且内存有效。

  4. 提前谢谢..

3 个答案:

答案 0 :(得分:1)

OutOfMemory的原因,从调试器看,POI 3.10.1:

XSSFWorkbook has ArrayList<XSSFSheet>; 
XSSFSheet has TreeMap<Integer,XSSFRow>;
XSSFRow has field _row._textsource._srcAfter found as char[32768]

计数:32768 *(行数)=完全浪费内存....在我的情况下超过1 GB。

答案 1 :(得分:0)

与ss.usermodel(http://poi.apache.org/spreadsheet/quick-guide.html#Validation

的效果非常好

而不是像手册中那样使用XSSF工作簿:

Workbook workbook = new XSSFWorkbook();    
Sheet sheet = workbook.createSheet("Data Validation");  
     DataValidationHelper dvHelper = sheet.getDataValidationHelper();

将SXSSF工作簿放在那里,以便从SXSSF表中提取DataValidationHelper

    Workbook workbook = new SXSSFWorkbook();    
    Sheet sheet = workbook.createSheet("Data Validation");  
         DataValidationHelper dvHelper = sheet.getDataValidationHelper();  
//stuff with validation

答案 2 :(得分:0)

在解析xlsx文件时我也遇到了同样的OOM问题......经过两天的挣扎,我终于找到了下面非常完美的代码;

此代码基于sjxlsx。它读取xlsx并存储在HSSF表中。

            // read the xlsx file
       SimpleXLSXWorkbook = new SimpleXLSXWorkbook(new File("C:/test.xlsx"));

        HSSFWorkbook hsfWorkbook = new HSSFWorkbook();

        org.apache.poi.ss.usermodel.Sheet hsfSheet = hsfWorkbook.createSheet();

        Sheet sheetToRead = workbook.getSheet(0, false);

        SheetRowReader reader = sheetToRead.newReader();
        Cell[] row;
        int rowPos = 0;
        while ((row = reader.readRow()) != null) {
            org.apache.poi.ss.usermodel.Row hfsRow = hsfSheet.createRow(rowPos);
            int cellPos = 0;
            for (Cell cell : row) {
                if(cell != null){
                    org.apache.poi.ss.usermodel.Cell hfsCell = hfsRow.createCell(cellPos);
                    hfsCell.setCellType(org.apache.poi.ss.usermodel.Cell.CELL_TYPE_STRING);
                    hfsCell.setCellValue(cell.getValue());
                }
                cellPos++;
            }
            rowPos++;
        }
        return hsfSheet;