vue实现文件流形式的导出下载

文章目录

Vue 项目中下载返回的文件流操作步骤

1、使用 Axios 请求文件流数据;

2、设置响应类型为 'blob';

3、创建下载链接并触发下载。

其中,最关键的一步是创建一个 Blob 对象并使用 URL.createObjectURL 方法生成一个下载链接。以下将详细说明如何实现。

一、使用 Axios 请求文件流数据

在 Vue 项目中,需要使用 Axios 来发送请求并获取文件流数据。可以在组件中使用 Axios 进行 HTTP 请求,确保在请求头中设置适当的响应类型。

import axios from 'axios';

export default {
  methods: {
    downloadFile() {
      axios({
        method: 'get',
        url: 'your-file-endpoint',  // 替换为实际的文件流接口
        params:{},
        responseType: 'blob'
      })
      .then(response => {
        this.handleFileDownload(response.data);
      })
      .catch(error => {
        console.error('Error downloading the file', error);
      });
    }
  }
};

二、设置响应类型为 'blob'

在 Axios 请求中,设置 responseType 为 'blob',这样 Axios 会将响应数据处理为 Blob 对象。Blob 对象表示一个不可变的、原始数据的类文件对象。

三、创建下载链接并触发下载

为了触发文件下载,需要创建一个 URL 链接并模拟点击事件。可以在组件中添加一个方法来处理 Blob 数据并进行下载。

methods: {
	  /**
	 * 拿到文件流后的下载的方法
	 * @param {*} data
	 * @param {*} filename
	 * @param {*} mime
	 * @param {*} bom
	 */
	 function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
	  const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
	  const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
	  if (typeof window.navigator.msSaveBlob !== 'undefined') {
	    window.navigator.msSaveBlob(blob, filename);
	  } else {
	    const blobURL = window.URL.createObjectURL(blob);
	    const tempLink = document.createElement('a');
	    tempLink.style.display = 'none';
	    tempLink.href = blobURL;
	    tempLink.setAttribute('download', filename);
	    if (typeof tempLink.download === 'undefined') {
	      tempLink.setAttribute('target', '_blank');
	    }
	    document.body.appendChild(tempLink);
	    tempLink.click();
	    // 移除 a 标签
	    document.body.removeChild(tempLink);   
	     // 释放 URL 对象
	    window.URL.revokeObjectURL(blobURL);
	  }
	}
}

四、在 Vue 组件中集成下载功能

<template>
  <div>
    <button @click="downloadFile">Download File</button>
  </div>
</template>
<script lang="ts" setup>

  // 下载
async function downloadFile() {
    try {
       axios({
        method: 'get',
        url: 'your-file-endpoint',  // 替换为实际的文件流接口
        params: {},   // 请求参数
        responseType: 'blob'
    }).then(
        (response) => {
          console.log('downloadByData',response)
          if(response.headers['content-disposition']) {
            let fileName = response.headers['content-disposition'].split('filename=')[1];
            // console.log('filename',fileName)
            fileName = fileName.replace(/"/g, '');
            downloadByData(response.data,fileName)
          } else {
            downloadByData(response.data,'xiazai.xlsx')
          }          
        }
      )
    } catch (e) {
      console.log(e);
    }
  }
  
  
  /**
 * 拿到文件流后的下载的方法
 * @param {*} data
 * @param {*} filename
 * @param {*} mime
 * @param {*} bom
 */
 function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) {
  const blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
  const blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
  if (typeof window.navigator.msSaveBlob !== 'undefined') {
    window.navigator.msSaveBlob(blob, filename);
  } else {
    const blobURL = window.URL.createObjectURL(blob);
    const tempLink = document.createElement('a');
    tempLink.style.display = 'none';
    tempLink.href = blobURL;
    tempLink.setAttribute('download', filename);
    if (typeof tempLink.download === 'undefined') {
      tempLink.setAttribute('target', '_blank');
    }
    document.body.appendChild(tempLink);
    tempLink.click();
    document.body.removeChild(tempLink);
    window.URL.revokeObjectURL(blobURL);
  }
}


</script>

五、解释与实例说明

1、使用 Axios 请求文件流数据:

Axios 是一个基于 Promise 的 HTTP 客户端,可以用于浏览器和 Node.js。

在发送请求时,通过设置 responseType 为 'blob' 来确保返回的数据是二进制流格式。

设置响应类型为 'blob':

Blob 对象表示一个不可变的、原始数据的类文件对象,可以表示数据,比如二进制数据。

在请求中指定 responseType 为 'blob',可以确保 Axios 将响应数据处理为 Blob 对象。

创建下载链接并触发下载:

Blob 对象可以通过 URL.createObjectURL 方法生成一个临时的 URL,用于表示该 Blob 对象。

创建一个 a 标签,并设置其 href 属性为生成的 URL,download 属性为文件名。

通过 JavaScript 触发点击事件来启动下载,然后移除 a 标签并释放生成的 URL。

下载文件,文件名获取不到

二进制流下载文件,从response header里面获取文件名,后端也设置了header【Content-Disposition】的值为【attachment;filename=MY_DOCUMENT_23.pdf】

network查看请求,response header的确是有值,但是axios获取header的值,永远只有content-type

这个请求是跨域请求

服务端加一个额外的响应头

【Access-Control-Expose-Headers】值为【Content-Disposition】

设置了这个响应头后,axios就可以获取到content-disposition响应头,也就能够拿到这个附件名字

相关推荐
xiao-xiang4 分钟前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师21 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳2 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?2 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
桂月二二8 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
沈梦研9 小时前
【Vscode】Vscode不能执行vue脚本的原因及解决方法
ide·vue.js·vscode
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
轻口味9 小时前
Vue.js 组件之间的通信模式
vue.js