vue + file-saver + xlsx导出 execl文件(简单自定义表头和表数据)

1 导入依赖

vue + file-saver + xlsx导出 execl文件(简单自定义表头和表数据)_第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 = '序号';
                for (let tabHandleKey in tabHandle) {
                    dataStr+=''+tabHandle[tabHandleKey]+''
                }
                dataStr+='';
                for (let tabDataKey in tabData) {
                    let index = parseInt(tabDataKey)+1;
                    dataStr += '' + index + '';
                    let a = Object.values(tabData[tabDataKey]);
                    for (let aKey in a) {
                        dataStr += '' + a[aKey] + ''
                    }
                    dataStr += ""
                }
                let data = {
                    tabHandle: tabHandle,
                    tabData: tabData,
                    dataStr: dataStr
                };
                let template = new Vue({
                    el: '#exportExcelTemplate',
                    data: data,
                    template: `
                      `
                });
                
                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>

效果

vue + file-saver + xlsx导出 execl文件(简单自定义表头和表数据)_第2张图片

你可能感兴趣的:(vue)