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响应头,也就能够拿到这个附件名字

相关推荐
koiy.cc16 分钟前
记录:echarts实现tooltip的某个数据常显和恢复
前端·echarts
一只专注api接口开发的技术猿26 分钟前
企业级电商数据对接:1688 商品详情 API 接口开发与优化实践
大数据·前端·爬虫
GISer_Jing28 分钟前
[前端高频]数组转树、数组扁平化、深拷贝、JSON.stringify&JSON.parse等手撕
前端·javascript·json
Yvonne爱编码1 小时前
CSS- 4.1 浮动(Float)
前端·css·html·github·html5·hbuilder
timeguys2 小时前
【前端】[vue3] [uni-app]使用 vantUI 框架
前端·uni-app
岁岁岁平安2 小时前
Vue3学习(组合式API——Watch侦听器、watchEffect()详解)
前端·javascript·vue.js·学习·watch侦听器·组合式api
码视野2 小时前
基于Spring Boot和Vue的在线考试系统架构设计与实现(源码+论文+部署讲解等)
vue.js·spring boot·系统架构
uwvwko2 小时前
BUUCTF——web刷题第一页题解
android·前端·数据库·php·web·ctf
有事没事实验室3 小时前
CSS 浮动与定位以及定位中z-index的堆叠问题
前端·css·开源