vue+element 使用Export2Excel導出表格組件


下載表格組件是根據我自己的業務需求來封裝的


使用的是vue中 xlsx 的插件,需要安裝新的依賴及配置

 

僅供參考 不保證和你百分百匹配

 

 

安裝依賴

npm install -S file-saver xlsx

npm install -D script-loader

下載所需js

鏈接: https://pan.baidu.com/s/170okRAPiWxQrBvlDEpp7SQ 提取碼: gsf5 

百度網盤真特喵的是個好東西啊

因為我的子組件引用了該js 如果你不想自己再修改位置,可以跟我一樣,

在src中,建立excel文件,將下載的js扔進去

 

 

組件調用

直接說調用部分,文章最后會把組件的代碼貼出來

 

父組件引入子組件

import exportTable from '@/components/common/exportTable';

......

components:{

  exportTable

}

父組件調用子組件

<export-table ref="childRefName" :export-prepare.sync="exportPrepare" :list-query.sync="listQuery"></export-table>

 

  

 

 參數詳解

exportPrepare:{
    percentage: 0, //導出數據完成的百分比
    name:'消耗記錄',//導出表格名稱
    pageType:'pagination',//導出數據獲取方式:offset為偏移量、pagination為分頁 默認值為pagination
    limit:200,//單頁數據數量 最大值為200 超過200 按200讀取(自定義)或 perPage: 200(根據接口參數決定使用limit/perPage,暫時僅支持limit/perPage)
    total:0,//導出數據總數
    json_fields: {  // excel 表頭(具體名稱根據實際情況而定)
        '耗材編號': 'String',
        '耗材品牌': 'String',
        '耗材類型': 'String',
        '耗材名稱': 'String',
        '規格型號': 'String',
        '耗材屬性': 'String',
        '耗材價格': 'Number',
        '消耗類型': 'String',
        '消耗地點': 'String',
        '出庫倉': 'String',
        '目標設備': 'String',
        '操作人': 'String',
        '操作時間': 'String'
    },
    json_relationship:{ //導出數據對應的字段名稱(具體字段根據實際情況而定 key值與表頭保持一致)
        '耗材編號': 'supplies_number',
        '耗材品牌': 'brand_name',
        '耗材類型': 'type',
        '耗材名稱': 'supplies_name',
        '規格型號': 'spec_name',
        '耗材屬性': 'spec_attribute',
        '耗材價格': 'cost',
        '消耗類型': 'supplies_type',
        '消耗地點': 'out_address',
        '出庫倉': 'warehouse_name',
        '目標設備': 'device_id',
        '操作人': 'staff_name',
        '操作時間': 'updated_at'
    },
    param:{},//獲取導引數據接口所需的參數
    dataList:[]
}

  注:json_relationship的值一定與json_fields的值保持一致,否則導出的表會出現空表的問題

listQuery: {    // 列表請求數據
    where: {},//where是我的接口用到的篩選數據的條件 沒有可以直接去掉
    page: 1,
    limit: 20
}

  注:子組件導出數據時頁碼,會引起父頁面修改exportPrepare的param的page、limit參數,使用listQuery進行獨立數據深拷貝,子組件的參數變化就不會引起父頁面的變化

 

頁面處理導出數據

父組件內獲取導出數據的方法

getExcelData(){
    this.$refs.exportExcel.index+=1;
    if(this.$refs.exportExcel.index<this.$refs.exportExcel.params.length) {
        suppliesWaitInExcelData( this.$refs.exportExcel.params[this.$refs.exportExcel.index]).then((response) => {
            const data = this.data_ext ? response[this.data_ext].data : response.data;
            //data的值,需要根據實際的response數據格式進行賦值
            const relationship = this.exportPrepare.json_relationship;
            for (let i in data) {
                var item = {};
                for (let attr in relationship) {
                    item[attr] = !data[i][relationship[attr]] && data[i][relationship[attr]] !== 0 ? '' : data[i][relationship[attr]];
                }
                this.exportPrepare.dataList.push(item);
            }
            this.exportPrepare.percentage = Number((this.exportPrepare.dataList.length / this.exportPrepare.total*100).toFixed(0)) || 0;
            this.getExcelData();
        })
        .catch(e=>{//這里是處理接口獲取失敗的情況 => 重新執行該條 知道走通(不需要可以把這個部分清空)
            console.log('失敗了')
            this.$refs.exportExcel.index-=1;
            this.getExcelData();
        })
    }
}

  注:getExcelData:為固定方法名稱,不可以自定義(子組件內有調用 除非兩者保持一致)
    suppliesWaitInExcelData:獲取導出數據的接口api名稱,根據具體項目需求更換(接口封裝方法不同,調用api方法不同,請根據實際情況修改)

 

