outOfMemoryError:java堆

时间:2012-03-07 07:27:25

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

public class seventhma {

    XSSFSheet m_sheet;
    int m_iNbRows;
    int m_iCurrentRow = 0;
    private static final String JAVA_TOSTRING = "EEE MMM dd HH:mm:ss zzz yyyy";

    public seventhma(XSSFSheet sheet) {
        m_sheet = sheet;
        m_iNbRows = sheet.getPhysicalNumberOfRows();
    }

    /*
     * Returns the contents of an Excel row in the form of a String array.
     * 
     * @see com.ibm.ccd.common.parsing.Parser#splitLine()
     */
    public String[] splitLine() throws Exception {
        // if (m_iCurrentRow == m_iNbRows)
        // return null;

        XSSFRow row = m_sheet.getRow(m_iCurrentRow);
        if (row == null) {
            return null;
        } else {
            int cellIndex = 0;
            int noOfCells = row.getPhysicalNumberOfCells();
            String[] values = new String[noOfCells];
            short firstCellNum = row.getFirstCellNum();
            short lastCellNum = row.getLastCellNum();

            if (firstCellNum >= 0 && lastCellNum >= 0) {
                for (short iCurrent = firstCellNum; iCurrent < lastCellNum; iCurrent++) {
                    XSSFCell cell = (XSSFCell) row.getCell(iCurrent);
                    if (cell == null) {
                        values[iCurrent] = "";
                        cellIndex++;
                        continue;
                    } else {
                        switch (cell.getCellType()) {
                            case XSSFCell.CELL_TYPE_NUMERIC:
                                double value = cell.getNumericCellValue();
                                if (DateUtil.isCellDateFormatted(cell))

                                {
                                    if (DateUtil.isValidExcelDate(value)) {
                                        Date date = DateUtil.getJavaDate(value);
                                        SimpleDateFormat dateFormat = new SimpleDateFormat(JAVA_TOSTRING);
                                        values[iCurrent] = dateFormat.format(date);
                                    } else {
                                        // throw new
                                        // Exception("Invalid Date value found at row number "
                                        // +
                                        // row.getRowNum()+" and column number "+cell.getCellNum());
                                    }
                                } else {
                                    values[iCurrent] = value + "";
                                }
                                break;

                            case XSSFCell.CELL_TYPE_STRING:
                                values[iCurrent] = cell.getStringCellValue();
                                break;

                            case XSSFCell.CELL_TYPE_BLANK:
                                values[iCurrent] = null;
                                break;

                            default:
                                values[iCurrent] = null;
                        }
                    }
                }
            }
            m_iCurrentRow++;
            return values;
        }

    }

    public static void main(String args[]) {
        XSSFWorkbook workBook = null;
        File file = new File("E:\\Local\\Local2.xlsx");
        InputStream excelDocumentStream = null;
        try {
            excelDocumentStream = new FileInputStream(file);
            // POIFSFileSystem fsPOI = new POIFSFileSystem(new
            // BufferedInputStream(excelDocumentStream));
            BufferedInputStream bfs = new BufferedInputStream(excelDocumentStream);
            workBook = new XSSFWorkbook(bfs);
            seventhma parser = new seventhma(workBook.getSheetAt(0));
            String[] res = null;
            while ((res = parser.splitLine()) != null) {
                for (int i = 0; i < res.length; i++) {
                    System.out.println("[" + res[i] + "]" + "\t");

                }
                System.out.println(res.length);

            }
            bfs = null;
            excelDocumentStream.close();

        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }

    }
}

此程序提供 java堆空间不足,当上传包含​​ 16 列的Excel工作表时,它会提供ArrayIndexOutOfBoundException
我增加了内存日食到-Xmx1600m,但这也没有用。

1 个答案:

答案 0 :(得分:2)

您在values数组上获得ArrayIndexOutOfBoundException,因为您使用row.getPhysicalNumberOfCells()来确定其大小。但是row.getPhysicalNumberOfCells()只会计算文件中实际填充的单元格。

例如,如果您创建Excel工作表并且仅填充A,C和F列,并且根本不接触其他单元格row.getPhysicalNumberOfCells()将返回3.
但是,您通过获取row.getFirstCellNum()row.getLastCellNum()来迭代所有单元格。因此,一旦到达单元格F,values[iCurrent]肯定会超出范围。

关于OutOfMemory问题: XSSF使用大量内存。尝试将VM推送到尽可能多的内存。或者,如果您只是阅读文件,请尝试使用eventmodel API而不是usermodel(想想SAX与DOM)。 Apache POI Streaming vs. In memory