vue实现word文件下载之开放权限
所以如果想要让客户端可以访问到其他的首部信息,服务器不仅要在header里加入该首部,还要将它们在 Access-Control-Expose-Headers 里面列出来,即上面后端的处理方法。此处极为重要,因为不添加的话前端vue的axios请求无法获取响应头headers的filename字段,就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部。因为不编码传递到前端后可能会
使用浏览器自带的导出功能
此种方法适用于GET请求
window.location.href = 完整的请求地址
使用流的形式下载文件
后端
InputStream input = null;
OutputStream out = null;
input = new BufferedInputStream(new FileInputStream("D:\\test\\wordFile\\final.docx"));
String fileName = "我的word文件";
//response.setContentType("application/msword");//doc文件
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");//docx文件
//计算文件大小
int available = input.available();
response.addHeader("Content-Length", String.valueOf(available));
response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(fileName+".docx", "UTF-8"));
response.setHeader("filename",URLEncoder.encode(fileName+".docx", "UTF-8"));
response.setHeader("Access-Control-Expose-Headers", "filename");
out = response.getOutputStream();
byte[] b = new byte[512];
if (out != null) {
if (input != null) {
int len = 0;
while ((len = input.read(b)) > 0) {
out.write(b, 0, len);
}
} else {
System.out.println("InputStream为空。。。");
}
} else {
System.out.println("OutputStream为空。。。");
}
out.flush();
input.close();
out.close();
暴露从header里可以获取的字段信息
注意: response.setHeader(“Access-Control-Expose-Headers”, “filename”);
此处极为重要,因为不添加的话前端vue的axios请求无法获取响应头headers的filename字段,
原因:
默认情况下,header只有六种 simple response headers (简单响应首部)可以暴露给外部:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
Access-Control-Expose-Headers 就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部。
所以如果想要让客户端可以访问到其他的首部信息,服务器不仅要在header里加入该首部,还要将它们在 Access-Control-Expose-Headers 里面列出来,即上面后端的处理方法
为了防止乱码而进行编码
注意: 因为不编码传递到前端后可能会造成乱码。
response.setHeader(“filename”,URLEncoder.encode(fileName+“.docx”, “UTF-8”));
前端VUE
在页面中调用下载接口并处理返回的文件数据
<script>
export default {
methods: {
//参数转化
function obj2params(obj) {
var p = [];
for (var key in obj) {
p.push(key + '=' + encodeURIComponent(obj[key]));
}
return p.join('&');
}
downReport() {
// 加载loading
this.loading = true
this.loadingText = '正在导出模板...'
this.$axios({
method: 'post',
baseURL: 'http://127.0.0.1:9010',
url:'/upload/DataManagerController/downLoadReport.html',
data: obj2params(data),
headers: {'Content-Type': 'application/x-www-form-urlencoded',},
responseType: 'blob',
timeout: 600000,
data: {}
}).then((res) => {
// 关闭loading
this.loading = false
var params={sbid:"19"};
var filename=res.headers['filename'];
//指定要下载的文件的类型是docx,编码为utf-8
let blob = new Blob([res.data], {type: `application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8`});
let objectUrl = URL.createObjectURL(blob);
let link = document.createElement("a");
//const fileName = res.headers["content-disposition"].match(/filename=(\S*).docx/)[1];
//let fname=decodeURIComponent(fileName)+'.docx'
let fname=decodeURIComponent(filename);
console.log("文件名称:"+fname);
link.href = objectUrl;
link.setAttribute("download", fname);
document.body.appendChild(link);
link.click();
}).catch((error) => {
console.log(error);
// 关闭loading
this.loading = false;
});
}
}
};
</script>
处理返回的文件数据:
注意: 不论后端在header添加的字段是大写还是小写,前端能获取的都是小写的字段。
前端解码:decodeURIComponent(filename)
切记: 如果你的axios请求返回的res做了事先处理只返回data的情况下,你在页面中是获取不到header里的字段数据的,需要做if判断处理,如下所示:
更多推荐
所有评论(0)