前言
本文介绍在Spring Boot项目中两种下载文件的方法:通过form表单方式下载和通过ajax请求文件转blob对象下载。
方法一: form表单方式下载
代码如下:
function formDownload(token, parameters){
var form=$("<form>");
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
form.attr("action",serviceUrl);
var fileInput1=$("<input>");
fileInput1.attr("type","hidden");
fileInput1.attr("name","token");
fileInput1.attr("value",token);
var fileInput2=$("<input>");
fileInput2.attr("type","hidden");
fileInput2.attr("name","filename");
fileInput2.attr("value",filename);
$("body").append(form);//将表单放置在web中
form.append(fileInput1);
form.append(fileInput2);
form.submit();//表单提交
form.remove();//移除
}
方法二:ajax请求文件转blob对象下载
后台返回json格式的数据,js中将字符串转为blob对象进行下载。
代码如下:
function ajaxDownload(token, parameters){
$.ajax({
type: "POST",
url: serviceUrl,
contentType: 'application/x-www-form-urlencoded;charset=utf-8',
data: {token:token, parameters:parameters},
dataType: "json",
success: function(res){
if (res.status === '0'){
var result = res.result;
var fname = result.name;
var fileStr= result.fileStr;
//兼容IE
const blob = new Blob([fileStr]);
if (window.navigator.msSaveBlob) {
window.navigator.msSaveBlob(blob, fname);
} else {
const eleLink = document.createElement('a');
eleLink.download = fname;
eleLink.style.display = 'none';
eleLink.href = URL.createObjectURL(blob);
document.body.appendChild(eleLink);
eleLink.click();
document.body.removeChild(eleLink);
}
} else {
console.log(res.message);
}
},
error:function(e){
console.log(e);
}
});
}
后台代码
主要例举方法一的后台代码,方法二在后台将文件转为字符串以JSON格式返回即可。
方法一的后台代码如下:
@RequestMapping(value="/download",method= RequestMethod.POST)
@ResponseBody
public void download(String token, String filename, HttpServletRequest request, HttpServletResponse response) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
//验证token
String useragent = request.getHeader("USER-AGENT").toLowerCase();
if(useragent.contains("msie")||useragent.contains("like gecko")||useragent.contains("trident")){
//ie11或者win10中用户代理字符串已经修改了,不再是“msie”了,添加了like Gecko,所以加上like gecko判断,防止IE中下载的文件名乱码。
fname = URLEncoder.encode(filename , "UTF-8");
}else{
fname = new String(filename.getBytes("utf-8"),"iso-8859-1");
}
response.setContentType("text/html;charset=UTF-8");
response.setHeader("Content-disposition", "attachment; filename="+ fname);
//获取输入流
InputStream is = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bis = new BufferedInputStream(is);
//获取输出流
bos = new BufferedOutputStream(response.getOutputStream());
//定义缓冲池大小,开始读写
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
}catch (Exception ex){
ex.printStackTrace();
}finally {
//关闭流
if(bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(bos != null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}