java - 写入 XSSF Workbook 时,是什么导致我的程序陷入困境?

标签 java performance optimization xssf

也许“写入”不是正确的词,因为在这个函数中,我只是设置单元格,然后再写入。

我有一个函数,我已经指出它是导致它陷入困境的原因。当它到达这个函数时,它在这里花费了 10 多分钟,然后我才终止它。 这是我将 output_wb 传递给的函数:

private static void buildRowsByListOfRows(int sheetNumber, ArrayList<Row> sheet, Workbook wb) {
    Sheet worksheet = wb.getSheetAt(sheetNumber);
    int lastRow;
    Row row;
    String cell_value;
    Cell cell;
    int x = 0;
    System.out.println("Size of array list: " + sheet.size());
    for (Row my_row : sheet) {
        try {
            lastRow = worksheet.getLastRowNum();
            row = worksheet.createRow(++lastRow);

            for (int i = 0; i < my_row.getLastCellNum(); i++) {
                cell_value = getCellContentAsString(my_row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                cell = row.createCell(i);
                cell.setCellValue(cell_value);
                System.out.println("setting row #: " + x + "with value =>" + cell_value);
            }
            x++;
        } catch (Exception e) {
            System.out.println("SOMETHING WENT WRONG");
            System.out.println(e);
        }
    }
}

ArrayList 的大小为 73,835。它开始运行得非常快,然后到达大约 20,000 行,然后您可以看到循环中的打印语句越来越分散。每行有 70 列。

这个函数真的写得那么糟糕还是发生了其他事情? 我可以做什么来优化它?

如果这很重要,我会像这样创建输出工作簿:

// Create output file with the required sheets 
createOutputXLSFile(output_filename_path);
XSSFWorkbook output_wb = new XSSFWorkbook(new FileInputStream(output_filename_path));

createOutputXLSFile() 如下所示:

private static void createOutputXLSFile(String output_filename_path) throws FileNotFoundException {
    try {
        // Directory path where the xls file will be created
        // Create object of FileOutputStream
        FileOutputStream fout = new FileOutputStream(output_filename_path);
        XSSFWorkbook wb = new XSSFWorkbook();
        wb.createSheet("Removed records"); 
        wb.createSheet("Added records"); 
        wb.createSheet("Updated records"); 

        // Build the Excel File
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        wb.write(outputStream);
        outputStream.writeTo(fout);
        outputStream.close();
        fout.close();
        wb.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
    private static String getCellContentAsString(Cell cell) {
        DataFormatter fmt = new DataFormatter();
        String data = null;
        if (cell.getCellType() == CellType.STRING) {
            data = String.valueOf(cell.getStringCellValue());
        } else if (cell.getCellType() == CellType.NUMERIC) {
            data = String.valueOf(fmt.formatCellValue(cell));
        } else if (cell.getCellType() == CellType.BOOLEAN) {
            data = String.valueOf(fmt.formatCellValue(cell));
        } else if (cell.getCellType() == CellType.ERROR) {
            data = String.valueOf(cell.getErrorCellValue());
        } else if (cell.getCellType() == CellType.BLANK) {
            data = String.valueOf(cell.getStringCellValue());
        } else if (cell.getCellType() == CellType._NONE) {
            data = String.valueOf(cell.getStringCellValue());
        }
        return data;
    }

更新 #1 - 似乎正在发生在这里。如果我注释掉所有 3 行,那么它就完成了:

    cell_value = getCellContentAsString(my_row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
    cell = row.createCell(i);
    cell.setCellValue(cell_value);

更新 #2 - 如果我注释掉这两行,则循环将按预期完成:

    cell = row.createCell(i); // The problem
    cell.setCellValue(cell_value);

现在我知道问题出在 row.createCell(i) 但为什么呢?我该如何优化它?

最佳答案

我终于成功解决了这个问题。事实证明,如果文件很大,使用 XSSF 写入就太慢了。因此,我将 XSSF 输出工作簿转换为 SXSSFWorkbook。为此,我只需将现有的 XSSFWorkbook 传递到 SXSSFWorkbook 中,如下所示:

        // Create output file with the required sheets 
        createOutputXLSFile(output_filename_path);
        XSSFWorkbook output_wb_temp = new XSSFWorkbook(new FileInputStream(output_filename_path));
        SXSSFWorkbook output_wb = new SXSSFWorkbook(output_wb_temp);

其余代码按原样工作。

关于java - 写入 XSSF Workbook 时,是什么导致我的程序陷入困境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69379171/

相关文章:

algorithm - 为闭合多边形的 Douglas-Peucker 算法找到好的起点

Java Swing UI 布局

java - 如何在 JTable 中按日期对记录进行排序?

wpf - 在 WPF 中使用带有嵌套对象的 ListView 的可怕性能

c# - 事件订阅的性能注意事项

tsql - IN或OR哪个更快?

Java:带有 SimpleCursorAdapter 的 ORMLite:StaleDataException

java - BoneCP 正在报告未关闭的连接,但我在所有获得新连接的地方都使用 try-with-resource

c# - 百万交易 - 提高网站性能

c++ - -fomit-frame-pointer,使用它安全吗?