<template>
<div>
<Modal
v-model="modal.isShow"
:title="options.title?options.title:'信息导出'"
:mask-closable="false"
>
<h4 slot="header">{{options.title?options.title:'信息导出'}}</h4>
<div v-if="getData" center>暂无数据导出</div>
<Row style="margin-bottom:10px;" v-if="!getData">
<Row style="padding:5px;" v-for="(exportItem,index) in exportArr" :key="index">
<Col span="20">
<Progress :percent="exportItem.percent"></Progress>
</Col>
<Col span="4">
<Button
type="primary"
size="small"
style="float:right"
:disabled=" exportItem.percent == 100 ? false : true"
@click="_export( exportItem.export )"
>确认导出</Button>
</Col>
</Row>
</Row>
<div slot="footer"></div>
</Modal>
</div>
</template>
<script>
import XLSX from "xlsx";
import "xlsx/dist/xlsx.full.min.js";
import saveAs from "file-saver/FileSaver.min.js";
import filters from "../filter";
import moment from "moment";
export default {
data() {
return {
modal: {
isShow: false,
},
getData: false,
limitNumber: 30000, // 单个excel上限数据量
totalCount: 0,
exportArr: [],
changeObj: {},
provinceList: [],
};
},
methods: {
show(flag) {
this.modal.isShow = flag;
this.totalCount = 0;
this.exportArr = [];
this.changeObj = {};
if (flag) {
this.startExport();
}
},
startExport() {
let _this = this;
this.options.columns.forEach((item) => {
if (item.filter) {
this.changeObj[item.prop] = item.filter;
}
});
let params = this.options.params;
params.pageIndex = 1;
params.pageSize = 500;
this.getData = false;
this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
if (res.body.status === "SUCCEED" || !!res.body.status) {
if (res.body.totalCount < 1) {
this.getData = true;
return;
}
this.getData = false;
this.totalCount = res.body.totalCount;
let pageNum = Math.ceil(this.totalCount / params.pageSize);
let excelNum = Math.ceil(this.totalCount / this.limitNumber);
for (let i = 0; i < excelNum; i++) {
this.exportArr.push({
export: [],
percent: 0,
});
}
let datas = res.body.datas || res.body.data;
if (!!this.options.special) {
datas.forEach((item, index) => {
item = { ...item, ...item[this.options.special] };
this.$set(datas, index, item);
});
}
// 添加额外数据
if (!!this.options.addData) {
datas.forEach((item, index) => {
item = {...this.options.addData,...item}
this.$set(datas, index, item);
});
}
datas.forEach((item) => {
for (let key in this.changeObj) {
if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
item[key]+='';
// item[key] = filters[this.changeObj[key]](item[key]);
}
if (!!item[key]) {
item[key] = filters[this.changeObj[key]](item[key]);
}
}
if (!!this.options.otherFunction) {
this.options.otherFunction(item);
}
});
this.exportArr[0].export.push(...datas);
if (pageNum === 1) {
this.exportArr[0].percent = 100;
// this._export(datas);
} else {
params.pageIndex = 2;
if (excelNum == 1) {
//一个Excel表
this.circleGetSingExc(params);
} else {
//多个Excel表
this.circleGet(params);
}
}
}
});
},
/* 循环下载 单个Excel表*/
circleGetSingExc(params) {
this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
if (res.body.status === "SUCCEED" || !!res.body.status) {
let datas = res.body.datas || res.body.data;
if (!!this.options.special) {
datas.forEach((item, index) => {
item = { ...item, ...item[this.options.special] };
this.$set(datas, index, item);
});
}
datas.forEach((item) => {
for (let key in this.changeObj) {
if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
item[key]+='';
}
if (!!item[key]) {
item[key] = filters[this.changeObj[key]](item[key]);
}
}
if (!!this.options.otherFunction) {
this.options.otherFunction(item);
}
});
this.exportArr[0].export.push(...datas);
if (params.pageIndex * params.pageSize < this.totalCount) {
this.exportArr[0].percent = Math.ceil(
((params.pageIndex * params.pageSize) / this.totalCount) * 100
);
params.pageIndex++;
this.circleGetSingExc(params);
} else {
this.exportArr[0].percent = 100;
}
}
});
},
/* 循环下载 多个Excel表*/
circleGet(params, single) {
let _index = Math.ceil(
(params.pageIndex * params.pageSize) / this.limitNumber
); //当前第几个EXCEL表格
this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
if (res.body.status === "SUCCEED" || !!res.body.status) {
let datas = res.body.datas || res.body.data;
if (!!this.options.special) {
datas.forEach((item, index) => {
item = { ...item, ...item[this.options.special] };
this.$set(datas, index, item);
});
}
datas.forEach((item) => {
for (let key in this.changeObj) {
if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
item[key]+='';
}
if (!!item[key]) {
item[key] = filters[this.changeObj[key]](item[key]);
}
}
if (!!this.options.otherFunction) {
this.options.otherFunction(item);
}
});
this.exportArr[_index - 1].export.push(...datas);
if (params.pageIndex * params.pageSize < this.totalCount) {
this.exportArr[_index - 1].percent = Math.ceil(
(this.exportArr[_index - 1].export.length / this.limitNumber) *
100
);
params.pageIndex++;
this.circleGet(params);
} else {
this.exportArr[_index - 1].percent = 100;
}
}
});
},
// 省份
getProvinceList() {
let _this = this;
_this.$http
.get("api/findProvincesAndCities", {
params: { keywords: "中国", level: "COUNTRY", sub: 2 },
})
.then(function (res) {
if (res.body.status && res.body.data[0]) {
_this.provinceList = res.body.data[0].divisions;
}
});
},
// 性别切换
genderChange(gender) {
if (gender === "M") {
return "男";
} else if (gender === "F") {
return "女";
}
},
// 省份切换
searchByprovinceCode: function (provinceCode) {
for (let i in this.provinceList) {
if (this.provinceList[i].id == provinceCode) {
return this.provinceList[i].name;
}
}
},
// 城市切换
searchByCityCode: function (cityCode) {
for (let i in this.provinceList) {
for (let j in this.provinceList[i].divisions) {
if (this.provinceList[i].divisions[j].id == cityCode) {
return this.provinceList[i].divisions[j].name;
}
}
}
},
_export(data) {
console.log(data)
let _this = this;
let returnArr = [];
let columns = this.options.columns;
let tempArr = [];
columns.forEach((item) => tempArr.push(item.label));
returnArr.push(tempArr);
data.forEach((item) => {
item.provinceCode = _this.searchByprovinceCode(item.provinceCode);
item.cityCode = _this.searchByCityCode(item.cityCode);
item.gender = _this.genderChange(item.gender);
// item.saleDate = moment(item.saleDate).format("YYYY-MM-DD");
item.serviceDate = item.serviceDate;
let keyArr = [];
columns.forEach((col) => keyArr.push(item[col.prop]));
returnArr.push(keyArr);
});
const wopts = { bookType: "xlsx", bookSST: false, type: "binary" };
const wb = { SheetNames: ["Sheet1"], Sheets: {}, Props: {} };
let objName = this.options.name ? this.options.name : "车主信息列表";
wb.Sheets["Sheet1"] = XLSX.utils.aoa_to_sheet(returnArr);
saveAs.saveAs(
new Blob([s2ab(XLSX.write(wb, wopts))], {
type: "application/octet-stream",
}),
objName + "." + (wopts.bookType == "biff2" ? "xls" : wopts.bookType)
);
function s2ab(s) {
if (typeof ArrayBuffer !== "undefined") {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
} else {
var buf = new Array(s.length);
for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;
return buf;
}
}
},
},
created() {
this.getProvinceList();
},
props: ["options"],
};
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。