Your stream was neither an OLE2 stream, nor an OOXML stream

最近使用Apache poi 做excel导出的功能,遇到了如下问题:

Your stream was neither an OLE2 stream, nor an OOXML stream

起初对比其他的web工程,没有发现如何解决。最后找到抛出此异常的源码:
org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:75)

    public static Workbook create(InputStream inp) throws IOException, InvalidFormatException {
        if (!((InputStream)inp).markSupported()) {
            inp = new PushbackInputStream((InputStream)inp, 8);
        }

        if (POIFSFileSystem.hasPOIFSHeader((InputStream)inp)) {
            return new HSSFWorkbook((InputStream)inp);
        } else if (POIXMLDocument.hasOOXMLHeader((InputStream)inp)) {
            return new XSSFWorkbook(OPCPackage.open((InputStream)inp));
        } else {
            throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
        }
    }

可以看到,在调用WorkbookFactory.create(inputStream)来创建Workbook时,会根据文件类型(文件头)来区别、创建合适的Workbook对象。如果不满足前两个if条件里的hasPOIFSHeader()方法,就会抛出异常。而两个if里的hasPOIFSHeader()方法就是针对Excel2003和Excel2007的判断,读取文件流中的文件头(byte[8])信息去判断。

那既然是根据文件的头部信息去比对进行判断的,并且excel只有2003和2007两个版本,那为什么放在classpath下的excel模板读取后创建WorkBook时,文件header判断都不符合呢?

最后找到原因:maven编译打包时,将resources下的资源文件转码了。最终web工程打出的jar/war包,里面归档进去的excel模板文件都是乱码,文件头信息被修改,导致poi根本无法识别这样的excel文件。

解决办法:

项目的pom.xml中添加maven资源插件



    
           org.apache.maven.plugins
           maven-resources-plugin
           
               
                   xls
               
           
    

总结

1、推荐使用poi-ooxml中的WorkbookFactory.create(inputStream)来创建Workbook,因为HSSFWorkbook和XSSFWorkbook都实现了Workbook接口。(Excel2003和Excel2007两个版本在此通过文件header进行适配)

2、当你的工程中,需要放入一些静态资源文件作为模板,比如excel填充模板,word模板(里面有些固定样式,程序运行时用模板导出报表类的),这个时候,最好都配置maven去除资源文件不被转码。下面的链接有2种方式。

Maven 打包 过滤资源文件
https://blog.csdn.net/qing_mei_xiu/article/details/80661216

你可能感兴趣的:(Your stream was neither an OLE2 stream, nor an OOXML stream)