后端返回base64文件前端如何下载

2023-12-13 03:40:13

1.后端返回base64格式文件
在这里插入图片描述

2.前端代码

<style lang="less" scoped>
@import "./style/common.less";

.table-div-a {
  color: #409EFF;
  text-decoration: underline;
  cursor: pointer;
}
</style>

<template>
  <div class="template-container content-container" v-loading="pageObj.loading">
    <div class="action-button-div flex-div">
      <div class="action-button-div-left flex-1">
        <el-button class="main-cust-btn" type="primary" size="small" @click="initList()">刷新</el-button>
      </div>
      <div class="action-button-div-right  flex-div">
        <el-select v-model="pageObj.pageParmas.exportType" placeholder="请选择导出类型" @change="selectVal">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
          </el-option>
        </el-select>
        <!-- <div class="single-query-input margin-right-8">
          <el-input size="small" placeholder="请输入角色名" v-model="pageObj.queryParams.roleName"></el-input>
        </div>
        <el-button-group>
          <el-button class="main-cust-btn" size="small" type="primary" icon="el-icon-search" @click="initList('query')">查询</el-button>
        </el-button-group> -->
      </div>
    </div>
    <!--表格区-->
    <div class="table-div flex-div">
      <el-table :data="pageObj.tableData" :stripe="true" ref="listTableRef" border class="flex-1 list-table"
        header-row-class-name="list-table-header">
        <el-table-column type="index" width="40" align="center">
        </el-table-column>
        <el-table-column prop="startTime" label="下载时间" min-width="150" align="center">
        </el-table-column>
        <el-table-column prop="exportTypeName" label="导出类型" min-width="150" align="center">
        </el-table-column>
        <el-table-column prop="operationalName" label="状态" min-width="150" align="center">
        </el-table-column>
        <el-table-column prop="endTime" label="完成时间" min-width="120" align="center">
        </el-table-column>
        <el-table-column label="操作" align="center" width="180" fixed="right">
          <div slot-scope="scope">
            <a class="table-div-a" v-if="'计算完成' == scope.row.operationalName" @click="toExportPath(scope.row)">下载</a>
          </div>
        </el-table-column>
      </el-table>
    </div>
    <!--分页区-->
    <div class="pagination-div">
      <el-pagination v-show="pageObj.pageParmas.total > 0" :current-page="pageObj.pageParmas.pageNum + 1"
        :page-sizes="pageObj.Config.paginationParams.pageSizes" :page-size="pageObj.pageParmas.pageSize"
        :layout="pageObj.Config.paginationParams.layout" :total="pageObj.pageParmas.total" @size-change="handleSizeChange"
        @current-change="handlePageChange">
      </el-pagination>
    </div>
    <!--确认删除对话框-->
    <!-- <del-dialog
      :delDialogVisible="deleteObj.delDialogVisible"
      v-on:doDel="delOne"
      v-on:cancelDel="
        () => {
          deleteObj.delDialogVisible = false;
        }
      "
    ></del-dialog> -->
  </div>
</template>

