最近遇到一個(gè)需求,就是前端發(fā)送post請(qǐng)求獲取后端的excel文件,并且前端實(shí)現(xiàn)下載導(dǎo)出到本地的功能。
前端頁(yè)面就長(zhǎng)上面那樣,一個(gè)批量導(dǎo)出功能,用戶勾選之后,前端通過(guò)接口把id和其他的參數(shù)傳給后端,接口調(diào)用方法這里需要注意的是,這里必須設(shè)置responseType: ‘blob’
,后端返回來(lái)一個(gè)文件流,然后前端通過(guò)封裝的方法實(shí)現(xiàn)下載導(dǎo)出,前端導(dǎo)出方法如下:
這里前端通過(guò)blobDownloads實(shí)現(xiàn)下載:
前端需要引入這個(gè)js
import localDownloadUtil from "@/utils/localDownloadUtil.js";
然后我們看看這個(gè)js里封裝了兩個(gè)下載方法,一種是iframe下載,一種是二進(jìn)制文件下載,這里我們選擇了二進(jìn)制文件下載:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-703633.html
/**
* 本地下載一個(gè)文本文件。
* @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下載文件,沒(méi)又身份驗(yàn)證的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);
}
// 設(shè)備二進(jìn)制文件
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標(biāo)簽
}
export default {
// download,
blobDownloads,
iframeDownloads
}
還有一種情況是后端返回的不是文件流或文件對(duì)象,而返回的就是一個(gè)blob文件,然后文件名帶文件格式的字符串,如下圖是后端返回的結(jié)果:
那這個(gè)請(qǐng)求就不能用我們封裝的請(qǐng)求去發(fā)請(qǐng)求了,需要我們手動(dòng)寫(xiě)個(gè)axios去發(fā)請(qǐng)求,并將返回的結(jié)果通過(guò)window.open來(lái)打開(kāi)下載:
整個(gè)頁(yè)面完整代碼如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-703633.html
<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: "設(shè)備IP", props: "ip", labelWidth: 95 },
{ type: "input", label: "設(shè)備MAC", props: "old", labelWidth: 95 },
{
type: "input",
label: "當(dāng)前MAC",
props: "new",
labelWidth: 95
},
{
type: "timeBox",
label: "時(shí)間范圍",
props: "time"
},
{ type: "btnList" }
],
tableHead_Board: [
{
label: "設(shè)備IP",
prop: "ip",
type: "normal",
sortable: false
},
{ label: "設(shè)備MAC", prop: "old", type: "normal", sortable: false },
{
label: "仿冒原因",
prop: "cause_str",
type: "normal",
sortable: false
},
{
label: "當(dāng)前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: "更新時(shí)間",
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:'是否確定歸檔這些數(shù)據(jù)'},
// {actionName:'deleteAction',label:'刪除',iconClass:'el-icon-delete',actionConfirm:'是否確定刪除這些數(shù)據(jù)'},
{
actionName: "downLoadBatch",
label: "批量導(dǎo)出",
type: "primary",
iconClass: "el-icon-download",
actionConfirm: "是否確定導(dǎo)出這些數(shù)據(jù)"
}
// {
// actionName: "editGroup",
// label: "移動(dòng)分組",
// type: "primary",
// iconClass: "el-icon-s-cooperation",
// actionConfirm: "是否確定移動(dòng)這些數(shù)據(jù)",
// flag: true,
// },
// {actionName:'editGroupHigh',label:'高級(jí)分組',type:'primary',iconClass:'el-icon-s-grid',actionConfirm:'', flagEx: true,},
],
rightBtnList: [
{
actionName: "downAll",
label: "一鍵導(dǎo)出",
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: {
// 每頁(yè)顯示數(shù)變動(dòng)
BoardChangeSize(pageSize) {
// console.log("條數(shù)", pageSize);
this.BoardPageObj.page_size = pageSize;
this.handleSubmit_Board({}, true);
},
BoardCurrentChange(page) {
// console.log("當(dāng)前頁(yè)", page);
this.BoardPageObj.page = page;
this.handleSubmit_Board({}, false);
},
// 獲取交換機(jī)列表數(shù)據(jù)
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 => {});
},
// 重置篩選項(xiàng)
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();
});
},
// 數(shù)據(jù)批量操作,判斷和提示都已經(jīng)做好了
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 = "設(shè)置資產(chǎn)分組";
// 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("導(dǎo)出", res);
if (res.data.code == 200) {
let filename = res.data.data;
window.open(`${window.g.API_URL}/media/${filename}`);
this.$message.success("批量導(dǎo)出成功", 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("導(dǎo)出", res);
if (res.data.code == 200) {
let filename = res.data.data;
window.open(`${window.g.API_URL}/media/${filename}`);
this.$message.success("一鍵導(dǎo)出成功", 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
}
});
},
//獲取公共數(shù)據(jù)
getCommonData() {
getBoardFakeCommonData()
.then(res => {
// console.log("獲取公共數(shù)據(jù)", res);
this.$nextTick(() => {
this.searchConfig_Board[0].options = res.data.log_pd_result;
});
})
.catch(err => {});
}
}
};
</script>
到了這里,關(guān)于前端發(fā)送請(qǐng)求獲取后端文件,并且前端實(shí)現(xiàn)下載文件功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!