1、背景
excel下载和导出时,使用response返回输出流,页面进行下载
2、异常信息
No converter for [class xxx.ResponseData]
with preset Content-Type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:312) ~[spring-webmvc-5.3.23.jar:5.3.23]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:183) ~[spring-webmvc-5.3.23.jar:5.3.23]
3、原因
导出时,将文件返回流写入HttpServletResponse,异常返回时(例如:内容为空,无法导出异常提示)使用的也是这个response,当response写入了部分文件流后,就无法正常展示response。
这两种返回的请求头格式是不一样的.
4、解决方案
方案一:
导出时,不直接使用response.getOutputStream(),先使用自定义输出流,最后写完时,再写入response.getOutputStream()
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(outputStream);
//...excel写入逻辑
excelWriter.finish();
ExcelExportUtil.setResponseHeader(request.getResponse(), request.getFileName());
//最后写入response,保证异常正常输出
outputStream.writeTo(request.getResponse().getOutputStream());
return true;
} catch (Exception e) {
request.getResponse().reset();
//日志处理...
}
方案二:
拦截异常,将response重置
try {
}catch (Exception e) {
log.error("报表导出异常", e);
response.reset();
//throw new ResultException...
}