vue + file-saver + xlsx导出 execl文件(简单自定义表头和表数据)
1 导入依赖ExcelExportTemplate.vue 为以下内容<template><div id="exportExcelTemplate" hidden style="display: none"></div></template><script>import xyFileSaver from '...
·
1 导入依赖
ExcelExportTemplate.vue 为以下内容
<template>
<div id="exportExcelTemplate" hidden style="display: none"></div>
</template>
<script>
import xyFileSaver from 'file-saver';
import Vue from 'vue/dist/vue.esm.js';
import xyXLSX from 'xlsx';
/**
* 导出excel模板
* @Author YJX
* @Date 2019-07-11 21:40.
*/
export default {
//name: ,
mounted() {
},
components: {},
props: {},
data() {
return {}
},
computed: {},
methods: {
/**
* 使用格式
* tabName:导出文件名称
* tabHandle:['设备号','门店名称'] //表头必须和tabData的字段排序一样
* tabData:[{"serial":"bhz001","storeName":"黄均益百花洲店"},{"serial":"bhz002","storeName":"黄均益百花洲店2"}]
*
* @author YJX
* @date 2019-07-11 21:45
**/
exportExcel(tabName, tabHandle, tabData) {
//判断表头和数据字段数量是否一致()
if ((tabHandle.length) !== Object.keys(Object.values(tabData)[0]).length) {
throw new Error('表头长度和数据长度不一致!');
}
//拼接tab
let dataStr = '<tr><td>序号</td>';
for (let tabHandleKey in tabHandle) {
dataStr+='<td>'+tabHandle[tabHandleKey]+'</td>'
}
dataStr+='</tr>';
for (let tabDataKey in tabData) {
let index = parseInt(tabDataKey)+1;
dataStr += '<tr><td>' + index + '</td>';
let a = Object.values(tabData[tabDataKey]);
for (let aKey in a) {
dataStr += '<td>' + a[aKey] + '</td>'
}
dataStr += "</tr>"
}
let data = {
tabHandle: tabHandle,
tabData: tabData,
dataStr: dataStr
};
let template = new Vue({
el: '#exportExcelTemplate',
data: data,
template: `
<div id="exportExcelTemplate" style="display: none">
<table v-html="dataStr">
{{dataStr}}
</table>
</div>`
});
let wb = xyXLSX.utils.table_to_book(template.$el);
let wbout = xyXLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'});
try {
xyFileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), tabName + '.xlsx');
} catch (e) {
if (typeof console !== 'undefined')
console.log(e, wbout)
}
return wbout
},
},
watch: {},
filters: {},
beforeDestroy() {
}
}
</script>
<style scoped>
</style>
使用方法
TerminalTable.vue 为以下内容
<template>
<div>
<div>
<el-table
ref="terminalTable"
:data="tableData"
stripe
border
@selection-change="selectionChangeHandle"
:empty-text="emptyText"
style="width: 100%">
<el-table-column v-if="false"
type="selection"
align="center"
width="55">
</el-table-column>
<el-table-column
type="index"
:index="indexMethod"
align="center"
width="50">
</el-table-column>
<el-table-column
align="center"
property="name"
label="设备名">
</el-table-column>
<el-table-column
align="center"
property="serial"
label="设备号">
</el-table-column>
<el-table-column
align="center"
property="storeName"
label="所属门店">
</el-table-column>
<el-table-column
prop="chiefly"
align="center"
label="默认通道">
<template slot-scope="scope">
<el-popover trigger="click" placement="top">
<div style="text-align: center; margin: 0">
<el-button type="primary" @click="enableHandle(scope.row,1)">默认</el-button>
</div>
<el-button size="mini" slot="reference" :type="scope.row.chiefly===true?'success':'info'">
{{ scope.row.chiefly | appSecretIsDefault}}
</el-button>
</el-popover>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="100">
<template slot-scope="scope">
<el-button type="text" size="small" @click="editHandle(scope.row)">修改</el-button>
<el-button type="text" size="small" @click="deleteHandle(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
@current-change="currentChangeHandle"
:page-size="pageSize"
layout="total, prev, pager, next"
:total="pageTotal">
</el-pagination>
</div>
</div>
<xy-excel-export-template ref="TerminalExportExcel"></xy-excel-export-template>
</div>
</template>
<script>
import xyExcelExportTemplate from '../common/ExcelExportTemplate';
export default {
mounted() {
if (this.$store.state.contextUser.role && this.$store.state.contextUser.role !== 'ADMIN') {
this.loadData()
}
},
components: {
xyExcelExportTemplate
},
props: {
filter: { //过滤器
default: function () {
return {
brandId: undefined, //所属品牌
areaId: undefined, //所属区域
storeId: undefined, //所属区域
}
},
type: Object
},
},
data() {
return {
pageTotal: 0,
pageSize: 10,
pageNo: 1,
emptyText: '',
tableData: []
};
},
computed: {
isAdmin() {
switch (this.$store.state.contextUser.role) {
case 'BRAND' :
this.filter.brandId = this.$store.state.contextUser.id;
break;
}
},
//判断当前选择的是门店
// isRentTreeStore(){
// return this.filter.storeId !== undefined;
// }
},
methods: {
//导出excel
exportExcel() {
let tabData = [];
this.tableData.forEach(item => {
tabData.push({"storeName": item.storeName,"serial": item.serial})
});
let tabHandle = ['门店名称', '设备号'];
this.$refs.TerminalExportExcel.exportExcel("设备号导出", tabHandle, tabData);
},
/*索引排序*/
indexMethod(index) {
if (this.pageNo > this.pageTotal / this.pageSize) {
if (this.pageTotal % this.pageSize === 0) {
this.pageNo = parseInt(this.pageTotal / this.pageSize);
} else {
this.pageNo = parseInt(this.pageTotal / this.pageSize) + 1;
}
}
return index + this.pageSize * (this.pageNo - 1) + 1;
},
/**
* 数据加载
*/
loadData: function (filter) {
let _this = this;
let params = Object.assign(_this.filter, {
pageNo: this.pageNo,
pageSize: this.pageSize
}, filter);
this.$ajax.get("joint/terminal/paging", {
params: params
}).then(res => {
if (res.code === '0') {
_this.tableData = res.data;
_this.pageTotal = res.count;
_this.emptyText = res.msg;
} else {
_this.$message.error(res.msg);
}
})
},
/**
* 当表格有一行选中事件
*/
selectionChangeHandle: function (selection) {
},
/**
* 修改事件
*/
editHandle: function (row) {
this.$emit('onEdit', row);
},
/**
* 删除事件
*/
deleteHandle: function (row) {
this.$emit('onDelete', row);
},
/**
* 分页提交
* @param val
*/
currentChangeHandle: function (val) {
this.pageNo = val;
this.loadData();
},
/**
* 修改默认设备
*/
enableHandle: function (row, val) {
this.$confirm('默认设备号真的要修改吗?', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (val && row.chiefly === 1) {
return;
}
if (!val && row.chiefly === 0) {
return;
}
let _this = this;
this.$ajax.put('/joint/terminal/dmlchiefly/' + row.id, {}
).then(res => {
if (res.code === '0') {
_this.loadData()
} else {
_this.$message.error(res.msg);
}
});
}).catch(() => {
//nothing to do
});
},
},
watch: {},
filters: {
appSecretIsDefault(val) {
return val === true ? "默认" : "非默认";
}
},
beforeDestroy() {
}
}
</script>
<style scoped>
</style>
效果
更多推荐
已为社区贡献2条内容
所有评论(0)