Java使用POI读取Excel文件异常
系统里一个通过 Excel 批量导入数据的功能,一直报异常:java.io.IOException: Your InputStream was neither an OLE2 stream, nor an OOXML stream
首先我可以确定这个功能之前一定是好的,因为之前系统也用了挺久。
但是现在不知道为什么报异常,拿异常信息去百度搜了一下,大多是说什么 maven 打包的问题之类的,或者是文件格式不对,xls 和 xlsx 不兼容。
但我的文件是放到七牛的啊。。。所以排除 maven 打包,至于文件格式,我也都试了,重新上传替换,还是报一样的异常。
还在 StackOverFlow 上搜到说可能是流不可读,要转换一下。
1 | public static byte[] getBytes(InputStream is) throws IOException { |
也试了,一样不行。
没办法,只能断点进去看了,根据异常,跟踪到以下代码。
1 | public static Workbook create(InputStream inp, String password) throws IOException, EncryptedDocumentException { |
发现 fm
的值是 HTML
,它认为我的文件是 HTML,不是 Excel 文件,所以才会报异常。
这就好玩了,我明明是个 Excel,为什么这里会认为是个 HTML 呢?
我也是百思不得其解。
于是又去看代码,然后我发现似乎有点不对劲。
1 | URL url = new URL(resource); |
这里直接一行代码通过 URL 类获取流,会不会是缺了请求头被拦截了?毕竟啥请求头都没有的话,是很容易被拦截的。
于是我就拿 postman 发请求,把请求头都去掉,结果给我返回了这个。
1 | <html> |
擦,难怪被认为是 HTML。
把请求头加上再发请求,这次成功返回了文件流。
既然找到问题了,那就改吧。
1 | resource = resource.replace("http://","https://"); |
加上 User-Agent 和 Host,同时顺便把 http 换成了 https。
重启,上传,可以了,没有报错!
至于为什么之前可以现在不行,我猜测是七牛那边更新,加了拦截规则吧。
但是又出现有几条数据无法导入的问题,原因是我的 Excel 表里有一列是地址信息,后台会通过高德解析该地址。
但是一直解析失败,后面看了好久,才发现是地址含有空格,删除空格重新导入,成功!淦!