先谈谈遇到的问题吧:
1. 后端接口返回的blob文件流,你下载下来的文件是乱码的?
解决办法 :让你的后端设置流的编码为utf-8。请跟后端大佬说,一定要给blob格式的文件流。
2. 后端返回的blob文件流,并且已经设置了utf-8,但是你接受的接口返回值,依然是乱码?
解决办法: 肯定没有设置 responseType: "blob",我不知道你用的什么接口请求方式,你可以搜一下,怎么设置responseType: "blob"
3. 下载word文件里面内容是【object object】或者下载的图片是损坏的?
解决办法:参考以上的1和2答案,确定1和2都没有问题。
那么还有个原因就是:response 中还有一层data ,如果直接用blob流,文件里面就是object。你就把文件流的response.data一下
下面附上 后端返回blob的文件流,前端下载、打印、预览文件的方法
本人用的vue,不管你用的什么技术库,原理一样,都是js。废话少说,直接上代码:
下载功能实现:
// 调用下载接口,返回bolb文件流
axios({
method: "get",
url: this.proxyUrl + "/api/file/downloadFile", //后端下载接口地址
responseType: "blob", // 设置接受的流格式
params: { // get方式,请写params, post方式写data,这里是get方式的传参
fileId: this.selectedTabelRow[0].fileId,
type: val,
},
}).then((res) => {
// res 中还有一层data ,如果直接用blob流,文件里面是object,我就是犯错了。
this.handleExport(res.data);
});
/* 下载文件的公共方法,参数就传blob文件流*/
handleExport(data) {
// 动态创建iframe下载文件
let fileName = this.selectedTabelRow[0].dirName;
if (!data) {
return;
}
let blob = new Blob([data], { type: "application/octet-stream" });
if ("download" in document.createElement("a")) {
// 不是IE浏览器
let url = window.URL.createObjectURL(blob);
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); // 下载完成移除元素
window.URL.revokeObjectURL(url); // 释放掉blob对象
} else {
// IE 10+
window.navigator.msSaveBlob(blob, fileName);
}
},
以上就是下载的方法啦,不好用,你砍我!!!!!
别别别 你私我,我随时在线。
打印功能实现:
也是直接上代码:
// 调用打印接口,我们这边是后端弟兄,把所有的word格式全部给转化成了pdf格式,还添加了水印
axios({
method: "post",
url: this.proxyUrl + "/api/file/printdocument",
responseType: "blob",
headers: { "Content-Type": "application/json" },
data: { // post格式是data传参数,注意请求方式
file_id: this.selectedTabelRow[0].fileId,
addwatermark: val,
},
}).then((res) => {
res = res.data;
const blob = new Blob([res], { type: "application/pdf" }); // 因为知道是pdf所以指定了格式。
var date = new Date().getTime();
var ifr = document.createElement("iframe");
ifr.style.frameborder = "no";
ifr.style.display = "none";
ifr.style.pageBreakBefore = "always";
ifr.setAttribute("id", "printPdf" + date);
ifr.setAttribute("name", "printPdf" + date);
ifr.src = window.URL.createObjectURL(blob);
document.body.appendChild(ifr);
this.doPrint("printPdf" + date);
window.URL.revokeObjectURL(ifr.src); // 释放URL 对象
});
// 打印
doPrint(val) {
var ordonnance = document.getElementById(val).contentWindow;
setTimeout(() => {
// window.print()
ordonnance.print();
this.pdfLoading = false;
}, 100);
},
预览功能实现:
预览功能我用的是vue-pdf这个npm包。同样预览也是java的弟兄给转成了pdf,我直接预览pdf格式就行,不过,返回的是文件流,不是url地址。所以需要先把流转化成url地址,很简单一个方法搞定。
// 将返回的流数据转换为url
getObjectURL(file) {
let url = null;
if (window.createObjectURL != undefined) {
// basic
url = window.createObjectURL(file);
} else if (window.webkitURL != undefined) {
// webkit or chrome
try {
url = window.webkitURL.createObjectURL(file);
} catch (error) {}
} else if (window.URL != undefined) {
// mozilla(firefox)
try {
url = window.URL.createObjectURL(file);
} catch (error) {}
}
return url;
},
其他的使用方法就是跟vue-pdf教程一样了。
踩坑记录一下!!!之前也做过根据url来下载文件,算是比较简单的,这次的文件流,倒是踩出来了很多坑。