【问题标题】:Inserting data from arraylist in chunks in excel file using apache poi使用apache poi在excel文件中的块中插入来自arraylist的数据
【发布时间】:2017-08-25 07:40:48
【问题描述】:

我有以下格式的数据数组列表:

ArrayList> 列表结果数据。现在集合包含大约 11k+ 行要插入到 excel 中。 当我在 excel 中插入这 11490 行时,插入记录需要 6 小时,这意味着它的性能问题非常糟糕。有没有办法一次将数据以块的形式插入 1000 行(意味着在 sql 中应该有类似 executeBatch() 的东西用于插入记录)。一行也包含 4-5 列。

以下是我一直在使用的代码:

public boolean setArrayListData(String sheetName, ArrayList<ArrayList<String>> listResultData) {
    try {
        fis = new FileInputStream(path);
        workbook = new XSSFWorkbook(fis);

        int index = workbook.getSheetIndex(sheetName);

        if (index == -1)
            return false;

        sheet = workbook.getSheetAt(index);

        int colNum = 0;
        int rowNum = this.getRowCount(sheetName);
        rowNum++;
        for (ArrayList<String> al : listResultData) {   
            for (String s : al) {
                sheet.autoSizeColumn(colNum);
                row = sheet.getRow(rowNum - 1);
                if (row == null)
                    row = sheet.createRow(rowNum - 1);

                cell = row.getCell(colNum);
                if (cell == null)
                    cell = row.createCell(colNum);

                // cell style
                // CellStyle cs = workbook.createCellStyle();
                // cs.setWrapText(true);
                // cell.setCellStyle(cs);
                cell.setCellValue(s);
                //System.out.print("Cell Value :: "+s);
                colNum++;
            }
            rowNum++;
            colNum = 0;
            //System.out.println("");
        }

        fileOut = new FileOutputStream(path);
        workbook.write(fileOut);
        fileOut.close();
        workbook.close();
        fis.close();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

请推荐!!

【问题讨论】:

  • 我不知道 apache poi,但也许 docx4j 对你有更好的性能。我在短时间内创建了一个大约 6000 行和 20 列的 xslx。我使用此示例对其进行调整以适应我的解决方案:github.com/plutext/docx4j/blob/master/src/samples/xlsx4j/org/… 只需注意每个单元格的 R 属性:row1colum.setR("A1"); cell.setR("B1"); cell.setR("C1"); ...
  • 你应该利用这个API,尤其是1.3版,速度非常快。

标签: java apache-poi


【解决方案1】:

您可能想尝试使用 XSSF 的流式扩展来代替 XSSF。与 xssf 相比,您可以访问文档中的所有行,这可能导致性能或堆空间问题,sxssf 允许您定义滑动窗口并限制对该窗口中行的访问。您可以使用 new SXSSFWorkbook(int windowSize) 在构建工作簿时指定窗口大小。然后,当您创建行并且行数超过指定的窗口大小时,具有最低索引的行将被刷新并且不再在内存中。

SXSSF (Streaming Usermodel API)查找更多信息

例子:

// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook wb = new SXSSFWorkbook(100); 
    Sheet sh = wb.createSheet();
    for(int rownum = 0; rownum < 1000; rownum++){
        //When the row count reaches 101, the row with rownum=0 is flushed to disk and removed from memory, 
        //when rownum reaches 102 then the row with rownum=1 is flushed, etc. 
        Row row = sh.createRow(rownum);
        for(int cellnum = 0; cellnum < 10; cellnum++){
            Cell cell = row.createCell(cellnum);
            String address = new CellReference(cell).formatAsString();
            cell.setCellValue(address);
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 2014-12-05
    • 1970-01-01
    相关资源
    最近更新 更多