子組件封裝

注:子組件中用到this.$parents.doSomeThing()的方式去尋找父組件的方法,所以子組件不能被包裹在別的組件中(包括ele、el-row等element或自定義組件),否則會因為父組件層級問題,找不到對應的父組件方法

或者根據具體情況修改子組件內的方法 ex:this.$parents.$parents.doSomeThing() 多找一層parent 有可能會找到 但是不推薦

 

<template>
    <div id="export-excel">
        <el-button type="primary" icon="document" class="export-btn" @click="init">導出數據</el-button>
        <el-dialog title="導出" :visible.sync="form.dialogFormVisible" size="tiny" :before-close="handleClose">
            <div class="prev-btn right">
                <el-progress :percentage="exportPrepare.percentage" style="margin-bottom: 20px;"></el-progress>
                <p style="color:#F56C6C;font-size:12px;" v-show="exportTips">數據量過大,推薦選擇精確數據下載</p>
                <el-button type="primary" @click="exportAction" v-if="exportPrepare.total == exportPrepare.dataList.length">導出</el-button>
                <el-button type="primary" class="cancel-action" v-else>導出</el-button>
                <el-button @click="handleClose">取消</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script type="application/ecmascript">
export default {
    name: "export-excel",
    props: {
        exportPrepare: {
            type: Object
        },
        listQuery: {
            type: Object
        }

    },
    data() {
        return {
            params: [],
            paramsItem: {},
            index: -1,
            // 導出表單所需數據對象
            form: {
                loading: false,
                dialogFormVisible: false,
            },
            pageType: 'pagination', //獲取數據方式 pagination為分頁方式  offset為偏移量方式
            json_meta: [ // 設置字符集
                [{
                    key: "charset",
                    value: "utf-8"
                }]
            ], // excel表頭
            json_data: [], // 要導出的數據
            dataList: [], // 要導出的數據
            button_text: '', // 導出按鈕名稱
            data_ext: '', // 數據后綴 防止返回的數據格式不是[obj, obj...]
            childExportPrepare:{},
            exportTips:false,//數據過大提示
        };
    },
    mounted() {
        this.pageType = this.exportPrepare.pageType || 'pagination'
        this.childExportPrepare =  JSON.parse(JSON.stringify(this.listQuery))
    },
    watch: {
        listQuery(newValue, oldValue) {
            this.childExportPrepare =  JSON.parse(JSON.stringify(this.listQuery))
        }
    },
    methods: {
        // 導出初始化
        init() {
            this.form.dialogFormVisible = true;
            this.data_ext = this.exportPrepare.data_ext || '';
            this.fetchExportList();
        },

        // 數據列表分次獲取
        fetchExportList() {
            this.childExportPrepare =  JSON.parse(JSON.stringify(this.listQuery))
            this.exportPrepare.dataList = [];
            this.index = -1;
            this.params = [];
            this.exportPrepare.percentage = 0;
            this.json_data = [];
            if (this.pageType == 'offset') {
                if(this.exportPrepare.limit){
                    if (this.exportPrepare.total > this.exportPrepare.limit) {
                        this.json_data = [];
                        let param = {}
                        param = this.childExportPrepare
                        for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.limit); i++) {
                            if(i>=20){
                                this.exportTips = true;
                            }else{
                                this.exportTips = false;
                            }
                            if(this.exportPrepare.limit>200){
                                this.exportPrepare.limit = 200;
                            }
                            var startPage = 0,
                                endlimit = 0;
                            startPage = i * this.exportPrepare.limit;
                            this.$set(param,'page',startPage)
                            endlimit = this.exportPrepare.limit;
                            if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.limit) - 1 && this.exportPrepare.total % this.exportPrepare.limit != 0) {
                                endlimit = this.exportPrepare.total % this.exportPrepare.limit
                            }
                            this.$set(param,'limit',endlimit)
                            let paramList = {page:param.page,limit:param.limit};
                            this.form.loading = true;
                            this.params.push(Object.assign(paramList,this.childExportPrepare));
                        }
                        this.$parent.$parent.getExcelData()
                        this.json_data = this.exportPrepare.dataList;
                    } else {

                        this.json_data = [];
                        this.params = [];
                        this.childExportPrepare.page = 0;
                        this.childExportPrepare.limit = this.exportPrepare.total;
                        let param = [];
                        param.page = 0;
                        param.limit = this.exportPrepare.total;
                        let paramList = {page:param.page,limit:param.limit};
                        this.params.push(Object.assign(paramList,this.childExportPrepare));
                        this.form.loading = true;
                        this.$parent.$parent.getExcelData();
                        this.json_data = this.exportPrepare.dataList;
                    }
                }else{
                    if (this.exportPrepare.total > this.exportPrepare.perPage) {
                        this.json_data = [];
                        let param = {};
                        param = this.childExportPrepare
                        for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage); i++) {
                            if(i>=20){
                                this.exportTips = true;
                            }else{
                                this.exportTips = false;
                            }
                            if(this.exportPrepare.perPage>200){
                                this.exportPrepare.perPage = 200;
                            }
                            var startPage = 0,
                                endlimit = 0;
                            startPage = i * this.exportPrepare.perPage;
                            this.$set(param,'page',startPage)
                            endlimit = this.exportPrepare.perPage;
                            if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage) - 1 && this.exportPrepare.total % this.exportPrepare.perPage != 0) {
                                endlimit = this.exportPrepare.total % this.exportPrepare.perPage
                            }
                            this.$set(param,'perPage',endlimit)
                            let paramList = {page:param.page,perPage:param.perPage};
                            this.form.loading = true;
                            this.params.push(Object.assign(paramList,this.childExportPrepare));
                        }
                        this.$parent.$parent.getExcelData()
                        this.json_data = this.exportPrepare.dataList;
                    } else {
                        this.json_data = [];
                        this.params = [];
                        this.childExportPrepare.page = 0;
                        this.childExportPrepare.limit = this.exportPrepare.total;
                        let param = [];
                        param.page = 0;
                        param.perPage = this.exportPrepare.total;
                        let paramList = {page:param.page,perPage:param.perPage};
                        this.params.push(Object.assign(paramList,this.childExportPrepare));
                        this.form.loading = true;
                        this.$parent.$parent.getExcelData();
                        this.json_data = this.exportPrepare.dataList;
                    }
                }
            } else {
                if(this.exportPrepare){
                    if (this.exportPrepare.total > this.exportPrepare.limit) {
                        this.json_data = [];
                        let param = {}
                        param = this.childExportPrepare
                        for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.limit); i++) {
                            if(i>=20){
                                this.exportTips = true;
                            }else{
                                this.exportTips = false;
                            }
                            if(this.exportPrepare.limit>200){
                                this.exportPrepare.limit = 200;
                            }
                            let startPage = 0, endlimit = 0;
                            startPage = i + 1;
                            this.$set(param,'page',startPage)
                            endlimit = this.exportPrepare.limit;
                            if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.limit) - 1 && this.exportPrepare.total % this.exportPrepare.limit != 0) {
                                endlimit = this.exportPrepare.total % this.exportPrepare.limit
                            }
                            this.$set(param,'limit',endlimit)
                            let paramList = {page:param.page,limit:param.limit};
                            this.form.loading = true;
                            this.params.push(Object.assign(paramList,this.childExportPrepare));
                        }
                        this.$parent.$parent.getExcelData()
                        this.json_data = this.exportPrepare.dataList;
                    } else {
                        this.json_data = [];
                        this.params = [];
                        this.childExportPrepare.page = 1;
                        this.childExportPrepare.limit = this.exportPrepare.total;
                        let param = [];
                        param.page = 1;
                        param.limit = this.exportPrepare.total;
                        let paramList = {page:param.page,limit:param.limit};
                        this.params.push(Object.assign(paramList,this.childExportPrepare));
                        this.form.loading = true;
                        this.$parent.$parent.getExcelData();
                        this.json_data = this.exportPrepare.dataList;
                    }
                }else{
                    if (this.exportPrepare.total > this.exportPrepare.perPage) {
                        this.json_data = [];
                        let param = {}
                        param = this.childExportPrepare
                        for (let i = 0; i < Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage); i++) {
                            if(i>=20){
                                this.exportTips = true;
                            }else{
                                this.exportTips = false;
                            }
                            if(this.exportPrepare.perPage>200){
                                this.exportPrepare.perPage = 200;
                            }
                            var startPage = 0,
                                endlimit = 0;
                            startPage = i + 1;
                            this.$set(param,'page',startPage)
                            endlimit = this.exportPrepare.perPage;
                            if (i >= Math.ceil(this.exportPrepare.total / this.exportPrepare.perPage) - 1 && this.exportPrepare.total % this.exportPrepare.perPage != 0) {
                                endlimit = this.exportPrepare.total % this.exportPrepare.perPage
                            }
                            this.$set(param,'perPage',endlimit)
                            let paramList = {page:param.page,perPage:param.perPage};
                            this.form.loading = true;
                            this.params.push(Object.assign(paramList,this.childExportPrepare));
                        }
                        this.$parent.$parent.getExcelData()
                        this.json_data = this.exportPrepare.dataList;

                    } else {
                        this.json_data = [];
                        this.params = [];
                        this.childExportPrepare.page = 1;
                        this.childExportPrepare.limit = this.exportPrepare.total;
                        let param = [];
                        param.page = 1;
                        param.perPage = this.exportPrepare.total;
                        let paramList = {page:param.page,perPage:param.perPage};
                        this.params.push(Object.assign(paramList,this.childExportPrepare));
                        this.form.loading = true;
                        this.$parent.$parent.getExcelData();
                        this.json_data = this.exportPrepare.dataList;
                    }
                }
            }
        },

        //導出
        exportAction() {
            if (this.exportPrepare.total == this.json_data.length) {
                require.ensure([], () => {
                    const {
                        export_json_to_excel
                    } = require('../../excel/Export2Excel');
                    const tHeader = [];
                    for (let i in this.exportPrepare.json_fields) {
                        tHeader.push(i);
                    }
                    if (this.json_data.length < 1) {
                        this.fetchExportList();
                        return
                    }
                    const list = this.json_data;
                    const data = this.formatJson(tHeader, list);
                    export_json_to_excel(tHeader, data, this.exportPrepare.name || '導出數據');
                    this.form.loading = true;
                    setTimeout(() => {
                        this.form.loading = false;
                        this.$notify({
                            title: '成功',
                            message: '導出成功',
                            type: 'success',
                            duration: 1500
                        });
                        this.form.dialogFormVisible = false;
                        this.json_data = [];
                        this.dataList = [];
                        this.exportPrepare.dataList = [];
                    }, 500);
                })
            }
        },

        formatJson(filterVal, jsonData) {
            return jsonData.map(v => filterVal.map(j => v[j]))
        },

        // 關閉導出對話框
        handleClose() {
            this.form.dialogFormVisible = false;
            this.exportPrepare.dataList = [];
            this.json_data = [];
            this.dataList = [];
            this.params = [];
            this.exportPrepare.percentage = 0;
        }
    }
}
</script>

<style scoped="scoped" lang="scss">
.cancel-action {
    opacity: .4;
}

.right {
    text-align: right;
}
#export-excel{
  float: right;
}
</style>
View Code

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM