尝试读取XLSX文件时出现NullpointerException

时间:2013-08-16 13:53:40

标签: java excel apache-poi

我目前有此代码使用apache POI打开xlsx文件

File existingXlsx = new File("/app/app.xlsx");
System.out.println("File Exists: " + existingXlsx.exists());

Workbook workbook = WorkbookFactory.create(existingXlsx);

当我尝试执行此操作时,我得到以下输出

File Exists: true
java.lang.NullPointerException
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:270)
    at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:159)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:186)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:91)

我尝试打开的文件可以在Excel中打开并正确显示数据,如何让POI读取XLSX文件?

这是打破的文件;

https://mega.co.nz/#!FJMWjQKI!CzihQgMVpxOQDTXzSnb3UFYSKbx4yFTb03-LI3iLmkE

修改

我也尝试过,导致同样的错误;

Workbook workbook = new XSSFWorkbook(new FileInputStream(existingXlsx));

修改

我找到了抛出异常的行;

WorkbookDocument doc = WorkbookDocument.Factory.parse(getPackagePart().getInputStream());
this.workbook = doc.getWorkbook();

Map<String, XSSFSheet> shIdMap = new HashMap<String, XSSFSheet>();
for(POIXMLDocumentPart p : getRelations())
{
    if(p instanceof SharedStringsTable) sharedStringSource = (SharedStringsTable)p;
    else if(p instanceof StylesTable) stylesSource = (StylesTable)p;
    else if(p instanceof ThemesTable) theme = (ThemesTable)p;
    else if(p instanceof CalculationChain) calcChain = (CalculationChain)p;
    else if(p instanceof MapInfo) mapInfo = (MapInfo)p;
    else if (p instanceof XSSFSheet) {
        shIdMap.put(p.getPackageRelationship().getId(), (XSSFSheet)p);
    }
}

stylesSource.setTheme(theme); <== BREAKS HERE

修改

经过一些研究POI似乎无法找到styles.xml和workbook.xml,我发现这很奇怪,因为像TextWrangler这样的简单读者显示了档案的结构,向我展示了样式xml。

我该如何解决这个问题?是否有一个默认的styles.xml和workbook.xml可以插入到存档中?

3 个答案:

答案 0 :(得分:5)

现在我已经下载了最新的软件包:

  • poi-src-3.9-20121203.zip(作为来源)
  • xmlbeans-2.6.0.zip
    • jsr173_1.0_api.jar
    • resolver.jar
    • xbean.jar
    • xbean_xpath.jar
    • 的xmlbeans-qname.jar
    • xmlpublic.jar
  • OOXML-架构-1.1.jar
  • DOM4J-1.6.1.jar
  • 公地编解码器-1.8.jar
  • 共享记录-1.1.3.jar
  • ant.jar(ant 1.7)

