Java 在使用ApachePOI读取xlsx文件时获取异常(org.apache.poi.openxml4j.Exception-无内容类型[M1.13])?

Java 在使用ApachePOI读取xlsx文件时获取异常(org.apache.poi.openxml4j.Exception-无内容类型[M1.13])?,java,apache-poi,Java,Apache Poi,我正在使用Apache POI(XSSF API)读取xlsx文件。当我尝试读取文件时,出现以下错误: org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13] 代码: 公共类ReadXLSX { 私有字符串文件路径; 私人XSSF工作簿; 专用静态记录器=null;

我正在使用Apache POI(XSSF API)读取xlsx文件。当我尝试读取文件时,出现以下错误:

org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
代码:

公共类ReadXLSX
{
私有字符串文件路径;
私人XSSF工作簿;
专用静态记录器=null;
私有输入流资源流;
公共ReadXLSX(字符串文件路径)
{
logger=LoggerFactory.getLogger(“ReadXLSX”);
this.filepath=filepath;
resourceAsStream=ClassLoader.getSystemResourceAsStream(文件路径);
}
公共ReadXLSX(输入流文件流)
{ 
logger=LoggerFactory.getLogger(“ReadXLSX”);
this.resourceAsStream=fileStream;
}
私有void loadFile()引发FileNotFoundException、NullObjectFoundException
{
if(resourceAsStream==null)
抛出新的FileNotFoundException(“无法找到给定文件…”);
其他的
{
尝试
{
工作簿=新XSSF工作簿(resourceAsStream);
}
捕获(IOEX异常)
{
}
}
}//结束加载XLSFILE
公共字符串[]getSheetsName()
{
int totalsheet=0;int i=0;
字符串[]sheetName=null;
试一试{
loadFile();
totalsheet=workbook.getNumberOfSheets();
sheetName=新字符串[totalsheet];
while(我清理了代码(大部分注释掉了记录器),使其在我的Eclipse环境中运行

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.*;

public class ReadXLSX {
private String filepath;
private XSSFWorkbook workbook;
// private static Logger logger=null;
private InputStream resourceAsStream;

public ReadXLSX(String filePath) {
    // logger=LoggerFactory.getLogger("ReadXLSX");
    this.filepath = filePath;
    resourceAsStream = ClassLoader.getSystemResourceAsStream(filepath);
}

public ReadXLSX(InputStream fileStream) {
    // logger=LoggerFactory.getLogger("ReadXLSX");
    this.resourceAsStream = fileStream;
}

private void loadFile() throws FileNotFoundException,
        NullObjectFoundException {

    if (resourceAsStream == null)
        throw new FileNotFoundException("Unable to locate give file..");
    else {
        try {
            workbook = new XSSFWorkbook(resourceAsStream);

        } catch (IOException ex) {

        }

    }
}// end loadxlsFile

public String[] getSheetsName() {
    int totalsheet = 0;
    int i = 0;
    String[] sheetName = null;

    try {
        loadFile();
        totalsheet = workbook.getNumberOfSheets();
        sheetName = new String[totalsheet];
        while (i < totalsheet) {
            sheetName[i] = workbook.getSheetName(i);
            i++;
        }

    } catch (FileNotFoundException ex) {
        // logger.error(ex);
    } catch (NullObjectFoundException ex) {
        // logger.error(ex);
    }

    return sheetName;
}

public int[] getSheetsIndex() {
    int totalsheet = 0;
    int i = 0;
    int[] sheetIndex = null;
    String[] sheetname = getSheetsName();
    try {
        loadFile();
        totalsheet = workbook.getNumberOfSheets();
        sheetIndex = new int[totalsheet];
        while (i < totalsheet) {
            sheetIndex[i] = workbook.getSheetIndex(sheetname[i]);
            i++;
        }

    } catch (FileNotFoundException ex) {
        // logger.error(ex);
    } catch (NullObjectFoundException ex) {
        // logger.error(ex);
    }

    return sheetIndex;
}

private boolean validateIndex(int index) {
    if (index < getSheetsIndex().length && index >= 0)
        return true;
    else
        return false;
}

public int getNumberOfSheet() {
    int totalsheet = 0;
    try {
        loadFile();
        totalsheet = workbook.getNumberOfSheets();

    } catch (FileNotFoundException ex) {
        // logger.error(ex.getMessage());
    } catch (NullObjectFoundException ex) {
        // logger.error(ex.getMessage());
    }

    return totalsheet;
}

public int getNumberOfColumns(int SheetIndex) {
    int NO_OF_Column = 0;
    @SuppressWarnings("unused")
    XSSFCell cell = null;
    XSSFSheet sheet = null;
    try {
        loadFile(); // load give Excel
        if (validateIndex(SheetIndex)) {
            sheet = workbook.getSheetAt(SheetIndex);
            Iterator<Row> rowIter = sheet.rowIterator();
            XSSFRow firstRow = (XSSFRow) rowIter.next();
            Iterator<Cell> cellIter = firstRow.cellIterator();
            while (cellIter.hasNext()) {
                cell = (XSSFCell) cellIter.next();
                NO_OF_Column++;
            }
        } else
            throw new InvalidSheetIndexException("Invalid sheet index.");
    } catch (Exception ex) {
        // logger.error(ex.getMessage());

    }

    return NO_OF_Column;
}

public int getNumberOfRows(int SheetIndex) {
    int NO_OF_ROW = 0;
    XSSFSheet sheet = null;

    try {
        loadFile(); // load give Excel
        if (validateIndex(SheetIndex)) {
            sheet = workbook.getSheetAt(SheetIndex);
            NO_OF_ROW = sheet.getLastRowNum();
        } else
            throw new InvalidSheetIndexException("Invalid sheet index.");
    } catch (Exception ex) {
        // logger.error(ex);
    }

    return NO_OF_ROW;
}

public String[] getSheetHeader(int SheetIndex) {
    int noOfColumns = 0;
    XSSFCell cell = null;
    int i = 0;
    String columns[] = null;
    XSSFSheet sheet = null;

    try {
        loadFile(); // load give Excel
        if (validateIndex(SheetIndex)) {
            sheet = workbook.getSheetAt(SheetIndex);
            noOfColumns = getNumberOfColumns(SheetIndex);
            columns = new String[noOfColumns];
            Iterator<Row> rowIter = sheet.rowIterator();
            XSSFRow Row = (XSSFRow) rowIter.next();
            Iterator<Cell> cellIter = Row.cellIterator();

            while (cellIter.hasNext()) {
                cell = (XSSFCell) cellIter.next();
                columns[i] = cell.getStringCellValue();
                i++;
            }
        } else
            throw new InvalidSheetIndexException("Invalid sheet index.");
    }

    catch (Exception ex) {
        // logger.error(ex);
    }

    return columns;
}// end of method

public String[][] getSheetData(int SheetIndex) {
    int noOfColumns = 0;
    XSSFRow row = null;
    XSSFCell cell = null;
    int i = 0;
    int noOfRows = 0;
    int j = 0;
    String[][] data = null;
    XSSFSheet sheet = null;

    try {
        loadFile(); // load give Excel
        if (validateIndex(SheetIndex)) {
            sheet = workbook.getSheetAt(SheetIndex);
            noOfColumns = getNumberOfColumns(SheetIndex);
            noOfRows = getNumberOfRows(SheetIndex) + 1;
            data = new String[noOfRows][noOfColumns];
            Iterator<Row> rowIter = sheet.rowIterator();
            while (rowIter.hasNext()) {
                row = (XSSFRow) rowIter.next();
                Iterator<Cell> cellIter = row.cellIterator();
                j = 0;
                while (cellIter.hasNext()) {
                    cell = (XSSFCell) cellIter.next();
                    if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                        data[i][j] = cell.getStringCellValue();
                    } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                        if (HSSFDateUtil.isCellDateFormatted(cell)) {
                            String formatCellValue = new DataFormatter()
                                    .formatCellValue(cell);
                            data[i][j] = formatCellValue;
                        } else {
                            data[i][j] = Double.toString(cell
                                    .getNumericCellValue());
                        }

                    } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
                        data[i][j] = Boolean.toString(cell
                                .getBooleanCellValue());
                    }

                    else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
                        data[i][j] = cell.getCellFormula().toString();
                    }

                    j++;
                }

                i++;
            } // outer while

        } else
            throw new InvalidSheetIndexException("Invalid sheet index.");

    } catch (Exception ex) {
        // logger.error(ex);
    }
    return data;
}

public String[][] getSheetData(int SheetIndex, int noOfRows) {
    int noOfColumns = 0;
    XSSFRow row = null;
    XSSFCell cell = null;
    int i = 0;
    int j = 0;
    String[][] data = null;
    XSSFSheet sheet = null;

    try {
        loadFile(); // load give Excel

        if (validateIndex(SheetIndex)) {
            sheet = workbook.getSheetAt(SheetIndex);
            noOfColumns = getNumberOfColumns(SheetIndex);
            data = new String[noOfRows][noOfColumns];
            Iterator<Row> rowIter = sheet.rowIterator();
            while (i < noOfRows) {

                row = (XSSFRow) rowIter.next();
                Iterator<Cell> cellIter = row.cellIterator();
                j = 0;
                while (cellIter.hasNext()) {
                    cell = (XSSFCell) cellIter.next();
                    if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                        data[i][j] = cell.getStringCellValue();
                    } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                        if (HSSFDateUtil.isCellDateFormatted(cell)) {
                            String formatCellValue = new DataFormatter()
                                    .formatCellValue(cell);
                            data[i][j] = formatCellValue;
                        } else {
                            data[i][j] = Double.toString(cell
                                    .getNumericCellValue());
                        }
                    }

                    j++;
                }

                i++;
            } // outer while
        } else
            throw new InvalidSheetIndexException("Invalid sheet index.");
    } catch (Exception ex) {
        // logger.error(ex);
    }

    return data;
}
}
所有这些运行起来都很有魅力,所以我猜您有一个XLSX文件在某种程度上“损坏”。请尝试使用其他数据进行测试

