当前位置: 首页 > 知识库问答 >
问题:

使用Apache-poi向现有excel文件添加工作表而不重写完整的文件

倪子晋
2023-03-14

我正在使用Apache poi并尝试将新的工作表添加到现有的excelhtml" target="_blank">文件中。

我正在使用FileOutputStream将工作表添加到workbook对象,并将workbook对象写入file。

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 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文件,即在输入模式下为每一张打开更新文件。

我的磁盘中已创建Excel文件。

我只是按照以下步骤:

>

  • 使用FileInputStream在输入中打开文件
  • 使用此FileInputStream对象创建工作簿
  • 创建工作表,写入数据
  • 使用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();
        }
    }
    

    它仍然给出了同样的例外。但我注意到的一件事是,当我试图向已经包含“newsheet1”的文件添加新工作表(例如“newsheet2”)时,它正在重写完整的工作簿,而不是在结尾处编写新工作表。

    有没有办法在最后写一张新的单子,而不是一遍又一遍地重写所有的单子?也许能解决我的问题。

    或者如果有任何其他解决方案来避免这种Java堆空间异常,最欢迎提出建议。

  • 共有1个答案

    常献
    2023-03-14

    有没有办法在最后写一张新的单子,而不是一遍又一遍地重写所有的单子?

    虽然我不熟悉文件格式的细节,但我严重怀疑这一点。文件的头部分可能有关于工作表的信息,所以您不能仅仅在文件末尾滑动一个新的工作表,而不重写文件头(从而重写整个文件)。

    如果您使用的是较新的excel格式(Office2007以后的版本),则可以尝试使用XSSFWorkbook。我知道它为阅读提供了更好的性能,所以它也可能为书写提供更好的性能(即不那么需要内存)。

     类似资料:
    • 我有一个Java方法writeToExcel(String sheetName,Map),它在一个新的excel文件中创建一个名为'sheet name'的新工作表,并将地图数据写入其中。当我使用不同的sheetName参数多次调用该方法时,现有的工作表将被上次调用的工作表替换。我希望每次使用不同的sheetName参数调用该方法时,都在同一个excel文件中创建新的工作表,而不会丢失现有的工作表

    • 我尝试使用Apache POI(3.15-Beta2版本,但也尝试过3.14)在XLSX电子表格中的现有表中添加列。使用下面的代码,我设法添加了一列,但它不能完全工作。 Excel 2013在尝试打开文件时出错(我们发现“....XLSX”中的某些内容有问题。是否希望我们尽可能多地恢复?如果信任此工作簿的来源,请单击是。)。如果单击“是”,文件将被打开,表的大小已经成功调整,新内容也被添加,但是列

    • 我试图使用apache POI、使用primefaces和java在现有的excel工作簿中创建一个新的工作表,但是到目前为止还没有成功。谁能告诉我这是怎么做的吗?我可以做单张 下面的代码是我为在一个xls文件中创建多个工作表而编写的,我给出的条件是它没有大于65535的of行创建新工作表并迭代它,但它显示错误 警告:允许范围(0..65535)之外的无效行号(65536)java.lang.Il

    • 我尝试了各种方式添加Excel电子表格。但问题总是相同的。 我尝试了这里提出的代码, 将工作表添加到现有excel文件 使用Apache POI for Java在现有Excel工作簿中创建新工作表 问题是:

    • 我试图将列表数据写入一个工作簿中的多个excel表格。与第一个列表一样,代码将创建新工作簿并为列表[1]创建新工作表,对于第二个列表,它将在现有工作簿中创建新工作表,依此类推。所以我写了下面的代码。但是它不起作用,我只能看到列表[1]的第一页。有人能帮我提供任何替代解决方案吗? 下面我写的代码 谢谢,Priyank Shah

    • 问题内容: 我想向现有的Excel文件中添加工作表。我怎样才能做到这一点?我正在研究一个selenium项目,我想将所有自动化结果表添加到单个excel文件中。现在,我能够为每个工作表创建新的Excel文件。 问题答案: 如果从Java 使用: 分别打开现有工作表或创建新工作表: 要检查工作表是否存在以创建唯一的工作表名称,可以使用如下所示的内容: 然后您可以通过调用添加工作表: 在这种情况下,工