使用Apache POI读取xlsx文件时出现异常(org.apache.poi.openxml4j.exception - no content type [M1.13])?

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

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

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

代码:

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;XSSFCell cell = null;
    XSSFSheet sheet=null;
            try {
                loadFile();  //load give Excel
                if(validateIndex(SheetIndex))
                {
                    sheet  = workbook.getSheetAt(SheetIndex);
                    Iterator rowIter = sheet.rowIterator();
                    XSSFRow firstRow = (XSSFRow) rowIter.next();
                    Iterator 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 rowIter = sheet.rowIterator();
                     XSSFRow Row = (XSSFRow) rowIter.next();
                     Iterator 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 rowIter = sheet.rowIterator();
                            while(rowIter.hasNext())
                            {
                                row = (XSSFRow) rowIter.next();
                                Iterator 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 rowIter = sheet.rowIterator();
                            while(i<noOfRows)
                            {

                                row = (XSSFRow) rowIter.next();
                                Iterator 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;
 }

请帮我解决这个问题。

谢谢。

10个回答

26
这个错误告诉你,POI无法找到OOXML文件的核心部分,即内容类型部分。你的文件不是有效的OOXML文件,更不是有效的.xlsx文件。但它确实是一个有效的zip文件,否则你早就会收到其他错误信息了。
Excel真的能够加载这个文件吗?我预计它不能够,因为异常最常被触发的情况是给POI一个普通的.zip文件!我怀疑你的文件并不是有效的,因此才会出现这个异常。

.

更新: 在 Apache POI 3.15(从 beta 1 开始),更常见的问题会有一组更有帮助的异常消息。在这种情况下,您将获得更多描述性的异常,例如 ODFNotOfficeXmlFileExceptionOLE2NotOfficeXmlFileException。如果 POI 真的不知道你给它什么但又知道它是损坏或无效的,那么只有这个原始形式才会出现。


1
我也遇到了同样的问题,不幸的是Excel可以毫无问题地打开它。我想知道是否有API的一部分可以对文件进行测试。 - Andres Farias
如果您确定这是一个有效的文件,而不是损坏的文件,最好的方法是在POI Bugzilla问题跟踪器中打开一个错误,并上传一个示例有问题的文件供人们检查。 - Gagravarr
@user448787 如果您确认这是一个有效的Excel .xlsx文件,请在Apache POI Bugzilla上创建一个新的错误报告,并将有问题的文件上传到那里。 - Gagravarr
1
在我的情况下,该文件确实无效。但是,有没有办法通过编程来修复它呢?由于Excel文件是由第三方生成的,我无法控制它。 - Mr. 14
@Chieh 取决于文件有多少损坏。确保您正在使用最新版本的Apache POI,如果问题仍然存在,请在POI bugzilla中打开一个错误,并上传触发错误的最小文件。 - Gagravarr
显示剩余2条评论

15

我很确定当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 {}
}

1
@Wilts C说得非常好,我在这个Excel文件上浪费了整整1个小时,你的答案中提到的“损坏”一词让我打开了Excel窗口。然后Windows也显示了同样的信息。唉... - DJphy
POI使用的非常好的例子。通常,HSSF / XSSF抽象解决了上述所有问题。 - Aram Paronikyan
我非常确定这不是问题!@Wilts - 我在Windows中打开了同一个文件,一切都好。问题是当我到达Excel数据的末尾时发现的。 - Shai Alon
有关密码方面我能做些什么吗?我正在将xlxs转换为txt,如果Excel没有密码保护,它可以正常工作。 - aaa

9

如果您将一个老式的 .xls 文件传递到该 API 中,就会得到这个确切的错误。将 .xls 另存为 .xlsx,然后它就能正常工作了。


9

我曾试图使用XSSFWorkbook读取.xls文件,但结果出现了InvalidFormatException。为了解决这个问题,我必须使用更通用的Workbook和Sheet。

这篇文章帮助我解决了我的问题。


但他问的是XLSX文件,不是XLS。 - Shai Alon

2

如果您尝试从相同的源文件两次解析文件,则可能会看到此错误。

我曾经对文件进行一次解析以进行验证,然后再次(从相同的InputStream)进行处理 - 这导致了上述错误。

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


1

我对 .xls 文件出现相同的异常,但是当我打开文件并将其另存为 xlsx 文件后,下面的代码可以正常运行:

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

1

清理了代码(主要是注释掉了日志记录器),使其在我的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;
}
}

创建了这个小测试代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class ReadXLSXTest {

/**
 * @param args
 * @throws FileNotFoundException 
 */
public static void main(String[] args) throws FileNotFoundException {
    // TODO Auto-generated method stub


    ReadXLSX test = new ReadXLSX(new FileInputStream(new File("./sample.xlsx")));

    System.out.println(test.getSheetsName());
    System.out.println(test.getNumberOfSheet());


}

}

所有的操作都非常顺利,所以我猜测您可能有一个XLSX文件在某种程度上出现了“损坏”。建议尝试使用其他数据进行测试。

祝好, Wim


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

0

我能够通过以下两种方式解决这个问题:

  1. 使用 MS-EXCEL 打开并重新保存文件
  2. 使用 Woorbookfactory 打开文件: Workbook workbook = WorkbookFactory.create(byteFile);

0

尝试仅将文件保存为Excel工作簿格式。不要使用其他任何格式。这对我有用。我曾经遇到过同样的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接