使用Apache-poi将表单添加到现有的excel文件中,而不用重写完整的文件

我正在处理Apache poi,并试图添加新的工作表到现有的Excel文件中。

我将这些工作表添加到工作簿对象中,并使用FileOutputStream将工作簿对象写入文件。

FileOutputStream outputStream = null; FileInputStream inputStream = null; HSSFWorkbook workbook = null; int nRows = 5000; int nCols = 100; try { ArrayList<String> names = new ArrayList(); names.add("NewSheet1"); names.add("NewSheet2"); names.add("NewSheet3"); names.add("NewSheet4"); workbook = new HSSFWorkbook(); for (String name : names) { HSSFSheet sheet = workbook.createSheet(name); for (int rowCounter = 0; rowCounter < nRows; rowCounter++) { HSSFRow row = sheet.createRow(rowCounter); for (int colCounter = 0; colCounter < nCols; colCounter++) { HSSFCell cell = row.createCell(colCounter); cell.setCellValue("" + rowCounter + colCounter); } } } outputStream = new FileOutputStream(excelFilePath); workbook.write(outputStream); } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (outputStream != null) { outputStream.flush(); outputStream.close(); outputStream = null; } if (workbook != null) { workbook = null; } if (inputStream != null) { inputStream.close(); inputStream = null; } } catch (Exception e) { e.getMessage(); } } 

但它是抛出内存exception。

 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2245) at java.util.Arrays.copyOf(Arrays.java:2219) at java.util.ArrayList.grow(ArrayList.java:242) at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216) at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208) at java.util.ArrayList.add(ArrayList.java:440) at org.apache.poi.hssf.usermodel.HSSFWorkbook$SheetRecordCollector.visitRecord(HSSFWorkbook.java:1200) at org.apache.poi.hssf.record.aggregates.RecordAggregate$PositionTrackingVisitor.visitRecord(RecordAggregate.java:106) at org.apache.poi.hssf.record.aggregates.RecordAggregate$PositionTrackingVisitor.visitRecord(RecordAggregate.java:106) at org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate.visitCellsForRow(ValueRecordsAggregate.java:254) at org.apache.poi.hssf.record.aggregates.RowRecordsAggregate.visitContainedRecords(RowRecordsAggregate.java:269) at org.apache.poi.hssf.model.Sheet.visitContainedRecords(Sheet.java:550) at org.apache.poi.hssf.usermodel.HSSFWorkbook.getBytes(HSSFWorkbook.java:1247) at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1157) at com.ExcelTrial.main(ExcelTrial.java:43) 

所以,我尝试了其他的方法。

我试图通过表格写入Excel文件表格,即通过在每个表格的input模式下打开来更新文件。

Excel文件已经在我的磁盘上创build。

我只是按照以下步骤:

  • 在input中使用FileInputStream打开文件
  • 使用此FileInputStream对象创build工作簿
  • 创build表单,写入数据
  • 使用FileOutputStream写入文件

     String excelFilePath = "C:\\TrialNew\\TrialNew.xls"; FileOutputStream outputStream = null; FileInputStream inputStream = null; HSSFWorkbook workbook = null; int nRows = 5000; int nCols = 100; try { ArrayList<String> names = new ArrayList(); names.add("NewSheet1"); names.add("NewSheet2"); names.add("NewSheet3"); names.add("NewSheet4"); for (String name : names) { inputStream = new FileInputStream(new File(excelFilePath)); workbook = new HSSFWorkbook(inputStream); HSSFSheet sheet = workbook.createSheet(name); for (int rowCounter = 0; rowCounter < nRows; rowCounter++) { HSSFRow row = sheet.createRow(rowCounter); for (int colCounter = 0; colCounter < nCols; colCounter++) { HSSFCell cell = row.createCell(colCounter); cell.setCellValue("" + rowCounter + colCounter); } } outputStream = new FileOutputStream(excelFilePath); workbook.write(outputStream); outputStream.flush(); outputStream.close(); outputStream = null; workbook = null; inputStream.close(); inputStream = null; } } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (outputStream != null) { outputStream.flush(); outputStream.close(); outputStream = null; } if (workbook != null) { workbook = null; } if (inputStream != null) { inputStream.close(); inputStream = null; } } catch (Exception e) { e.getMessage(); } } 

它仍然给出同样的例外。 但我注意到的一件事是,当我试图添加新工作表(例如“Newsheet2”)到一个已经包含“NewSheet1”的文件时,它正在重写完整的工作簿,而不是在最后写一个新工作表。

有没有办法在最后写一张新的表格,而不是一次又一次地重新写入所有的表格呢? 这可能会解决我的问题。

或者,如果有其他解决scheme来避免此Java堆空间exception,build议是非常受欢迎的。

有没有办法在最后写一张新的表格,而不是一次又一次地重新写入所有的表格呢?

虽然我对文件格式的细节并不熟悉,但是我非常怀疑。 可能有关于文件头部分的表单的信息,所以你不能只是在文件末尾滑动一个新的工作表,并且不用重写头部(因此也就是整个文件)就可以工作。

如果您使用的是较新的Excel格式(Office 2007起),则可以尝试使用XSSFWorkBook 。 我知道它为阅读提供了更好的性能,所以它可能会更好的performance(即减less内存饿)的写作。