如何使用 SXSSF Apache POI 将列添加到现有的大型 excel 文件?
How to add columns to an existing large excel file using SXSSF Apache POI?
我正在处理一个大型 excel 文件(大于 40 Mb,超过 100k 行和 50 列)。我使用 POI(3.10.1 版)事件流成功读取它,然后进行一些计算并将结果存储到列表中。
现在我必须将此列表附加为同一文件中的一列。在这部分我遇到了问题。
我尝试使用以下代码实现此目的
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(0); // Get first sheet
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
workbook.write(fos);
fos.close();
它对较小的文件工作正常但问题是我的内存不足而无法处理较大的文件。现在我尝试修改它并使用 SXSSF 代替 XSFF 来解决内存问题(见下面的代码)。但是在测试较小的文件时,我得到的输出文件与输入文件相同。
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
XSSFWorkbook xwb = new XSSFWorkbook(inputStream);
inputStream.close();
SXSSFWorkbook wb = new SXSSFWorkbook(xwb,100);
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheetAt(0);
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
wb.write(fos);
fos.close();
在我的用例中不适合使用数据库,由于内存限制,我想避免使用临时数据结构来保存要写入的数据。
有没有办法在流式传输时写入输出工作簿?这是我使用 POI Streaming API
阅读的代码
private class ExcelData implements SheetContentsHandler {
LinkedHashMap<Strin, String> rowMap;
public void startRow(int rowNum) {
}
public void endRow(int rowNum) {
// Process the row
// Handle write to output workbook ??
}
public void cell(String cellReference, String formattedValue,
XSSFComment comment) {
// Save current row in rowMap ( column name => cell value )
}
public void headerFooter(String text, boolean isHeader, String tagName)
{
}
}
无法使用 POI SXSSF 将列添加到现有工作簿。它只允许添加新行。
唯一的解决方案是读取现有工作簿并写入包含添加列的新工作簿。
为了实现这一点,我们可以在 endrow() 方法中将行存储在数据结构或数据库中,然后使用持久化的数据编写新的工作簿。
我正在处理一个大型 excel 文件(大于 40 Mb,超过 100k 行和 50 列)。我使用 POI(3.10.1 版)事件流成功读取它,然后进行一些计算并将结果存储到列表中。
现在我必须将此列表附加为同一文件中的一列。在这部分我遇到了问题。
我尝试使用以下代码实现此目的
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(0); // Get first sheet
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
workbook.write(fos);
fos.close();
它对较小的文件工作正常但问题是我的内存不足而无法处理较大的文件。现在我尝试修改它并使用 SXSSF 代替 XSFF 来解决内存问题(见下面的代码)。但是在测试较小的文件时,我得到的输出文件与输入文件相同。
FileInputStream excelFile = new FileInputStream(new File(pathToFile));
XSSFWorkbook xwb = new XSSFWorkbook(inputStream);
inputStream.close();
SXSSFWorkbook wb = new SXSSFWorkbook(xwb,100);
wb.setCompressTempFiles(true);
SXSSFSheet sh = (SXSSFSheet) wb.getSheetAt(0);
Iterator<Row> iterator = datatypeSheet.iterator();
int i=0;
while (iterator.hasNext()) { // Loop over each row
Row currentRow = iterator.next();
Cell cell = currentRow.createCell(currentRow.getLastCellNum());
cell.setCellType(Cell.CELL_TYPE_STRING);
if(currentRow.getRowNum() == 0)
cell.setCellValue("OUTPUT-COLUMN"); // set column header for the new column
else {
cell.setCellValue(list.get(i)); // list contains the output to populate in new column
i++;
}
}
FileOutputStream fos = new FileOutputStream(new File(pathToOutput));
wb.write(fos);
fos.close();
在我的用例中不适合使用数据库,由于内存限制,我想避免使用临时数据结构来保存要写入的数据。
有没有办法在流式传输时写入输出工作簿?这是我使用 POI Streaming API
阅读的代码private class ExcelData implements SheetContentsHandler {
LinkedHashMap<Strin, String> rowMap;
public void startRow(int rowNum) {
}
public void endRow(int rowNum) {
// Process the row
// Handle write to output workbook ??
}
public void cell(String cellReference, String formattedValue,
XSSFComment comment) {
// Save current row in rowMap ( column name => cell value )
}
public void headerFooter(String text, boolean isHeader, String tagName)
{
}
}
无法使用 POI SXSSF 将列添加到现有工作簿。它只允许添加新行。
唯一的解决方案是读取现有工作簿并写入包含添加列的新工作簿。
为了实现这一点,我们可以在 endrow() 方法中将行存储在数据结构或数据库中,然后使用持久化的数据编写新的工作簿。