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)
})
})
}