尝试读取XLSX文件时发生NullpointerException
我目前有这个代码使用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));
编辑
我发现它正在抛出exception的行;
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似乎无法findstyles.xml和workbook.xml之后,我发现这很奇怪,因为像TextWrangler这样简单的阅读器,显示了存档的结构,显示了样式xml。
我该如何解决? 是否有一个默认styles.xml和workbook.xml,我可以插入到档案?
现在我已经下载了最新的软件包:
- 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
- 共享logging-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文档build议?
编辑
嗯。 它也适用于我的jar子。
-
我已经从http://poi.apache.org/download.html下载了poi-bin-3.9-20121203.tar.gz
-
在Eclipse中创build一个新项目,从zip中提取所有的jar包:
- LIB /公地编解码器1.5.jar
- LIB /共享logging-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
- 添加testingxlsx:
- testing数据/ test2.xlsx
- testingJava:
- SRC / XlsxReadTest1.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(); } } }
-
跑。 (用jdk1.7.0_07,jdk1.6.0_31尝试)
-
结果:
File Exists: true A1: Testing Edit
“ testing编辑 ”是文件第一张纸上的第一个单元格的内容。
我想,你可以从头开始尝试。
(也许你正在为你的项目使用其他的jar子,在类加载器中干扰这个jar子?类加载器是一个狡猾的家伙…)
我猜你刚刚使用了错误的poi软件包。 尝试下载以下内容,或从网页上检查最新版本。
以下我在我的Eclipse开发中进行了testing:
我结合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(); } } }
最后我得到了结果:
如果你想阅读.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的内容。