Java 下载解析Excel文件 报错:jxl.read.biff.BiffException: Unable to recognize OLE stream

项目开发需要先下载excel文件,然后解析出内容,最后将内容分批次下发给APP端。
在创建Excel的解析实例Workbook时,发现构造函数的入参是InputStream,心中窃喜。

public static Workbook getWorkbook(InputStream is)

随即就将从HttpURLConnection处得到的InputStream内存流传给了Workbook,结果报错:

jxl.read.biff.BiffException: Unable to recognize OLE stream
    at jxl.read.biff.CompoundFile.(CompoundFile.java:116)
    at jxl.read.biff.File.(File.java:127)
    at jxl.Workbook.getWorkbook(Workbook.java:268)
    at jxl.Workbook.getWorkbook(Workbook.java:253)
    at com.bj58.lbg.chat.manage.utils.FileComp.downLoadExcel(FileComp.java:29)

在网上搜答案,说是excel的格式有要求,必须是xls;不能是xlsx。于是找FE同学另行生成xls。更换之后,却发现仍然报同样的错。
是下载得到的内容有误吗?带着这个疑问,先将excel保存到本地,然后打开,发现正常。核心代码为:

        InputStream instream = new FileInputStream("E:/test.xls");
        Workbook wwb = Workbook.getWorkbook(instream);

看来,Workbook接受FileInputStream类型。
但是,在Java开发中,是很少创建临时文件的,这点与APP开发不同。
向同事诉说问题现象,同事一句: 改用ByteArrayInputStream试试呢?
遂改随验,发现OK!
结论:不同类型的InputStream应该有不同的读写规范,workbook需要的传参是具体的子类。
最终代码附上:

    public static List downLoadExcel(String fileUrl) throws Exception {
        if(StringUtil.isBlank(fileUrl)){
            return null;
        }
        byte[] fileContent = HttpUtils.download(fileUrl);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(fileContent);
        Workbook wwb = Workbook.getWorkbook(byteArrayInputStream);
        List lists = new ArrayList();
        for (Sheet sheet : wwb.getSheets()) {
            if (sheet != null && sheet.getRows() > 0) {
                for (int i = sheet.getRows()-1; i >=0; i--) {
                    for (Cell cell : sheet.getRow(i)){
                        if (StringUtil.isBlank(cell.getContents())) continue;
                        lists.add(cell.getContents());
                    }
                }
            }
        }
        return lists;
    }
public static byte[] download(String urlLocation) {

    HttpURLConnection conn = null;
    InputStream is = null;
    try {
        URL url = new URL(urlLocation);
        conn = (HttpURLConnection)url.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(false);
        conn.setUseCaches(false);
        conn.setRequestMethod("GET");
        conn.setConnectTimeout(TIME_OUT);
        conn.connect();

        is = conn.getInputStream();
        return IOUtils.toByteArray(is);
    } catch (Exception e) {
        throw new RuntimeException("请求错误!", e);
    } finally {
        IOUtils.closeQuietly(is);
        if(conn != null) conn.disconnect();
    }
}

你可能感兴趣的:(Java)