文件下载(比如模板下载),方法之一是先在服务器上创建一个路径,再通过代码里面写死或配置去读取这个路径的下的这个文件进行下载。 这个方法的缺点就是需要提前创建好这个目录,并给文件路径给与读写权限,上线时还有可能忘记做这个操作了。今天主要是写一个把文件放在项目里面,打包后运行可直接可以下载的功能。
项目录结构
下载控制类
package com.yulisao.rest;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.walmart.presale_server.util.FileUtil;
import com.walmart.presale_server.util.MyStringUtils;
@RestController
@RequestMapping("/api")
public class FileDownloadRest {
private static final Logger LOG = LoggerFactory.getLogger(FileDownloadRest.class);
@GetMapping("dowmTemplate/{name}")
public Object downLoadExcel(@PathVariable("name") String fileName,HttpServletRequest request) {
ResponseEntity<InputStreamResource> response = null;
try {
String userAgent = request.getHeader("USER-AGENT"); // 获取请求头里的参数
String newFileName = FileUtil.getNewFileName(userAgent,fileName);
response = FileUtil.downloadFile(fileName+".xlsx",newFileName);
} catch (Exception e) {
LOG.error("下载模板失败");
}
return response;
}
}
下载工具类
package com.yulisao.util;
import java.io.*;
import java.net.URLEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
public class FileUtil {
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
/**
* 下载模板
* @param fileName 模板文件名称或者编号标识
* @param newFileName 下载后模板新文件名称
* @return
*/
public static ResponseEntity<InputStreamResource> downloadFile(String fileName, String newFileName) {
String route = "excel" + File.separator;
String path = null;
ResponseEntity<InputStreamResource> response = null;
try {
path = route + fileName;
ClassPathResource classPathResource = new ClassPathResource(path);
InputStream inputStream = classPathResource.getInputStream();
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Content-Disposition",
"attachment; filename=" + newFileName + ".xlsx");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
response = ResponseEntity.ok().headers(headers)
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(inputStream));
} catch (FileNotFoundException e1) {
log.error("找不到指定的文件", e1);
} catch (IOException e) {
log.error("获取不到文件流", e);
}
return response;
}
/**
* 浏览器传参 转码
* @param userAgent
* @param fileName
* @return
* @throws UnsupportedEncodingException
*/
public static String getNewFileName(String userAgent, String fileName) throws UnsupportedEncodingException {
String newFileName = "模板";
switch (fileName) {
case "template-1" :
newFileName = "用户批量导入模板";
break;
case "template-2" :
newFileName = "用户资金导入模板";
break;
default:
newFileName = "模板";
}
// 以免新文件名称编码到浏览器后变成乱码
if (userAgent != null && userAgent.indexOf("chore") >= 0) {
newFileName = new String(fileName.getBytes("UTF-8"), "ISO859-1");
} else {
newFileName= URLEncoder.encode(fileName,"UTF-8"); //其他浏览器
}
return newFileName;
}
}
通过baseurl + /api/dowmTemplate/template-2 就可以下载一个名为 用户资金导入模板.xlsx的文件