是什么导致我的程序在写入 XSSF 工作簿时陷入困境?
What is causing my program to bog down when writing to XSSF Workbook?
也许“写”不是正确的词,因为在这个函数中,我只是设置单元格,然后再写。
我有一个功能,我已经指出这是它陷入困境的原因。当它到达这个函数时,它在这里花费了 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);
其余代码按原样工作。
也许“写”不是正确的词,因为在这个函数中,我只是设置单元格,然后再写。
我有一个功能,我已经指出这是它陷入困境的原因。当它到达这个函数时,它在这里花费了 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);
其余代码按原样工作。