最近开发点小功能,有下载excel模板文件的需求,途中遇到了一个坑,特此记录一下,让有同样疑惑的小伙伴不用在浪费时间。
坑:
以下是模板文件在项目中的位置:
这是相关代码:(问题代码)
public void templateFileDownload(HttpServletResponse response) throws Exception {
//获取文件的路径
String path = getClass().getResource("/template/" + TEMPLATE_FILE_NAME).getPath();
//解决文件名乱码
String filePath = URLDecoder.decode(path, "UTF-8");
// 设置输出的格式
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodeFileName = URLEncoder.encode(TEMPLATE_FILE_NAME, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
FileUtils.copyFile(new File(filePath), response.getOutputStream());
response.flushBuffer();
}
用post本地测试是可以下载的(这里还有个问题就是postman下载的文件名字一直是<response.xlsx>,我怎么设置都没有用,postman是会有这个问题的,遇到了不用纠结直接跳过。)
放到测试环境之后,springboot项目打成jar包之后这样会提示:No such file or directory
经查jar中的文件要通过流的方式输出,改为以下方式即可:
public void templateFileDownload(HttpServletResponse response) {
//获取文件的路径 (打包后获取方式)
try (InputStream inputStream = this.getClass().getResourceAsStream("/template/" + TEMPLATE_FILE_NAME); ServletOutputStream out = response.getOutputStream();) {
// 设置输出的格式
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String encodeFileName = URLEncoder.encode(TEMPLATE_FILE_NAME, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
int i;
while ((i = inputStream.read()) != -1) {
out.write(i);
}
out.flush();
} catch (IOException e) {
log.info("模板下载失败:{}", e.toString());
}
}
另外:你可以试试jdk1.7以后关闭资源的新方式,try with resource 只要这个资源实现了Closeable接口,你就可以很方便的把他放在try()中