也许“写入”不是正确的词,因为在这个函数中,我只是设置单元格,然后再写入。
我有一个函数,我已经指出它是导致它陷入困境的原因。当它到达这个函数时,它在这里花费了 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/