明天的明天 永远的永远 未知的一切 我与你一起承担 ??

是非成败转头空 青山依旧在 几度夕阳红 。。。
  博客园  :: 首页  :: 管理

这段代码演示了如何通过JavaScript的axios库异步获取HTTP资源,以blob形式处理响应数据,

创建一个可供下载的Word文档(客流日报.docx)。它设置特定的请求头,传递日期参数,并监听下载完成以释放内存中的URL对象。

const wordExportTwo = async () => {
  try {
    const response = await axios.get('http://192.168.0.108:8080/Word/Report/Export', {
      responseType: 'blob',
      headers: {
        Accept: 'application/json',
      },
      params: {
        date: choiceYesterdayDate,
      },
    });

    const fileName = '客流日报.docx'; // 替换为实际的文件名
    const blob = new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8',
    });
    const url = window.URL.createObjectURL(blob);

    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', fileName);
    document.body.appendChild(link);

    // 触发点击事件开始下载
    link.click();

    // 下载完成后释放 URL 对象
    link.addEventListener('click', () => {
      setTimeout(() => {
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);
      }, 100);
    }, { once: true });
  } catch (error) {
    console.error('导出失败:', error);
  }
};

 VUE 描述"application/x-www-form-urlencoded"传值问题

var qs = require('qs')
      let param = {
        'ids':id
      };
      let token = window.localStorage.getItem("token");
      axios
        .post(api.purchase, qs.stringify(param), {
          headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            Authorization: token
          }
        })
        .then(res => {
          console.log(res.data);
          //   Toast("程序异常,请稍后再试");
        });
    },

 

例2:

<template>
  <div class="content-box">
    <div class="container">
      <div>。。。</div>
    </div>
  </div>
</template>

<script>
import {  exportProjectStandard } from '@/api/brand/standard'

export default {
  props: {},
  data() {
    return {}
  },
  methods: {
    gotoExport(row){
      // console.log(row);
      try {
        // window.location.href = `${ process.env.VUE_APP_BASE_BRAND_API }/v1/inspectionstandard/exportProject?id=${row.id}&standardName=${row.title}`
        // window.open(`${ process.env.VUE_APP_BASE_BRAND_API }/v1/inspectionstandard/exportProject?id=${row.id}&standardName=${row.title}`)
        // this.$message.success('数据导出中,请稍等')
        
        // 调接口文件流形式
        let parmas = {
          id: row.id,
          standardName: row.title
        }
        exportProjectStandard(parmas).then(res => {
          console.log(res);
          // 因为后端直接返回的就是blob数据流格式
          // if (res.code == 200) {
            const content = res;
            const blob = new Blob([content])
            const fileName = row.title + '.xls';  //自定义下载文件的名字
            if ('download' in document.createElement('a')) { // 非IE下载
              const elink = document.createElement('a');
              elink.download = fileName;
              elink.style.display = 'none';
              elink.href = URL.createObjectURL(blob);
              document.body.appendChild(elink);
              elink.click();
              URL.revokeObjectURL(elink.href); // 释放URL 对象
              document.body.removeChild(elink);
            } else { // IE10+下载
              navigator.msSaveBlob(blob, fileName);
            }
          // }
        }).catch((error) => {
          this.$message.error('导出异常,请稍后重试')
            console.log(error.response)   //可获取错误的返回信息
          if (error.response.status == 400) {}
        }).finally(() => {})
      } catch (error) {
        this.$message.error('导出失败')
      }
    }
  }
}
</script>

<style lang="scss" scoped>

</style>

 

前端文件下载的几种方式

    后端直接给文件url,
    这种情况很简单,直接将url付给a标签,a标签加上download属性即可

    后端返回的是文件流,但是请求是get请求
    此种情况下,要获取文件原始文件名,也简单。一种是使用window.open(url),一种是直接将请求地址给a标签

    后端由于需要,只能使用post请求(比如下载文件时需要携带过多的参数),使用这种方式获取下载文件的原始文件名,比之前两种麻烦些,本文重点说的是这种情况

    思路如下:
    1) 使用ajax发起请求,指定接收类型为blob
    2)读取请求返回的头部信息里的content-disposition,返回的文件名就在这里面
    3)使用URL.createObjectURL将请求的blob数据转为可下载的url地址
    4)使用a标签下载