你的 test2.xlsx 被没有问题地阅读了:

  public static void main(String arg []){
    try {
      //File existingXlsx = new File("/app/app.xlsx");
      File existingXlsx = new File("c:/Java/poi-3.9/test-data/__theproblem/test2.xlsx");
      System.out.println("File Exists: " + existingXlsx.exists());

      Workbook workbook = WorkbookFactory.create(existingXlsx);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

您确定在POI文档中推荐使用 ooxml-schemas-1.1.jar 吗?

修改

嗯。它也适用于jar。

  1. 我已从下载 poi-bin-3.9-20121203.tar.gz http://poi.apache.org/download.html

  2. 在Eclipse中创建了一个新项目,从zip中提取了所有的jar:

    • LIB /公地编解码器-1.5.jar
    • LIB /共享记录-1.1.jar
    • LIB / DOM4J-1.6.1.jar
    • LIB /的junit-3.8.1.jar
    • LIB / log4j的-1.2.13.jar
    • LIB / POI-3.9-20121203.jar
    • LIB / POI-例子-3.9-20121203.jar
    • LIB / POI-excelant-3.9-20121203.jar
    • LIB / POI-OOXML-3.9-20121203.jar
    • LIB / POI-OOXML-架构 - 3.9-20121203.jar
    • LIB / POI暂存器-3.9-20121203.jar
    • LIB / STAX-API-1.0.1.jar
    • LIB /的xmlbeans-2.3.0.jar
  3. 添加测试xlsx:
    • 测试数据/ test2.xlsx
  4. 测试Java:
    • 的src / XlsxReadTest1.java
  5. 来源:

        import java.io.File;
        import org.apache.poi.ss.usermodel.Workbook;
        import org.apache.poi.ss.usermodel.WorkbookFactory;
    
        public class XlsxReadTest1 {
          public static void main(String arg []){
            try {
    
              File existingXlsx = new File("c:/Java/__Work/apache_POI/poi-3.9-bin/test-data/test2.xlsx");
              System.out.println("File Exists: " + existingXlsx.exists());
    
              Workbook workbook = WorkbookFactory.create(existingXlsx);
    
              System.out.println("A1: " + workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
    
            } catch (Exception e) {
              e.printStackTrace();
            }
          }
        }
    
    1. 运行。 (试过jdk1.7.0_07,jdk1.6.0_31)

    2. 结果:

      File Exists: true
      A1: Testing Edit
      
    3. 测试修改”是文件第一张纸上第一个单元格的内容。

      我想,你可以从头开始尝试这个。

      (也许你正在为你的项目使用其他jar,它们会干扰类加载器中的这些jar?类加载器是一个狡猾的人......)

答案 1 :(得分:4)

我猜你刚刚使用了错误的poi包。 尝试下载以下内容或从页面检查最新版本。

以下我在Eclipse开发中测试过:

http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.9-20121203.zip 提取它,并将所有的jar包含到你的eclipse lib中

eclipse structure

我结合了user1234的答案和我自己的方法,两者都在处理你的test2.xlsx

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

            import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
            import org.apache.poi.openxml4j.opc.OPCPackage;
            import org.apache.poi.ss.usermodel.Cell;
            import org.apache.poi.ss.usermodel.Row;
            import org.apache.poi.ss.usermodel.Sheet;
            import org.apache.poi.ss.usermodel.Workbook;
            import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
            import org.apache.poi.xssf.usermodel.XSSFWorkbook;
            import org.apache.xmlbeans.XmlException;


            public class Main {

                /**
                 * @param args
                 */
                public static void main(String[] args) {
                    //      File existingXlsx = new File("app.xlsx");

                    File file = new File("test2.xlsx");
                    FileInputStream fs;
                    try {
                        fs = new FileInputStream(file);

                        OPCPackage xlsx = OPCPackage.open(fs);
                        XSSFExcelExtractor xe = new XSSFExcelExtractor(xlsx);
                        System.out.println(xe.getText());


                    } catch (FileNotFoundException e1) {
                        e1.printStackTrace();
                    } catch (XmlException e) {
                        e.printStackTrace();
                    } catch (OpenXML4JException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    /// -------------- Another approach

                    File existingXlsx = new File("test2.xlsx");
                    System.out.println("File Exists: " + existingXlsx.exists());

                    try {
                        Workbook workbook = new XSSFWorkbook(new FileInputStream(
                            existingXlsx));

                        Sheet worksheet = workbook.getSheet("Filter criteria");
                        Row row1 = worksheet.getRow(0);
                        Cell cellA1 = row1.getCell((short) 0);
                        String a1Val = cellA1.getStringCellValue();


                        System.out.println("A1: " + a1Val);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

            }

最后我得到了结果:

enter image description here

答案 2 :(得分:1)

如果你想阅读.xlsx,请试试这段代码(使用apache poi 3.9):

    File file = new File("/app/app.xlsx");
    FileInputStream fs = new FileInputStream(file);
    OPCPackage xlsx = OPCPackage.open(fs);
    XSSFExcelExtractor xe = new XSSFExcelExtractor(xlsx);
    System.out.println(xe.getText());

以上代码应显示app.xlsx文件的内容。