EasyExcel 导出 cannot be resolved to absolute file path because it does not reside in the file system
问题:
开发环境没问题,测试通过,但是打包发到测试环境报错,报错内容标题,本人的文件模板是放在 resource
文件下的,也就是在我们的 jar 包中。
按照这个大佬的说法是文件在打包时url的protocol 类型变了导致报错,所以可以使用字节流输出,具体请看:字节流解决方式
但是我的模板需要动态导出下拉的内容选项,EasyExcel 也没有提供字节流输出还能填充数据的方法,所以用了字节流就不能填充数据了,这时我想起前端同事说因为前端没有拿到Content-disposition
所以报错了,那么就暴露给它试试?
解决方案
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
public static void ordinaryExcelDownload(HttpServletResponse response, String fileName, String filePath, Object data) {
try {
// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
// 设置Header响应头将Content-Disposition属性暴露给前端获取
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
// 设置Content-Disposition属性值
response.setHeader("Content-disposition", "attachment;filename=utf-8''" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream()).withTemplate(filePath).sheet().doFill(data);
} catch (IOException e) {
e.printStackTrace();
}
}
完美解决,没加之前在本地环境是可以拿到 Content-Disposition
的,为啥上了测试不行,因为 Linux 和 Windows 的原因?暂时还不清楚。那为什么暴露了Content-Disposition
就可以呢,从后端的角度来看,可以仔细的看代码的顺序,我们是暴露了之后才去 getOutputStream
的。。。估计跟这个有关所以拿到到文件流,所以就没问题,猜测大概这么回事,没仔细研究,感兴趣的大佬可以看看,有结果了欢迎评论讨论。
兄弟们我后面发现我以为我解决问题了,结果早上上去侧式环境上看,我还是没有解决,我上面不是说了,我导出的模板需要填充数据嘛,所以必须使用文件流,并不是的,EasyExcel 提供了处理流,流无论是文件流还是字节流都可以。
看到我的 ordinaryExcelDownload
方法了?我的报凑是从
public void hbProjectInfoExport(HttpServletResponse response) throws IOException {
String absolutePath = new DefaultResourceLoader().getResource("classpath:temp/md_temp.xlsx").getFile().getAbsolutePath();
ExportUtil.ordinaryExcelDownload(response,"XXXXX表",absolutePath,null);
}
.getFile()
的时候报错了,它说找不到问题,引用上面大佬的话就是Linux环境下因为和 Jar 包一起打包的原因,所以。。。
那么这里不用获取文件,直接获取流,不就好了,可以转为字节流在转为文件,在填充是不是就好了,这是一种方式,但是
.withTemplate(filePath)
可以是个流啊,之前真的没注意看【😂】,直接获取流传入不就好了。
改为:
public void hbProjectInfoExport(HttpServletResponse response) throws IOException {
org.springframework.core.io.Resource resource = new DefaultResourceLoader().getResource("classpath:temp/md_temp.xlsx");
ExportUtil.ordinaryExcelDownload(response,"XXXXX表",resource.getInputStream(),null);
}
额,真垃圾,这都没注意看,注意看就没那么多事了。