一、前端
1、注意事项
- 异步是请求不能下载文件的,因为ajax本身无法触发浏览器的下载功能,它的response由JavaScript处理,JavaScript无法和磁盘进行交互,否则这会是一个严重的安全问题,js无法调用到浏览器的下载处理机制和程序,会被浏览器阻塞;使用ajax下载完成后,response以字符串的形式存储在内存中
2、解决
-
打开新标签页
window.open('download')
-
链接跳转
window.location.href=`download`
-
提交表单
<!-- 空表单,下载使用 --> <form id="exportForm"></form>
//改变表单的提交地址为下载的地址 $("#exportForm").attr("action","download") $("#exportForm").attr("method","get") $("#exportForm").submit()
-
axios
//解决了其他方式不能携带token的问题 import axios from 'axios' import { getToken } from '@/utils/auth' import { Message } from 'element-ui' //下载文件 export function downloadFile(url){ axios({ url: process.env.VUE_APP_BASE_API+url, headers: { 'Authorization': 'Bearer ' + getToken() }, params: { name:'kimi' }, method: 'GET', responseType: 'blob' }).then(res=> { //使用后端返回的res.dada二进制数据构建Blod对象 const blob = new Blob([res.data]) //无流数据返回 if(blob.size===0){ Message.error("文件下载失败!") }else{ //响应头中获取文件名 const fileName = res.headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1') //创建url并指向 blob const url = window.URL.createObjectURL(blob) //创建1个a标签元素 const aDom = document.createElement('a') aDom.href = url aDom.download = decodeURIComponent(fileName) aDom.style.display = 'none' //点击它 aDom.click() //释放该url window.URL.revokeObjectURL(url) } }) }
二、后端
/**
* download
*/
@GetMapping("download")
@ResponseBody
public void download(HttpServletResponse response){
final String fileName="table_templat.xlsx";
//resources下的文件
URL url=this.getClass().getClassLoader().getResource("file/"+fileName);
//not exists
if(url==null){
return;
}
File file = new File(url.getPath());
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
bis = new BufferedInputStream(new FileInputStream(url.getPath()));
bos = new BufferedOutputStream(response.getOutputStream());
//清空response
response.reset();
//设置response的header
//下载的文件名
response.addHeader("content-disposition", "attachment;filename="+new String(fileName.getBytes(StandardCharsets.UTF_8.name()), StandardCharsets.ISO_8859_1.name()));
//文件长度
response.addHeader("content-length", ""+file.length());
//内容类型 application/octet-stream
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
//字符集
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
//写出
byte[] buffer = new byte[1024];
int length;
while((length=bis.read(buffer))!=-1){
bos.write(buffer,0,length);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try{
if(bis!=null){
bis.close();
}
if(bos!=null){
bos.close();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}