【问题标题】:not able to update the excel data - it overwrites the actual data无法更新 excel 数据 - 它会覆盖实际数据
【发布时间】:2021-02-03 00:46:46
【问题描述】:

我有一个使用 apache poi api 写入 excel 文件的代码。问题是它每次都将新数据写入文件而不是附加数据。你能帮帮我吗?这是我的代码。

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class ExcelWrite {
    public static void write(AddExcel addExcel){
       try {
           XSSFWorkbook workbook = new XSSFWorkbook("NG.xlsx");
           XSSFSheet worksheet = workbook.createSheet("Scrap Data");



           int lastRow = worksheet.getLastRowNum();
           System.out.println(lastRow);
           Row row = worksheet.createRow(++lastRow);
           row.createCell(2).setCellValue(addExcel.getArtistName());
           row.createCell(3).setCellValue(addExcel.getItemName());
           row.createCell(6).setCellValue(addExcel.getOriginalPrimaryMarket());
           row.createCell(7).setCellValue(addExcel.getAvgResalePrice());
           row.createCell(8).setCellValue(addExcel.getPriceChangedFromPrimaryMarket());
           row.createCell(9).setCellValue(addExcel.getHighestAvgBid());
           row.createCell(10).setCellValue(addExcel.getLastSoldPrice());
           row.createCell(11).setCellValue(addExcel.getSecondayMarketVolume());
           row.createCell(12).setCellValue(addExcel.getSecondarySales());
           row.createCell(13).setCellValue(addExcel.getPrimarySales());
           row.createCell(14).setCellValue(addExcel.getDateCreated());
           row.createCell(16).setCellValue(addExcel.getInstagramURl());
           row.createCell(17).setCellValue(addExcel.getTwitterURL());


           FileOutputStream out = new FileOutputStream(new File("NG.xlsx"));
           workbook.write(out);
           out.close();
           System.out.println("Write Successfully.");

       }
       catch(IOException io){
           System.out.println(io.getMessage());
           System.out.println(io.getStackTrace());
       }

    }
}

【问题讨论】:

  • 您的文件输出流应该处于append 模式,即便如此,我认为如果您以这种方式编写文件,文件将无法读取。最好的办法是再次使用 api 读取文件并将行/列附加到文件中,而不是将原始字节附加到文件中
  • 你能把代码中的更正给我吗,我把这段代码改成了这个 FileOutputStream out = new FileOutputStream(new File("NG.xlsx"),true);,还有什么遗漏吗?
  • 永远不要使用 "new FileOutputStream(new File("NG.xlsx"), true)" 因为它总是会破坏你的代码。可能与stackoverflow.com/questions/65967508/… 重复阅读所有答案,以获取有关如何在不覆盖现有数据的情况下写入新数据的提示。每次执行代码时,您都在重新创建一个新的 excel 删除旧的。另一个学习如何更新 Excel 的有用链接:stackoverflow.com/questions/65940340/…

标签: java excel apache-poi


【解决方案1】:

问题是每次运行代码时,总是会创建全新的 XSSFWorkbook全新的 excel 文件,删除和覆盖现有的。

你打电话给worksheet.getLastRowNum()没关系;它会总是返回 -1,因为您的 XSSFWorkbook总是为空

如果您想更新现有的 excel 文件(向其附加新行),您必须通过加载现有的 excel 文件来创建您的 XSSFWorkbook您的代码已损坏,因为线

  workbook = new XSSFWorkbook();

您正在创建一个全新的XSSFWorkbook,它与您要更新的 Excel 文件完全无关。您必须改用:

  Workbook workbook = WorkbookFactory.create(new FileInputStream(toUpdateExcelFilePath));

您可能想查看此帖子以了解更多详细信息:how to update an existing excel file in Java

【讨论】:

    【解决方案2】:

    根据我的测试(我使用 maven 存储库中的 4.1.2 版本),当您使用 createSheet 时会产生异常:

    java.lang.IllegalArgumentException: The workbook already contains a sheet named 'Scrap Data'
    

    使用getSheet() 方法,您可以获取现有工作表。如果它不存在,您将获得一个null,然后您可以创建一个具有所需名称的新工作表。

    XSSFWorkbook workbook;
    try {
        File file = new File("NG.xlsx");
        workbook = new XSSFWorkbook();
        if(file.exists()) {
           FileInputStream fs = new FileInputStream(file);
           workbook = new XSSFWorkbook(fs);                
        }
        String sheetName = "Scrap Data";
        XSSFSheet worksheet = workbook.getSheet(sheetName);
        if(worksheet == null) {
           worksheet = workbook.createSheet(sheetName);
        }
    
    ... //other code unchanged
    
    } catch(Exception io){
      io.printStackTrace();
    }
    

    注意:我稍微更改了文件读取代码,因为我遇到了错误,文档说明如下:

    * Note - if the Document was opened from a {@link File} rather
    *  than an {@link InputStream}, you <b>must</b> write out to
    *  a different file, overwriting via an OutputStream isn't possible.
    

    【讨论】:

    • 在使用您的代码时出现此错误 - org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException:未找到有效条目或内容,这不是有效的 OOXML(Office Open XML)文件
    • 你用的是哪个版本的?
    • 使用 2016 office 和 poi-ooxml 3.15。
    • 很抱歉,但如果我降级到 3.15,同样的代码对我有用。可能的文件损坏?我在这里发现了一个类似的问题:NotOfficeXmlFileException 你可以检查一下。我只在 Windows 上进行了测试。
    猜你喜欢
    • 2020-03-03
    • 1970-01-01
    • 2019-02-20
    • 2017-01-28
    • 1970-01-01
    • 2020-12-03
    • 2020-03-27
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多