Исключение NullpointerException при попытке прочитать файл XLSX

В настоящее время у меня есть этот код для открытия файла xlsx с использованием apache POI

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

Edit

Я также попытался, это приводит к той же ошибке;

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

Edit

Я нашел строку, в которой она выбрала исключение:

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

Edit

После некоторого исследования POI, похоже, не может найти styles.xml и workbook.xml, я нахожу это странным, потому что простой читатель, такой как TextWrangler, который показывает структуру архива, показывает мне стили xml.

Как это исправить? Есть ли стиль styles.xml по умолчанию и workbook.xml, который можно вставить в архив?

Ответ 1

Теперь я загрузил последние пакеты:

  • 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();
    }
  }

Вы уверены, что используете ooxml-schemas-1.1.jar, как рекомендует документация POI?

ИЗМЕНИТЬ

Хм. Это работает и для меня из jar.

  • Я загрузил poi-bin-3.9-20121203.tar.gz из http://poi.apache.org/download.html

  • Сделал новый проект в Eclipse, извлек все банки из zip:

    • Библиотека/Обще-кодек-1.5.jar
    • Библиотека/Обще-каротаж 1.1.jar
    • Библиотека /dom 4j-1.6.1.jar
    • Библиотека /JUnit -3.8.1.jar
    • Библиотека /log 4j-1.2.13.jar
    • Библиотека/пои-3.9-20121203.jar
    • Библиотека/пои-примеры-3.9-20121203.jar
    • Библиотека/пои-excelant-3.9-20121203.jar
    • Библиотека/пои-OOXML-3.9-20121203.jar
    • Библиотека/пои-OOXML-схемы-3.9-20121203.jar
    • Библиотека/пои-блокнотная-3.9-20121203.jar
    • Библиотека/StAX-апи-1.0.1.jar
    • Библиотека /XMLBeans -2.3.0.jar
  • Добавьте тест xlsx:
    • тест-данные/test2.xlsx
  • Тест Java:
    • ЦСИ /XlsxReadTest 1.java

Источник:

    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. Run. (Пробовали с помощью jdk1.7.0_07, jdk1.6.0_31)

  2. Результат:

    File Exists: true
    A1: Testing Edit
    

" Тестирование Edit" - это содержимое первой ячейки на первом листе вашего файла.

Я думаю, вы можете попробовать это, с нуля.

(Возможно, вы используете другие баночки для своего проекта, которые мешают этим баночкам в загрузчике классов? Классный загрузчик - хитрый парень...)

Ответ 2

Думаю, вы использовали неправильный пакет poi. Попробуйте загрузить следующее или вы проверите последнюю версию со страницы.

Следующее, что я тестировал в своей разработке Eclipse:

http://www.apache.org/dyn/closer.cgi/poi/release/bin/poi-bin-3.9-20121203.zip извлеките его и включите все банки в свой 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

Ответ 3

Если вы хотите прочитать .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.