最近開發點小功能,有下載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()中