<script>
// 删除组件
// import delDialog from "../../components/list/DelDialog.vue";
import config from "./config.js";
export default {
  components: {
    // delDialog
  },
  data() {
    return {
      pageObj: {
        // 页面属性
        showSearch: true, // 高级搜索展示
        detailRouter: "roleDetail", // 详情页路由
        loading: false, // 加载
        tableData: [],
        queryParams: {},
        pageParmas: {
          pageNum: 0,
          pageSize: 10,
          exportType: ''//2 结算导出 3 订单导出
        },
        Config: config
      },
      deleteObj: {
        // 删除对话框 属性
        delDialogVisible: false, // 是否显示删除对话框
        delOneId: "" // 删除单个ID
      },
      listLooper: null,
      options: [{
        value: 2,
        label: '结算导出'
      }, {
        value: 3,
        label: '订单导出'
      }]
    };
  },
  methods: {
    init() {
      if (Object.keys(this.$route.query).length > 0) {//从订单和结算页面带值过来
        this.pageObj.pageParmas.exportType = this.$route.query.type;
        console.log(this.pageObj.pageParmas.exportType)
      }
      // 初始化面包屑
      this.$store.commit("setBreadCrumbList", [
        { type: 'title', name: '主数据' },
        { type: 'title', name: '下载中心' }
      ]);
      this.initList();
    },
    // 跳转新增页面
    toAdd() {
      var _ = this;
      this.$store.commit("setEditId", "");
      this.$router.push({
        name: _.pageObj.detailRouter
      });
    },
    // 跳转编辑页
    toEdit(objId) {
      var _ = this;
      this.$store.commit("setEditId", objId);
      this.$router.push({
        name: _.pageObj.detailRouter
      });
    },
    // 展示删除对话框
    toDelOne(objId) {
      this.deleteObj.delOneId = objId;
      this.deleteObj.delDialogVisible = true;
    },
    // 删除一个
    delOne() {
      let _ = this;
      const url = this.$A.role + "/" + this.deleteObj.delOneId;
      _.$H.delete(_, url, function () {
        // TODO
        _.deleteObj.delDialogVisible = false;
        _.$U.success(_, "删除成功!");
        _.initList();
      });
    },
    selectVal() {
      this.pageObj.pageParmas.pageNum = 0;
      this.initList();
    },
    // 初始化列表
    initList() {
      let _ = this;
      clearTimeout(_.listLooper);
      this.pageObj.loading = true;
      // if (this.$U.notEmpty(type)) {
      //   this.pageObj.pageParmas.pageNum = 0;
      // }
      // 初始化查询参数
      this.initQueryParams();
      // TODO
      // _.$H.get(_, _.$A.download.list, _.pageObj.queryParams, function (res) {
      //   _.pageObj.tableData = res.data.data.content;
      //   if (
      //     _.pageObj.tableData.length === 0 &&
      //     _.pageObj.pageParmas.pageNum > 0
      //   ) {
      //     _.pageObj.pageParmas.pageNum--;
      //     _.initList();
      //   } else {
      //     _.pageObj.pageParmas.total = res.data.data.totalElements;
      //     _.pageObj.loading = false;

      //     _.listLooper = setTimeout(() => {
      //       _.initList();
      //     }, 30000);
      //   }
      // });
      _.$H.get(_, _.$A.download.list, _.pageObj.queryParams).then(res => {
        _.pageObj.tableData = res.data.data.content;
        if (
          _.pageObj.tableData.length === 0 &&
          _.pageObj.pageParmas.pageNum > 0
        ) {
          _.pageObj.pageParmas.pageNum--;
          _.initList();
        } else {
          _.pageObj.pageParmas.total = res.data.data.totalElements;
          _.pageObj.loading = false;

          // _.listLooper = setTimeout(() => {
          //   _.initList();
          // }, 30000);
        }

      }).catch(err => {

      })
    },
    // 初始化查询参数
    initQueryParams() {
      this.pageObj.queryParams.pageNum = this.pageObj.pageParmas.pageNum || 0;
      this.pageObj.queryParams.pageSize = this.pageObj.pageParmas.pageSize || 10;
      this.pageObj.queryParams.exportType = this.pageObj.pageParmas.exportType || '';
    },
    // 条数变更
    handleSizeChange(val) {
      this.pageObj.pageParmas.pageSize = val;
      this.initList();
    },
    // 页码变更
    handlePageChange(val) {
      this.pageObj.pageParmas.pageNum = val - 1;
      this.initList();
    },
    typeFormat(row, key, value) {
      var typeName = "";
      if (value == "01") {
        typeName = "安装订单导出";
      } else if (value == "02") {
        typeName = "配送订单导出";
      } else if (value == "04") {
        typeName = "结算导出";
      } else if (value == "09") {
        typeName = "补贴订单导出";
      } else if (value == "012") {
        typeName = "退回订单记录导出";
      } else if (value == "03") {
        typeName = "作废订单导出";
      } else if (value == "06") {
        typeName = "报修订单导出";
      } else if (value == "011") {
        typeName = "投诉订单导出";
      } else if (value == "013") {
        typeName = "不送桩VIN导出";
      }
      return typeName;
    },
    statusFormat(row, key, value) {
      var statusName = "";
      if (value == 0) {
        statusName = "等待中";
      }
      if (value == 1) {
        statusName = "进行中";
      } else if (value == 2) {
        statusName = "已完成";
      } else if (value == 5) {
        statusName = "失败";
      }
      return statusName;
    },
    downloadFile: function (blob, fileName) {
      const link = document.createElement("a");
      link.href = window.URL.createObjectURL(blob);
      link.download = fileName;
      // 此写法兼容可火狐浏览器
      document.body.appendChild(link);
      const evt = document.createEvent("MouseEvents");
      evt.initEvent("click", false, false);
      link.dispatchEvent(evt);
      document.body.removeChild(link);
    },
    // 将Base64文件转为 Blob
    buildBlobByByte: function (data) {
      const raw = window.atob(data);
      const rawLength = raw.length;
      const uInt8Array = new Uint8Array(rawLength);
      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
      }
      return new Blob([uInt8Array]);
    },
    // 二进制数组 生成文件
    downloadFileByByte: function (data, fileName) {
      const blob = this.buildBlobByByte(data);
      this.downloadFile(blob, fileName);
    },
    // 下载
    toExportPath(obj) {
      let _ = this;
      this.pageObj.loading = true;

      // _.$H.getBlob(
      //   _,
      //   _.$A.exportListDownload + "/" + obj.id,
      //   {},
      //   function (res) {
      // const fileName = _.typeFormat("", "", obj.type);
      // //数据转换为文件下载
      // var elink = document.createElement("a");
      // elink.download = fileName;
      // elink.style.display = "none";
      // var blob = new Blob([res.data]);
      // const reader = new FileReader();
      // reader.readAsText(blob); // 以文本形式读取Blob对象
      // reader.onload = () => {
      //   const jsonStr = reader.result; // 获取读取的内容
      //   const jsonData = JSON.parse(jsonStr); // 将JSON格式的字符串转换为JavaScript对象

      //   const fileBase64 = jsonData.data.base64;

      //   _.downloadFileByByte(fileBase64, fileName + ".xlsx");
      // };

      // _.pageObj.loading = false;
      //   }
      // );
      _.$H.getBlob(_, _.$A.download.export, {
        id: obj.id,
        exportType: obj.exportType
      }).then(res => {
        console.log(res.data)
        // const fileName = _.typeFormat("", "", obj.type);
        const fileName =  obj.exportTypeName +  Date.now();
        //数据转换为文件下载
        var elink = document.createElement("a");
        elink.download = fileName;
        elink.style.display = "none";
        var blob = new Blob([res.data]);
        const reader = new FileReader();
        reader.readAsText(blob); // 以文本形式读取Blob对象
        reader.onload = () => {
          const jsonStr = reader.result; // 获取读取的内容
          const jsonData = JSON.parse(jsonStr); // 将JSON格式的字符串转换为JavaScript对象

          const fileBase64 = jsonData.data.base64;

          _.downloadFileByByte(fileBase64, fileName + ".xlsx");
        };

        _.pageObj.loading = false;
      }).catch(err => {

      })
    }
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    clearTimeout(this.listLooper);
  }
};
</script>

3.请求封装

// get 请求
http.getBlob = function (vm, url, params) {
    return new Promise((resolve, reject) => {
        axios
            .get(url, {
                params: params || {},
                headers: {
                    'Content-Type': 'application/json;charset=UTF-8',
                    authorization: vm.$store.state.token,
                    responseType: 'blob'
                },
                timeout: config.httpTimeOut,
                responseType: 'blob'
            })
            .then(res => {
                resolve(res)
            })
            .catch(err => {
                custErrFun(vm, err)
            })
    })
}
// postBlob 请求
http.postBlob = function (vm, url, params) {
    return new Promise((resolve, reject) => {
        axios
            .post(url, params, {
                headers: {
                    'Content-Type': 'application/json;charset=UTF-8',
                    authorization: vm.$store.state.token,
                    responseType: 'blob'
                },
                timeout: config.httpTimeOut,
                responseType: 'blob'
            })
            .then(res => {
                custResponseFun(vm, res, resolve)
            })
            .catch(err => {
                custErrFun(vm, err)
            })
    })
}

文章来源:https://blog.csdn.net/weixin_44705979/article/details/134880928
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。