[alibaba/easyexcel]web重复多次写入,导出的excel不能正常打开,提示”部分内容有问题“

2024-05-24 197 views
8

触发场景描述 web导出,参考demo重复多次写入,为了在发生异常时能够返回json格式的错误信息,设置了autoCloseStream(Boolean.FALSE)不关闭流。 导出时无任何异常信息,但导出的文件无法正常打开,提示:发现“xxx.xlsx”中的部分内容有问题。 触发Bug的代码 autoCloseStream(Boolean.FALSE) 如果不设置这行代码,导出的文件可以正常打开。

回答

5

试试在所有导出进行完成后进行finish()操作,不执行这个操作,excel的内容仍然在内存,没有同步到硬盘,得到的会是一个空文件

5

是的,现在所有导出进行完成后我有调用finish()操作,代码:excelWriter.finish();

7

是的,现在所有导出进行完成后我有调用finish()操作,代码:excelWriter.finish();

我翻了下代码,我感觉你对这个参数的理解有误,一般excelWriter调用finish()之前是可以连续操作的,autoCloseStream这个参数的作用是指你传入的时输出流的的时候不自动关闭输出流,继续执行后续操作,如果你是填写的是输出到文件,那么就会产生一个bug,这个文件打开的流没办法关闭了

0
try {
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");

    String fileName = URLEncoder.encode("xxx", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
            .autoCloseStream(Boolean.FALSE)
            .head(service.getHead())
            .build();
    WriteSheet writeSheet = EasyExcel.writerSheet("xxx").build();
    int pageNo = 1;
    List<Data> data;
    do {
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        datas= service.getDatas(param, pageNo++, 1000);
        if (datas!= null && datas.size() > 0) {
            excelWriter.write(datas, writeSheet);
        }
    } while (datas!= null && datas.size() > 0);
    excelWriter.finish();
} catch (Exception e) {
    response.reset();
    throw new BaseException(e.getMessage());
}

这个是我的代码,我想出错的时候返回json,还想连续的写数据,该如何设置呢

7

只去掉.autoCloseStream(Boolean.FALSE)试试,你的写法应该没问题

9

去掉后导出的文件没问题,可以打开,不过如果我在取数据的时候如果发生的异常,我没有办法给前端做出有效的提示。就是异常后response.reset();无法执行成功。

3

response.reset() 貌似是用来来清除首部的空白行。已经写入的话貌似没作用,试试去掉, 或者,先生成excel文件,没问题之后,再写response 还有,finish()才会输出到流,如果前面可能发生异常,试试这么写

try {

    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
            .head(service.getHead())
            .build();
    WriteSheet writeSheet = EasyExcel.writerSheet("xxx").build();
    int pageNo = 1;
    List<Data> data;
    do {
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        datas= service.getDatas(param, pageNo++, 1000);
        if (datas!= null && datas.size() > 0) {
            excelWriter.write(datas, writeSheet);
        }
    } while (datas!= null && datas.size() > 0);

    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");

    String fileName = URLEncoder.encode("xxx", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    excelWriter.finish();
} catch (Exception e) {
    throw new BaseException(e.getMessage());
}
7

问题解决了,感谢! 顺便再问一下,如果因为异常导致excelWriter.finish()没有执行到,会有什么影响?有办法解决么?

3

没有影响,就是前面的代码没有用了,然后这块内存也会被回收掉,如果有打开文件之类的,不要忘记关掉就可以了