干杯,
Wim

非常确定,当Excel文件受密码保护或文件本身已损坏时,会引发此异常。如果您只想读取.xlsx文件,请尝试下面的我的代码。它更简短,更易于阅读

import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Sheet;
//.....

static final String excelLoc = "C:/Documents and Settings/Users/Desktop/testing.xlsx";

public static void ReadExcel() {
InputStream inputStream = null;
   try {
        inputStream = new FileInputStream(new File(excelLoc));
        Workbook wb = WorkbookFactory.create(inputStream);
        int numberOfSheet = wb.getNumberOfSheets();

        for (int i = 0; i < numberOfSheet; i++) {
             Sheet sheet = wb.getSheetAt(i);
             //.... Customize your code here
             // To get sheet name, try -> sheet.getSheetName()
        }
   } catch {}
}
import org.apache.poi.ss.usermodel.WorkbookFactory;
导入org.apache.poi.ss.usermodel.工作簿;
导入org.apache.poi.ss.usermodel.Sheet;
//.....
静态最终字符串excelLoc=“C:/Documents and Settings/Users/Desktop/testing.xlsx”;
公共静态void ReadExcel(){
InputStream InputStream=null;
试一试{
inputStream=新文件inputStream(新文件(excelLoc));
工作簿wb=WorkbookFactory.create(inputStream);
int numberOfSheet=wb.getNumberOfSheets();
对于(int i=0;isheet.getSheetName()
}
}捕获{}
}

