poi大数据量生成excel

使用poi生成excel,当遇到大数据量时,会有几个问题:

 

1. 目前office2003 excle每个sheet最大支持行数为65536,当数据超过65536行时,会报异常

2. 当列为17列左右,数据行数达到50w条左右时,会包OOM错误

Exception in thread "15124183@qtp-16902686-1" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Thread-13" java.lang.OutOfMemoryError: Java heap space
        at org.apache.poi.hssf.usermodel.HSSFRow.createCell(HSSFRow.java:141)
        at org.apache.poi.hssf.usermodel.HSSFRow.createCell(HSSFRow.java:119)

 

问题1比较好解决,每次写入数据时,都获取sheet最后一行,在最后一行后继续写入数据,判断当最大行数大于65536或再小些,生成新的sheet,就能解决此问题。

具体代码片段

   int sheetLastSize = sheet.getLastRowNum();
            // 如果数据是最大写入数的整数倍(Constants.EXCEL_SHEET_DATASIZE为最大行数)
            if (sheetLastSize >= Constants.EXCEL_SHEET_DATASIZE) {
                sheet = workbook.createSheet();
                sheetLastSize = sheet.getLastRowNum();
                log.info("sheetLast Size:=========" + sheetLastSize);
                mapInfo.put("sheet", sheet);
                // 处理标题头
                processExcelTitle(dataset, workbook, sheet);
            }

 

问题2 目前没有较好的解决办法。由于每行都要生成多个cell对象,当数据量大时,java GC还没来得及回收,导致最后没有内存创建cell对象。现在正测试一种方法(只是暂时缓解,不是最好的办法),每次写入数据后,把row赋值null,定时调用System.GC();没有别的好办法,只能暂时测试下。

还是不行,仍然溢出!

 

 

 

/**
     * 传入已存在的workbook和数据源,向excel中追加数据,每个sheet大于指定行数时,创建新的sheet
     *
     * @param workbook
     *            已存在的工作薄
     * @param dataset
     *            写入数据集合
     * @param mapInfo
     *                 准备数据map
     */
    @SuppressWarnings("unchecked")
    private void dynamicExcel(HSSFWorkbook workbook, Map<String, Object> dataset, Map<Object, Object> mapInfo) {
        Map<String, String> headers = (Map<String, String>) dataset.get("1");
        Iterator<Entry<String, String>> titleIter = headers.entrySet().iterator();

        // 取得所有行的数据
        List<Map<String, String>> valueList = (List<Map<String, String>>) dataset.get("2");
        wroteRecodeSize += valueList.size();
        log.info("this times size is:------------------------------------------------------" + valueList.size());
        log.info("total wrote recode size is:------------------------------------------------" + wroteRecodeSize);
        HSSFSheet sheet = (HSSFSheet) mapInfo.get("sheet");
        for (int i = 0; i < valueList.size(); i++) {
            int sheetLastSize = sheet.getLastRowNum();
            // 如果数据是最大写入数的整数倍
            if (sheetLastSize >= Constants.EXCEL_SHEET_DATASIZE) {
                sheet = workbook.createSheet();
                sheetLastSize = sheet.getLastRowNum();
                log.info("sheetLast Size:=========" + sheetLastSize);
                mapInfo.put("sheet", sheet);
                // 处理标题头
                processExcelTitle(dataset, workbook, sheet);
            }
            // 追加行
            HSSFRow row = sheet.createRow(sheetLastSize + 1);
            sheet.setDefaultColumnWidth(25);
            // 取得一行所有记录的所有值
            int dataIndex = 0;
            Map<String, String> values = valueList.get(i);
            titleIter = headers.entrySet().iterator();
            while (titleIter.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry<String, String>) titleIter.next();
                String key = entry.getKey();
                HSSFCell cell = row.createCell(dataIndex++);
//                String v = values.get(key);
                cell.setCellValue(values.get(key));
            }
           
        }
    }

你可能感兴趣的:(thread,exception,object,String,Excel,dataset)