export const downloadFile = (url,data)=>{
function down(fileUrl,fileName){
fileName=decodeURIComponent(fileName)
let a=document.createElement('a')
a.setAttribute('href',fileUrl)
a.setAttribute('download',fileName)
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
axios({
  url,
  data,
  responseType:'blob',
  method:'POST',
}).then(res=>{
  let data=res.data
  let dis= res.headers['content-disposition']
  let url=URL.createObjectURL(data)
  let fileName=dis.split('attachment;filename=')[1]
  down(url,fileName)
})

需要说明的是,content-disposition 取值是res.headers[‘content-disposition’],res.headers[‘content-disposition’] 的值是如下类型字符串 attachment;filename=xxx.xlsx,需要自己切分。另外,如果文件名是中文,则需要后端配合转码,后端在发送文件时,组要将文件名进行java.net.URLEncoder.encode(fileName, “UTF8”) 转码,否则前端接收到的 res.headers[‘content-disposition’] 的中文信息是乱码的。后端转码后,前端通过decodeURIComponent 解码即可

 

==========================================================

vue实现导出二进制流(blob)文件(get请求)

说明:该导出主要是基于后端做的,前端拿到二进制blob文件流

方法一:导出后直接打开的是表格

handleExport() {
  let _this = this;
  if (_this.exportIds.length == 0) {
    return _this.$message.info("暂无选择要导出的数据");
  }
  axios.get("https://********/****/export.do", {
    params: {
      ids: _this.exportIds.join(","),
      _t: new Date().getTime()
    },
    responseType: "blob" // 1.首先设置responseType对象格式为 blob:
  }).then(res => {
      //resolve(res)
      // 2.获取请求返回的response对象中的blob 设置文件类型,这里以excel为例
      let blob = new Blob([res.data], {
        type: "application/vnd.ms-excel"
      });
      // 3.创建一个临时的url指向blob对象
      let url = window.URL.createObjectURL(blob);
      // 4.创建url之后可以模拟对此文件对象的一系列操作,例如:预览、下载
      let a = document.createElement("a");
      a.href = url;
      a.download = "导出数据_" + new Date().getTime() + ".xlsx"; //自定义导出文件名
      a.click();
      // 5.释放这个临时的对象url
      window.URL.revokeObjectURL(url);
      return _this.$message.success("导出成功");
    },
    err => {
      resolve(err.response);
    }
  ).catch(error => {
    reject(error);
  });
}

 

方法二:导出后需要用excel 打开

handleExport() {
  let _this = this;
  if (_this.exportIds.length == 0) {
    return _this.$message.info("暂无选择要导出的数据");
  }
   axios({
    method: 'get',
    url: 'https://******e/export.do',
    responseType: 'blob',
    params: { ids: _this.exportIds.join(","), _t: new Date().getTime() }
   }).then((res) => {
    if (res.code != 0) {
      _this.loading = false;
      return _this.$message.error(res.msg);
    }    
       let blob = new Blob([res.data], {
     type: 'application/vnd.ms-excel',
       });
    let link = document.createElement('a')
    let body = document.querySelector('body')
    link.href = window.URL.createObjectURL(blob) // 
    link.style.display = 'none' // 让这个a标签不可见
    link.download = '导出文件'  //文件名称
    body.appendChild(link)
    link.click()        // 创建了新的a标签之后模拟点击事件,开始传输文件
    body.removeChild(link)  // 下载完成之后,移除按钮,垃圾回收,减少页面内存消耗
      window.URL.revokeObjectURL(link.href)   // 移除之前使用createObjectURL创建的URL,垃圾回
      return _this.$message.success("导出成功");
   });
}

 

方法三: 兼容IE和谷歌、火狐浏览器

//导出兼容ie浏览器
        handleExport() {
          let _this = this;
          if (_this.exportIds.length == 0) {
            return _this.$message.info("请选择要导出的数据!");
          }
          axios({
            url: "8888888",
            method: "get",
            responseType: 'blob', //文件流数据一定要写
            params: {
              ids: _this.exportIds.join(","),
              _t: new Date().getTime()
            },
          }).then(res => {
            const blob = new Blob([res.data]); //处理文档流
            const fileName = '发票管理.xlsx'; //导出后的文件名
            if (!!window.ActiveXObject || "ActiveXObject" in window || window.navigator.userAgent
              .indexOf('Edge/') > 0) { //判断是不是ie的浏览器
              window.navigator.msSaveOrOpenBlob(blob, fileName);
              console.log('ieeeeee')
            } else {
              const elink = document.createElement('a');
              elink.download = fileName;
              elink.style.display = 'none';
              elink.href = URL.createObjectURL(blob);
              document.body.appendChild(elink);
              elink.click();
              URL.revokeObjectURL(elink.href); // 释放URL 对象
              document.body.removeChild(elink);
              console.log('noieeeee')
            }
          }).catch(err => {
            console.log(err)
          })
        }