错误告诉您POI找不到OOXML文件的核心部分,在本例中是内容类型部分。您的文件不是有效的OOXML文件,更不用说有效的.xlsx文件了。但它是一个有效的zip文件,否则会出现早期错误

Excel真的可以加载此文件吗?我希望它无法加载,因为异常通常是通过给POI一个常规的.zip文件触发的!我怀疑您的文件无效,因此出现异常


更新:在Apache POI 3.15中(从beta 1开始),有一组更有用的异常消息,用于解决此问题的更常见的原因。在这种情况下,您将获得更多描述性异常,例如和。只有当POI确实不知道您给出了什么,但知道它已损坏或无效时,才会显示此原始表单。

如果您通过了一个老派。xls f将.xls另存为.xlsx,然后它就可以工作了。

我对
.xls
文件也有同样的例外,但是在我打开文件并将其另存为
xlsx
文件后,下面的代码就可以工作了:

 try(InputStream is =file.getInputStream()){
      XSSFWorkbook workbook = new XSSFWorkbook(is);
      ...
 }

尝试仅将文件保存为Excel工作簿。而不是任何其他格式。它对我有效。我遇到了相同的错误。

如果Excel文件受密码保护,则会出现此错误。

如果尝试从同一源两次解析同一文件,也可能会看到此错误

我对文件进行了一次解析以进行验证,然后再次(从同一个InputStream)进行处理——这产生了上述错误


为了解决这个问题,我将源文件解析为两个不同的输入流,一个用于验证,另一个用于处理。

我使用XSSFWorkbook读取.xls,这导致了无效格式异常。我必须使用更通用的工作簿和工作表才能使其正常工作


这帮助我解决了我的问题。

我也遇到了同样的问题,不幸的是Excel可以毫不费力地打开它。我想知道API是否有任何部分可以对该文件进行测试。如果您确定该文件是有效的,并且没有损坏,那么最好是在POI Bugzilla问题跟踪器中打开一个bug,然后上传一个有问题的示例file供人们检查当试图在Windows上读取Excel文件时,当它从我的Mac导出为Excel格式时,会出现此错误。@user448787如果您确定它是有效的Excel.xlsx文件,请在中创建一个新错误并上载有问题的文件。在我的情况下,该文件确实无效。但是,有没有办法通过编程修复它lly?因为excel文件是由第三方生成的,我从来没有控制过它。说得很好@Wilts C,我在这个excel文件上只浪费了1个小时,你的答案中的“损坏”一词让我打开了excel窗口本身。然后windows也说了同样的。Uffffff…POI用法的一个很好的例子。通常HSSF/XSSF抽象解决了这个问题这都是上述类型的问题。我很确定不是!@Wilts-我在Windows中打开了同一个文件,一切正常。当我在Excel中找到数据末尾时发现了问题,但他问的是XLSX文件,而不是XLS。
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Sheet;
//.....

static final String excelLoc = "C:/Documents and Settings/Users/Desktop/testing.xlsx";

public static void ReadExcel() {
InputStream inputStream = null;
   try {
        inputStream = new FileInputStream(new File(excelLoc));
        Workbook wb = WorkbookFactory.create(inputStream);
        int numberOfSheet = wb.getNumberOfSheets();

        for (int i = 0; i < numberOfSheet; i++) {
             Sheet sheet = wb.getSheetAt(i);
             //.... Customize your code here
             // To get sheet name, try -> sheet.getSheetName()
        }
   } catch {}
}
 try(InputStream is =file.getInputStream()){
      XSSFWorkbook workbook = new XSSFWorkbook(is);
      ...
 }