场景
注意是导出文件的场景,不是普通的现在文件,导出文件一般先要生成文件然后在下载文件,比如企业中经常用到的excel导出功能,先生成excel表格。在下载excel表格
如果现在让你做这么一个导出excel的功能你第一时间会想到什么?一般都会想到在文件生成之后在response中声明Content-Type的MIME为二进制文件浏览器会自动进行下载,这是在response上面做文章,整个过程发了一次请求
在实际开发过程中还看到一种做法:不在response上面做文章,直接在服务器上生成可以下载的文件,然后返回文件的路径,js在请求下载该文件,这是在js上做文章,整个过程发了两次请求
下面分别看一下两种思路的实现方案
在response上声明下载
在Java Spring框架中你可以这么写
@GetMapping("/export")
public void export(HttpServletRequest request, HttpServletResponse response,SwaggerUserFindVO user) throws IOException {
//set header
String fileName = "用户数据导出"+System.currentTimeMillis()+".xls";
String userAgent = request.getHeader("user-agent").toLowerCase();
// WIN10 IE EDGE 浏览器 和其他系统的ie
if (userAgent.contains("msie") || userAgent.contains("like gecko") ) {
fileName = URLEncoder.encode(fileName, "UTF-8");
//非IE
} else {
fileName = new String(fileName.getBytes(),"ISO8859-1");
}
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
//write file
OutputStream os = response.getOutputStream();
//组装excel
XSSFWorkbook wb = createWorkbook();
wb.write(os);
os.flush();
os.close();
}
最后直接在浏览器地址栏输入路径,用GET请求下载即可,整个过程一次请求
在js中请求文件下载
后端
@RequestMapping(value = "/export",produces = "application/text; charset=utf-8")
@ResponseBody
public String exportKeywordSceneMonitoringData(HttpServletRequest request) {
//容器根path,这个地方生成的文件可以被容器直接访问
String path = request.getSession().getServletContext().getRealPath("/")
//定义临时目录
String folderName = "/tempLoad";
//创建目录
File file = new File(path + folderName);
if (!file.exists()) {
file.mkdirs();
}
//文件名字
fileName = "/文件导出.xlsx";
StringBuilder filePath = new StringBuilder(path).append(folderName).append(fileName);
//生成此文件
SXSSFWorkbook workbook = new SXSSFWorkbook();//TODO
FileOutputStream out = new FileOutputStream(filePath);
workbook.write(out);
//返回文件名称
return folderName + fileName;
}
前端
var params = {};
$.ajax({
type: 'post',
url: '../app/export',
data: params,
dataType: 'text',
success: function(_fileName){
if (_fileName != '') {
//浏览器地址栏给生成的文件发送GET请求即可下载
window.location.href = "../" + _fileName;
}
},
error: function(){
}
});
在js中控制下载,整个过程两次请求
评论 (0)