vue下载数据流文件

日常开发中我们常常需要下载文件,但是后端返回给前端需要下载的文件大致有两种:一种url链接,另一种文件流的形式;

1、前端下载url链接文件

方法1、通过a标签的href直接下载

方法2、通过 window.open(url) 直接下载
window.open("https://www.baidu.com/img/bd_logo1.png")

2、前端处理 文件流 文件

针对文件流文件,前端需要进行文件类型,blob处理以后通过动态创建a标签的形式下载

Blob对象处理

MDN上描述:Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。 要从其他非blob对象和数据构造一个 Blob,请使用 Blob() 构造函数

MDN-Blob.png

需要利用Blob()构造函数构建一个blob对象,axios请求例子:

axios.get( url, params ).then((res) => {
    const data = res.data;
    const url = window.URL.createObjectURL(new Blob([data], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    }))
    const a = document.createElement('a')
    a.style.display = 'none'
    a.href = url
    a.setAttribute('download', 'excel.xlsx')
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a) 
    this.dialogInfo.dialogVisible = false
 
}).catch((err) => {
  console.log(err.message);
});

注意:上面的方法虽然可以下载文件,但是下载下来的文件是乱码,甚至打开文件出错。


file-error.png

花了一个上午的时间找问题,结果接口链接直接在浏览器中,通过a标签下载都能直接打开并下载文件,且文件数据没有任何问题。但是通过axios请求拿到的数据浏览器不识别,且通过blob和动态创建a标签不能下载正确的文件内容,百思不得其解。。。

后来发现是参数 responseType 的问题,responseType 它是服务器响应的数据类型,由于后台返回来的是二进制数据,所以我们要把它设为arraybuffer或者blob

axios.get(url, {
    params, 
    responseType: 'arraybuffer'
}).then((res) => {
    const data = res.data;
    const url = window.URL.createObjectURL(new Blob([data], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    }))
    const a = document.createElement('a')
    a.style.display = 'none'
    a.href = url
    a.setAttribute('download', 'excel.xlsx')
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a) 
    this.dialogInfo.dialogVisible = false
 
}).catch((err) => {
  console.log(err.message);
});

最后发现文件数据下载成功,文件能够直接打开且数据内容没有问题


file-success.png

你可能感兴趣的:(vue下载数据流文件)