poixmlexception

vtwuwzda  于 2021-06-26  发布在  Java
关注(0)|答案(1)|浏览(329)

当我尝试覆盖现有excel文件时,会收到以下错误消息:

Exception in thread "main" org.apache.poi.ooxml.POIXMLException: OOXML file structure broken/invalid - no core document found!
at org.apache.poi.ooxml.POIXMLDocumentPart.getPartFromOPCPackage(POIXMLDocumentPart.java:783)
at org.apache.poi.ooxml.POIXMLDocumentPart.<init>(POIXMLDocumentPart.java:175)
at org.apache.poi.ooxml.POIXMLDocumentPart.<init>(POIXMLDocumentPart.java:165)
at org.apache.poi.ooxml.POIXMLDocument.<init>(POIXMLDocument.java:61)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:282)
at Test.main(Test.java:16)

顺便说一句,如果我试着写一个新的excel文件是没有问题的。所以它工作正常,但我不能更新现有的文件。我做错什么了?这是我的密码:

public static void main(String[] args) throws InvalidFormatException, IOException {
    File file = new File("C:/Users/yavuz/IdeaProjects/inspection/src/main/java/inspection.xlsx");
    OPCPackage pkg = OPCPackage.open(file);
    FileOutputStream outputStream = new FileOutputStream(file);
    XSSFWorkbook wb = new XSSFWorkbook(pkg);

    int finding = 445;

    DataFormatter formatter = new DataFormatter();
    for(Sheet sheet : wb) {
        for(Row row : sheet){
            if(row.getCell(0)!=null && !formatter.formatCellValue(row.getCell(0)).equals("")){
                Cell cell = row.getCell(0);
                String text = formatter.formatCellValue(cell);
                if('0'<=text.charAt(0) && text.charAt(0)<='9') {
                    int id = Integer.parseInt(text);
                    if (id == finding) {
                        System.out.println(sheet.getSheetName());
                        System.out.println(sheet.getRow(row.getRowNum()).getCell(1));
                        Cell cellCurrent = row.getCell(2);
                        if (cellCurrent == null){
                            cellCurrent = row.createCell(2);
                        }
                        cellCurrent.setCellValue("X");

                        wb.write(outputStream);
                        outputStream.close();
                    }
                }
            }
        }
    }
}
fxnxkyjh

fxnxkyjh1#

代码中存在多个问题。
如果您正在创建 OPCPackage 或者 XSSFWorkbookFile ,您不能有 FileOutputStream 只要 OPCPackage 或者 XSSFWorkbook 未关闭。这是因为 OPCPackage 或者 XSSFWorkbook 从一个 File 直接从文件中获取数据。所以内存占用较低,因为并非所有数据都在随机存取内存中。但是文件被锁定了。
如果需要阅读 File 写进同样的东西 File ,然后使用 FileInputStream 用于阅读和 FileOutputStream 因为写作是必要的。
而且你不能在每次更改后写出工作簿。之后 Workbook.write 工作簿还没有准备好从中获取数据。所以工作簿需要在所有更改完成后写一次。
整个世界都在创造 OPCPackage 没有必要。更好的方法是直接从 FileInputStream .

XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));

更好的是使用 WorkbookFactory.create 因为这是能够创造 HSSF 或者
XSSF Workbook 依赖于给定的文件。

Workbook wb = WorkbookFactory.create(new FileInputStream(file));

下面的代码已经过测试并使用 apache poi 4.1.2 .

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.ss.usermodel.*;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

class ExcelFromOPC {

  public static void main(String[] args) throws Exception {
    File file = new File("./inspection.xlsx");

    //OPCPackage pkg = OPCPackage.open(file);
    OPCPackage pkg = OPCPackage.open(new FileInputStream(file));
    XSSFWorkbook wb = new XSSFWorkbook(pkg);

    //XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(file));
    //Workbook wb = WorkbookFactory.create(new FileInputStream(file));

    //wb -> sheets -> rows -> cols
    int finding = 445;

    DataFormatter formatter = new DataFormatter();
    boolean write = false;
    for(Sheet sheet : wb) {
      for(Row row : sheet) {
        if(row.getCell(0)!=null && !formatter.formatCellValue(row.getCell(0)).equals("")) {
          Cell cell = row.getCell(0);
          String text = formatter.formatCellValue(cell);
          if('0'<=text.charAt(0) && text.charAt(0)<='9') {
            int id = Integer.parseInt(text);
            if (id == finding) {
              System.out.println(sheet.getSheetName());
              System.out.println(sheet.getRow(row.getRowNum()).getCell(1));
              Cell cellCurrent = row.getCell(2);
              if (cellCurrent == null) {
                cellCurrent = row.createCell(2);
              }
              cellCurrent.setCellValue("X");
              write = true;
            }
          }
        }
      }
    }

    if (write) {
        System.out.println("writing");
        FileOutputStream outputStream = new FileOutputStream(file);
        wb.write(outputStream);
        outputStream.close();
        wb.close();
    }
  }

}

相关问题