【问题标题】:POI OutOfMemory Exception with xlsx (XSSF)带有 xlsx (XSSF) 的 POI OutOfMemory 异常
【发布时间】:2012-05-30 01:55:31
【问题描述】:

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

在 XSSF 中,当我尝试打开 xlsx 文件 (~5 MB) 时,内存会猛增,大部分会导致 OutOfMemory。我的问题是,

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

  2. 有没有一种方法可以使用 XSSF 进行数据验证,但内存占用更少。

  3. 是否有用于 xlsx 数据验证的替代 Java 解决方案,它既快速又节省内存。

提前谢谢你..

【问题讨论】:

  • 建议您询问 poi 用户邮件列表,或者甚至打开带有测试用例的 JIRA。

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


【解决方案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。

【讨论】:

    【解决方案2】:

    它与 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 工作簿放在那里,这样 DataValidationHelper 将从 SXSSF 表中提取出来

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

    【讨论】:

      【解决方案3】:

      我在解析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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多