zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    02
    springmvc根据请求uri获取handlermapping源码
    springmvc零xml配置原理
    maven使用tomcat插件出现Failed to start component [StandardService[Tomcat]]: Failed to start component [StandardEngine[Tomcat]]: A child container failed during startd错误
    zipkin以JAR文件启动以Mysql作为持久化方式
    OAuth2AuthenticationProcessingFilter资源认证服务器过滤器
    OAuth2中四种授权模式以及相应操作
    JVM双亲委派机制
    springcloud对应springboot版本【如果版本依赖不对,则会出现一堆神奇的问题】
    python实现一元二次表达式求值
  • 原文地址:https://www.cnblogs.com/tongjiaojiao/p/11888910.html
Copyright © 2011-2022 走看看