axios下载后台传过来的流文件并设置下载文件名(如excel)

主要介绍两种方法,使用 Blob对象 和 使用 js-file-download

这两种方法下载的文件都不会乱码,但是 不管使用哪种方法,发送请求时都要设置 responseType

方法一:使用Blob对象

Blob对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File接口基于Blob,继承了blob的功能并将其扩展使其支持用户系统上的文件。

一、Blob() 构造函数

摘自:Blob() 构造函数

语法

var aBlob = new Blob( array, options );

参数

  • array 是一个由ArrayBufferArrayBufferViewBlobDOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。
  • options 是可选的,它可能会指定如下两个属性:

    • type,默认值为 "",它代表了将会被放入到blob中的数组内容的MIME类型。也就是设置文件类型。
    • endings,默认值为"transparent",用于指定包含行结束符 的字符串如何被写入。 它是以下两个值中的一个: "native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持blob中保存的结束符不变。

二、URL对象

通过创建URL对象指定文件的下载链接。

// 创建新的URL表示指定的File对象或者Blob对象
const href = window.URL.createObjectURL(blob)
window.URL.revokeObjectURL(href) // 释放掉blob对象
在每次调用createObjectURL()方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL()方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

三、利用a标签自定义文件名

const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
const contentDisposition = response.headers['content-disposition'] // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
const patt = new RegExp('filename=([^;]+\.[^\.;]+);*')
const result = patt.exec(contentDisposition)
const filename = decodeURI(escape(result[1])) // 处理文件名,解决中文乱码问题
downloadElement.style.display = 'none'
downloadElement.href = href
downloadElement.download = filename // 下载后文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
download 属性设置文件名时,可以直接设置扩展名。如果没有设置,则浏览器将自动检测正确的文件扩展名并添加到文件 。

四:主要完整代码

  • 普通下载

  axios.post(postUrl, params, { responseType: 'arraybuffer' }).then(response => {
    const fileType = [
      'application/vnd.ms-excel;charset=utf-8', // xls
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' // xlsx
    ]
    const blob = new Blob([response.data], { type: fileType })
    const downloadElement = document.createElement('a')
    const href = window.URL.createObjectURL(blob)
    const contentDisposition = response.headers['content-disposition'] // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
    const patt = new RegExp('filename=([^;]+\.[^\.;]+);*')
    const result = patt.exec(contentDisposition)
    const filename = decodeURI(escape(result[1])) // 处理文件名,解决中文乱码问题
    downloadElement.style.display = 'none'
    downloadElement.href = href
    downloadElement.download = filename // 下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() // 点击下载
    document.body.removeChild(downloadElement) // 下载完成移除元素
    window.URL.revokeObjectURL(href) // 释放掉blob对象
  })
注 :下载指定扩展名的文件只需要对照MIME 参考手册设置type即可。

方法二:使用 js-file-download

  • 安装

    npm install js-file-download --save
  • 使用

     
    import fileDownload from 'js-file-download'
    
    axios.post(postUrl, params, {responseType: 'arraybuffer'}).then(response => {
        const contentDisposition = response.headers['content-disposition'] // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
        const patt = new RegExp('filename=([^;]+\.[^\.;]+);*')
        const result = patt.exec(contentDisposition)
        const filename = decodeURI(escape(result[1])) // 处理文件名,解决中文乱码问题
        fileDownload(response.data, filename)
    })
原文地址:https://www.cnblogs.com/baidei/p/14894361.html