解决POI导入EXCEL兼容问题

    公司项目中需要用到excel导入,在权衡使用jxl还是POI后,决定使用版本兼容性更好的POI。下面介绍一下使用poi遇到的问题:

    一开始写了一个工具类关键代码如下:

        HSSFWorkbook workbook = new HSSFWorkbook(in);

后面考虑到POI解析excel要考虑excel2003和2007之后的版本,参考网上大把的解决方法就有了如下的方法

        

    其中:XSSFWorkBooK类可以解析2007之后的excel版本

              HSSFWorkBook类则是解析2003的版本

这种写法看起来非常合理,也用了几个月,没想到最近又有一个功能模块用到了poi,导入功能测试的时候发现,我自己的excel导入没有任何问题,而同事导入测试时会报


为了测试问题的所在,我直接在工具类main方法中解析本地的excel,代码如下

 

结果还是报错:

这个错误说流已经被关闭,可是我并没有,思前想后,自己并没有关闭

         Workbook work = null;
            try {
                work = new HSSFWorkbook(stream);
            } catch (Exception e) {
                work = new XSSFWorkbook(stream);
            }

debug追踪了一下,发现执行完这段代码后不论是有没有进catch,work都是空,说明该输入流无法创建workbook对象

但是如果把file路径换成path2或path3就可以解析

这就无关乎是.xls还是.xlsx的事了,不过也可能是因为path2路径的文件后缀是强制改成.xlsx的(后面证实确实是)

没想明白具体是啥原因我接着跟踪springMvc传过来的file得到的InputStream有什么区别,结果发现:

path2和path3的文件获得的输入流的类型是FileInputStream,而path1的文件的类型是ByteArrayInputStream。

而HSSFWorkBook能解析FileInputStream,XSSFWorkBook则可以解析ByteArrayInputStream。

这就让我想到了是不是两个获得WorkBook顺序的问题,如图:


两个语句换个顺序后发现果真是,但是又出现新问题,换了顺序后,path1能解析,但是path2和path3又不能解析,也就是说输入流经过第一个语句进入到catch语句后流似乎被自动关闭(个人猜测)

咋办嘞。。。。

突然想到两个文件获得输入流不同,是不是可以通过判断输入流的不同,进而手动选择是用HSSFWorkbook还是XSSFWorkbook。贴代码(暂时可行)


哈哈,,,,,,虽然土,

虽然解决了,但总感觉不怎么靠谱,继续寻找办法

找到一个别人找到的方法,地址:https://www.jianshu.com/p/a7eca64237bd

poi官方给出了的解决方案是:


测试通过,完美~,给遇到poi兼容问题的同学参考

本文仅个人观点,如有错误请指正!