使用 apache-poi 更新 excel 文件时出现 POIXMLException
POIXMLException when updating excel file with apache-poi
当我尝试覆盖现有 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 file.So 它工作正常,但我无法更新现有文件。我究竟做错了什么?
有我的代码:
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();
}
}
}
}
}
}
您的代码中存在多个问题。
如果您从 File
创建 OPCPackage
或 XSSFWorkbook
,只要 [=13] =] 或 XSSFWorkbook
未关闭。这是因为从 File
打开的 OPCPackage
或 XSSFWorkbook
直接从该文件获取数据。所以内存占用量较低,因为并非所有数据都在随机存取存储器中。但是文件被锁定了。
如果需要从 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();
}
}
}
当我尝试覆盖现有 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 file.So 它工作正常,但我无法更新现有文件。我究竟做错了什么? 有我的代码:
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();
}
}
}
}
}
}
您的代码中存在多个问题。
如果您从 File
创建 OPCPackage
或 XSSFWorkbook
,只要 [=13] =] 或 XSSFWorkbook
未关闭。这是因为从 File
打开的 OPCPackage
或 XSSFWorkbook
直接从该文件获取数据。所以内存占用量较低,因为并非所有数据都在随机存取存储器中。但是文件被锁定了。
如果需要从 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();
}
}
}