前端发送请求获取后端文件,并且前端实现下载文件功能

前端 0

最近遇到一个需求,就是前端发送post请求获取后端的excel文件,并且前端实现下载导出到本地的功能。
在这里插入图片描述
前端页面就长上面那样,一个批量导出功能,用户勾选之后,前端通过接口把id和其他的参数传给后端,接口调用方法这里需要注意的是,这里必须设置responseType: ‘blob’
请添加图片描述

,后端返回来一个文件流,然后前端通过封装的方法实现下载导出,前端导出方法如下:
在这里插入图片描述
这里前端通过blobDownloads实现下载:
前端需要引入这个js

import localDownloadUtil from "@/utils/localDownloadUtil.js";

然后我们看看这个js里封装了两个下载方法,一种是iframe下载,一种是二进制文件下载,这里我们选择了二进制文件下载:

/** * 本地下载一个文本文件。 * @link https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server * @param filename {string} * @param text {string} */// function download (filename, text) {//   const element = document.createElement('a')//   element.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(text)}`)//   element.setAttribute('download', filename)//   element.style.display = 'none'//   document.body.appendChild(element)//   element.click()//   document.body.removeChild(element)// }// iframe下载文件,没又身份验证的get接口可以使用function iframeDownloads(lastUrl){  var downloadFileUrl = window.g.API_URL + lastUrl  var elemIF = document.createElement("iframe");  elemIF.src = downloadFileUrl;  elemIF.style.display = "none";  document.body.appendChild(elemIF);}// 设备二进制文件function blobDownloads (data, fileName) {  if (!data) {    return  }  // type: 'application/vnd.ms-excel'  const url = window.URL.createObjectURL(new Blob([data]))  const link = document.createElement('a')  link.style.display = 'none'  link.href = url  link.setAttribute('download', fileName)  document.body.appendChild(link)  link.click()  window.URL.revokeObjectURL(url)  document.body.removeChild(link)// 下载完毕删除a标签}export default {  // download,  blobDownloads,  iframeDownloads}

还有一种情况是后端返回的不是文件流或文件对象,而返回的就是一个blob文件,然后文件名带文件格式的字符串,如下图是后端返回的结果:
请添加图片描述
那这个请求就不能用我们封装的请求去发请求了,需要我们手动写个axios去发请求,并将返回的结果通过window.open来打开下载:
请添加图片描述
整个页面完整代码如下:

<template>  <div class="mainBox">    <!-- 仿冒日志 -->    <el-card shadow="always" :style="'height:100%;overflow:auto;'">      <div class="centerLeftBox">        <search-form          ref="searchForm_Board"          @reset="reset_Board"          @handleSubmit="handleSubmitSearch_Board"          :formData="formData_Board"          :isInline="true"          :searchConfig="searchConfig_Board"        >        </search-form>      </div>    </el-card>    <div style="height:10px;"></div>    <el-card>      <commonTable        :tableHead="tableHead_Board"        :tableData="tableData_Board"        :selectionFlag="true"        :toolBoxFlag="true"        :resizable="true"        :dataFiter="true"        :xuhaoFlag="false"        :dropdownList="dropdownList"        @selectAction="selectAction"        :addBtn="false"        :tableLoading="tableLoading_Board"        :showListD="showListD_Board"        :maxHeight="'458'"        :freeElfFlag="false"        :rightBtnList="rightBtnList"        ref="commonTable"      >        <template slot-scope="scope" slot="freeElf">          <!-- <el-button          size="mini"          type="text"          @click="goFakeLog(scope.scope.row)"          v-authbuttons:[otherAuth]          >仿冒日志</el-button        > -->        </template>      </commonTable>      <div style="height:10px;"></div>      <el-pagination        class="tac page-style"        background        @size-change="BoardChangeSize"        @current-change="BoardCurrentChange"        :current-page.sync="BoardPageObj.page"        :page-sizes="[10, 20, 30, 40, 50]"        :page-size.sync="BoardPageObj.page_size"        :current.sync="BoardPageObj.page"        layout="total, sizes, prev, pager, next, jumper"        :total="BoardPageObj.total"        :style="'text-align:left;'"      ></el-pagination>    </el-card>    <el-dialog      title="处理仿冒"      center      :visible.sync="isShowModal"      @close="closeModal"      :show-close="true"      :close-on-click-modal="false"      :width="'800px'"    >      <fake-edit        v-if="isShowModal"        ref="fakeEdit"        :formData="FakeObj"        :newValue="newValue"        @closeFake="closeFake"      />      <div slot="footer" class="dialog-footer">        <el-button @click="isShowModal = false">取 消</el-button>        <el-button type="primary" :loading="saveLoading" @click="editOk"          >处 理</el-button        >      </div>    </el-dialog>  </div></template><script>import searchForm from "@/components/search-form";import commonTable from "@/components/common-table";import { getFakelogList } from "@/api/systemControl.js";import { getBoardFakeCommonData } from "@/api/asset.js";import localDownloadUtil from "@/utils/localDownloadUtil.js";import { getToken } from "@/utils/auth";import axios from "axios";export default {  name: "PendingProcessing",  components: {    commonTable,    searchForm  },  data() {    return {      formData_Board: {},      searchConfig_Board: [        {          type: "select",          label: "操作类型",          props: "log_pd_result",          labelWidth: 95,          options: [],          changeSearch: true,          changeSearch: true,          defaultPropsLabel: "val",          defaultPropsValue: "key"        },        { type: "input", label: "设备IP", props: "ip", labelWidth: 95 },        { type: "input", label: "设备MAC", props: "old", labelWidth: 95 },        {          type: "input",          label: "当前MAC",          props: "new",          labelWidth: 95        },        {          type: "timeBox",          label: "时间范围",          props: "time"        },        { type: "btnList" }      ],      tableHead_Board: [        {          label: "设备IP",          prop: "ip",          type: "normal",          sortable: false        },        { label: "设备MAC", prop: "old", type: "normal", sortable: false },        {          label: "仿冒原因",          prop: "cause_str",          type: "normal",          sortable: false        },        {          label: "当前MAC",          prop: "new",          type: "normal",          sortable: false        },        {          label: "操作人账户",          prop: "user_name",          type: "normal",          sortable: false        },        {          label: "操作类型",          prop: "pd_result_str",          type: "normal",          sortable: false        },        {          label: "更新时间",          prop: "c_time",          type: "normal",          sortable: false        }      ],      tableData_Board: [],      tableLoading_Board: false,      showListD_Board: [        "ip",        "old",        "cause_str",        "new",        "user_name",        "c_time",        "pd_result_str"      ],      BoardPageObj: {        page: 1,        page_size: 10,        total: 0      },      editAuth: "update,FakeManage",      otherAuth: "others,FakeManage",      FakeObj: {},      isShowModal: false,      saveLoading: false,      newValue: "",      dropdownList: [        // {actionName:'fileAction',label:'归档',iconClass:'el-icon-s-cooperation',actionConfirm:'是否确定归档这些数据'},        // {actionName:'deleteAction',label:'删除',iconClass:'el-icon-delete',actionConfirm:'是否确定删除这些数据'},        {          actionName: "downLoadBatch",          label: "批量导出",          type: "primary",          iconClass: "el-icon-download",          actionConfirm: "是否确定导出这些数据"        }        // {        //   actionName: "editGroup",        //   label: "移动分组",        //   type: "primary",        //   iconClass: "el-icon-s-cooperation",        //   actionConfirm: "是否确定移动这些数据",        //   flag: true,        // },        // {actionName:'editGroupHigh',label:'高级分组',type:'primary',iconClass:'el-icon-s-grid',actionConfirm:'', flagEx: true,},      ],      rightBtnList: [        {          actionName: "downAll",          label: "一键导出",          type: "primary",          iconClass: "el-icon-download",          actionConfirm: "",          flagEx: true        }      ]    };  },  created() {    this.formData_Board.ip = this.$route.query.fakeIp;    this.handleSubmit_Board({}, true);    this.getCommonData();  },  methods: {    // 每页显示数变动    BoardChangeSize(pageSize) {      // console.log("条数", pageSize);      this.BoardPageObj.page_size = pageSize;      this.handleSubmit_Board({}, true);    },    BoardCurrentChange(page) {      // console.log("当前页", page);      this.BoardPageObj.page = page;      this.handleSubmit_Board({}, false);    },    // 获取交换机列表数据    handleSubmit_Board(data, flag) {      if (flag) {        this.BoardPageObj.page = 1;      }      let dataT = JSON.parse(JSON.stringify(this.formData_Board));      dataT.page = this.BoardPageObj.page;      dataT.page_size = this.BoardPageObj.page_size;      if (dataT.time && dataT.time.length > 0) {        dataT.start_time = dataT.time[0];        dataT.end_time = dataT.time[1];        delete dataT.time;      }      this.tableLoading_Board = true;      getFakelogList(dataT)        .then(res => {          this.tableData_Board = res.data.list;          this.BoardPageObj.total = res.data.total;          this.tableLoading_Board = false;        })        .catch(err => {});    },    // 重置筛选项    reset_Board() {      this.formData_Board = {};      this.handleSubmit_Board({}, true);    },    handleSubmitSearch_Board(data) {      this.handleSubmit_Board(data, true);    },    editData(item) {      this.isShowModal = true;      this.newValue = item.new;      this.FakeObj = {        ...item,        process_type: "1"      };    },    closeModal() {      this.isShowModal = false;    },    closeFake() {      this.isShowModal = false;      this.reset_Board();    },    editOk() {      this.$nextTick(() => {        this.$refs.fakeEdit.submit();      });    },    // 数据批量操作,判断和提示都已经做好了    selectAction(data) {      var idList = [];      var idString = "";      for (let index = 0; index < data.data.length; index++) {        const element = data.data[index];        idList.push(element.id);        idString = idString + element.id;        if (index + 1 !== data.data.length) {          idString = idString + ",";        }      }      var dataT = { ids: idString };      var that = this;      if (data.name === "fileAction") {        // 归档        // assetsdevinfofiling(dataT).then((res) => {        //   that.$message({ message: "归档成功", type: "success" });        //   this.handleSubmitSearch({});        // });      } else if (data.name === "deleteAction") {        // if (data.data.length <= 1) {        //   assetsListDelete(dataT.ids).then((res) => {        //     that.$message({ message: "删除成功", type: "success" });        //     this.handleSubmitSearch({});        //   });        // } else {        //   multipleDelete(dataT.ids).then((res) => {        //     that.$message({ message: "删除成功", type: "success" });        //     this.handleSubmitSearch({});        //   });        // }      } else if (data.name === "editGroup") {        // var showListFenzu = [];        // for (let index = 0; index < data.data.length; index++) {        //   const element = data.data[index];        //   showListFenzu.push(element.id);        // }        // this.editAssetGroutIdList = showListFenzu;        // this.treeTitle = "设置资产分组";        // this.treeFlag = true;      } else if (data.name === "downLoadBatch") {        // dataT.id_ls = JSON.stringify(idList);        dataT.filename = "仿冒文件";        dataT.pending_flag = "1";        dataT.ip = that.formData_Board.ip ? that.formData_Board.ip : "";        dataT.old = that.formData_Board.old ? that.formData_Board.old : "";        dataT.new = that.formData_Board.new ? that.formData_Board.new : "";        dataT.pd_result = "";        this.tableLoading_Board = true;        let datatFormdata = new FormData();        for (var key in dataT) {          datatFormdata.append(`${key}`, dataT[key]);        }        axios({          url: `${window.g.API_URL}/counterfeits/log/export/`,          method: "post",          data: datatFormdata,          headers: {            "Content-Type": "multipart/form-data",            Authorization: "Bearer " + getToken()          }        })          .then(res => {            // console.log("导出", res);            if (res.data.code == 200) {              let filename = res.data.data;              window.open(`${window.g.API_URL}/media/${filename}`);              this.$message.success("批量导出成功", 4000);              this.$nextTick(() => {                this.$refs.commonTable.resetSelect();                this.$refs.commonTable.clearSelection();              });              this.tableLoading_Board = false;            }          })          .catch(err => {});      } else if (data.name === "downAll") {        this.tableLoading_Board = true;        let query = {          filename: "仿冒文件",          ids: "all"        };        let queryFormdata = new FormData();        for (var k in query) {          queryFormdata.append(`${k}`, query[k]);        }        axios({          url: `${window.g.API_URL}/counterfeits/log/export/`,          method: "post",          data: queryFormdata,          headers: {            "Content-Type": "multipart/form-data",            Authorization: "Bearer " + getToken()          }        })          .then(res => {            // console.log("导出", res);            if (res.data.code == 200) {              let filename = res.data.data;              window.open(`${window.g.API_URL}/media/${filename}`);              this.$message.success("一键导出成功", 4000);              this.$nextTick(() => {                this.$refs.commonTable.resetSelect();                this.$refs.commonTable.clearSelection();              });              this.tableLoading_Board = false;            }          })          .catch(err => {});      }    },    goFakeLog(item) {      this.$router.push({        path: "FakeLog",        query: {          fakeIp: item.ip        }      });    },    //获取公共数据    getCommonData() {      getBoardFakeCommonData()        .then(res => {          // console.log("获取公共数据", res);          this.$nextTick(() => {            this.searchConfig_Board[0].options = res.data.log_pd_result;          });        })        .catch(err => {});    }  }};</script>

也许您对下面的内容还感兴趣: