一言不合先抛个异常
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
HSSFWorkbook workbook = new HSSFWorkbook(in);
这段异常表示excel版本和workbook的类型不匹配导致的, HSSFWorkbook不支持Excel2007之后的文件版本, poi提供了XSSFWorkbook类型支持后面的版本,
XSSFWorkbook workbook = new XSSFWorkbook(in);
但是这段代码对老版本的excel不兼容, 查看文档和源码发现HSSFWorkbook和XSSFWorkbook都实现了Workbook接口, 按照网上推荐的方法, 把代码修改成了
Workbook workbook = null;
try{
workbook = new HSSFWorkbook(in);
}catch(Exception e){
workbook = new XSSFWorkbook(in);
}
然后. 成功的抛出了另一个异常
java.io.IOException: Stream closed
这.... 节奏不对啊, 进入try块之后顺手把流关了, 这个方法也搞不定, 难道不用流来做参数?? 还是先判断一下流的类型????
怎么判断???? 我是不会, 好吧, 看文档, 我相信apache肯定能解决这个问题
好了, 代码改成了
Workbook workbook = WorkbookFactory.create(in);
一切都正常了. 那么这个方法一定是判断了文件类型的, 废话不多说, 贴源码
public static Workbook create(InputStream inp, String password) throws IOException, InvalidFormatException, EncryptedDocumentException {
// If clearly doesn't do mark/reset, wrap up
if (! inp.markSupported()) {
inp = new PushbackInputStream(inp, 8);
}
// Ensure that there is at least some data there
byte[] header8 = IOUtils.peekFirst8Bytes(inp);
// Try to create
if (NPOIFSFileSystem.hasPOIFSHeader(header8)) {
NPOIFSFileSystem fs = new NPOIFSFileSystem(inp);
return create(fs, password);
}
if (DocumentFactoryHelper.hasOOXMLHeader(inp)) {
return new XSSFWorkbook(OPCPackage.open(inp));
}
throw new InvalidFormatException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
}
当然, maven的依赖要改成这个了
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
网友评论