美文网首页flask我爱编程Web 前端开发
Bootstrap Table结合tableExport.jqu

Bootstrap Table结合tableExport.jqu

作者: 李北北 | 来源:发表于2017-10-16 14:37 被阅读2316次

    最近几天因为项目需要做一个导出导出表格数据到Excel功能,我们的项目的前端框架用的是Bootstrap Table,去百度了一下发现其本身有一个导出扩展,那就是结合了tableExport.jquery.plugin扩展。
    但是如果直接使用这个扩展的话,只能在Bootstrap Table的toolbar上面显示导出菜单,而我们的项目是要在特定位置设置一个导出按钮的。于是就研究了几天,终于找到了解决方法,先看两张示意图:

    1、页面

    Paste_Image.png

    2、导出结果


    Paste_Image.png

    下面就让我一步步来介绍实现的过程。

    HTML代码

    HTML代码定义了Bootstrap Table的工具菜单栏以及表格标签

    <div class="container-fluid" id="main-container">
    <div id="page-content" class="clearfix">
        <div class="row-fluid">
            <div class="row-fluid"">
                <div id="toolbar" class="btn-group" style="width: 800px;">
                    <table>
                        
                            <td>
                                <div style="float: right;">
                                    <label>性别</label>
                                    <select style="height: 25px;" name="sex" id="sex" onchange="$('#dataGrid').bootstrapTable('refresh');" >
                                        <option value="" selected >所有</option>
                                        <option value="男">男</option>
                                        <option value="女">女</option>
                                    </select>
                                </div>
                            </td>
                            
                            <td>
                                <div style="float: right;">
                                    <label>是否启用</label>
                                    <select style="height: 25px;" name="userStatus" id="userStatus" onchange="$('#dataGrid').bootstrapTable('refresh');" >
                                        <option value="" selected >全部</option>
                                        <option value="1">是</option>
                                        <option value="0">否</option>
                                    </select>
                                </div>
                            </td>
                                                    
                        </tr>
                        <tr>
                            <td colspan="99">
                                <label>注册时间:</label>
                                <input id="startTime" type="text" placeholder="开始日期" class="datainp wicon"  size="15" readonly>
                                - 
                                <input id="endTime" type="text" placeholder="结束日期" class="datainp wicon"  size="15" readonly>
                                  
                                <label>其他:</label>
                                <input id="search" type="text" placeholder="姓名、手机号、昵称" size="18">
                            
                                 <button type="button" onclick="$('#dataGrid').bootstrapTable('refresh');" class='btn btn-mini btn-info'>搜索</button>
                                 <button type="button" onclick="exportData();" class='btn btn-mini btn-info'>导出一</button>
                                 <button type="button" id="myExportData" value="excel" class='btn btn-mini btn-info'>导出二</button>
                            </td>
                        </tr>
                    </table>
                </div>
              <table id="dataGrid" class="table text-nowrap"></table>
        </div>
        </div>
        <!--/row-->
    </div>
    <!--/#page-content-->
    </div>
    <!--/.fluid-container#main-container-->
    

    导入相关依赖

    首先,当然是导入相关的js了,在这里我们假设已经正确引用了Bootstrap Table相关的js、css,然后还需要再导入下面两个css文件

    <script src="<%=basePath%>static/bootstrapStatic/export/bootstrap-table-export.js"></script>
    <script src="<%=basePath%>static/bootstrapStatic/export/tableExport.js"></script>
    

    其中
    bootstrap-table-export.js 在bootstrap-table下载的解压文件夹dist\extensions\export目录下,
    tableExport.js 在tableExport.jquery.plugin下载的解压文件夹下。

    导入依赖后就可以使用文件导出功能了,下面介绍三种导出菜单设置。

    一、toolbar默认菜单

    该种方式最简单,只需要在Bootstrap Table参数中加入如下参数就可以了

    showExport: true,      //是否显示导出
    

    最终会显示如图默认导出菜单,点击箭头在显示的下拉框中再点击MS-Excel就可以下载.xls类型的Excel文件了。

    Paste_Image.png

    完整代码如下:

    $(function() {
            $('#dataGrid').bootstrapTable(
                            {
                                url : '${prefix}/selectModelVoListPage',
                                method : 'post',
                                toolbar : '#toolbar',
                                contentType : 'application/x-www-form-urlencoded',
                                striped : true,
                                showColumns : true,
                                showRefresh : true,
                                pagination : true,
                                pageSize : 10,
                                sortName : 'id',
                                sidePagination : 'server',
                                queryParamsType : 'limit',
                                queryParams : queryParams,
                                showExport: true,      //是否显示导出
                                buttonsAlign:"right",  //按钮位置
                                exportDataType: "all",              //basic', 'all', 'selected'.
                                exportTypes:['excel'],  //导出文件类型 
                                Icons:'glyphicon-export',  
                                exportOptions:{  
                                    ignoreColumn: [0,12],  //忽略某一列的索引  
                                    fileName: '用户列表',  //文件名称设置  
                                    worksheetName: 'sheet1',  //表格工作区名称  
                                    tableName: '用户列表',
                                    onMsoNumberFormat: doOnMsoNumberFormat,
                                    onCellHtmlData: DoOnCellHtmlData,
                                },
                                columns : [
                                        {
                                            field : 'id',
                                            title : '排序',
                                            align : 'center',
                                            width : 5,
                                            formatter : function(value, row, index) {
                                                return index + 1;
                                            }
                                        },
                                        {
                                            field : 'createTime',
                                            title : '注册时间',
                                            width : 120
                                        },
                                        {
                                            field : 'nickname',
                                            title : '昵称',
                                            align : 'center',
                                            width : 120,
                                            formatter : function(value) {
                                                if(typeof(value) == 'undefined'){
                                                    return '';
                                                }
                                                if(value.length > 6){
                                                    return '<span title="'+value+'">'+value.substring(0,6)+'...</span>';
                                                }else{
                                                    return value;
                                                }
                                            }
                                        },
                                        {
                                            field : 'sex',
                                            title : '性别',
                                            align : 'center',
                                            width : 120
                                        },
                                        {
                                            field : 'userStatus',
                                            title : '是否启用',
                                            align : 'center',
                                            formatter : function(value, row, index) {
                                                var statusJson = {
                                                    0 : "否",
                                                    1 : "是",
                                                };
                                                return statusJson[row.userStatus || 2] || "未知";
                                            }
                                        },
                                        {
                                            field : 'userMemo',
                                            title : '备注',
                                            align : 'center',
                                            width : 100,
                                            formatter : function(value) {
                                                if(typeof(value) == 'undefined'){
                                                    return '';
                                                }
                                                if(value.length > 6){
                                                    return '<span title="'+value+'">'+value.substring(0,6)+'...</span>';
                                                }else{
                                                    return value;
                                                }
                                            }
                                        },
                                        {
                                            field : 'operate',
                                            title : '操作',
                                            align : 'center',
                                            width : 100,
                                            formatter : function(value, row, index) {
                                                var str = '';
                                                str += "<a onclick='edit(\""
                                                        + row.userId
                                                        + "\",\"${prefix}\", \"编辑信息\", 600, 600);' href='javascript:void(0);' class='btn btn-mini btn-info' > <i class='icon-edit'></i> </a>";
                                                return str;
                                            }
                                        }
                                    ]
                            });
        });
        
    
        //数字
        function doOnMsoNumberFormat(cell, row, col){
            var result = "";  
            if (row > 0 && col == 0){
                result = "\\@";  
            }
            return result;  
        }
        
        //处理导出内容,这个方法可以自定义某一行、某一列、甚至某个单元格的内容,也就是将其值设置为自己想要的内容
        function DoOnCellHtmlData(cell, row, col, data){
            if(row == 0){
                return data;
            }
            
            //由于备注列超过6个字的话,通过span标签处理只显示前面6个字,如果直接导出的话会导致内容不完整,因此要将携带完整内容的span标签中title属性的值替换
            if(col == 4 || col ==11 || col == 7){
                var spanObj = $(data);//将带 <span title="val"></span> 标签的字符串转换为jQuery对象
                var title = spanObj.attr("title");//读取<span title="val"></span>中title属性的值
                //var span = cell[0].firstElementChild;//读取cell数组中的第一个值下的第一个元素
                if(typeof(title) != 'undefined'){
                    return title;
                }
            }
            
            return data;
        }
    

    由于默认的导出是只导出当前页显示的可看见的所有列数据,如果需要设置一下导出的结果,还需要加入下面的参数,其中属性方法看上面的完整代码片段。

    buttonsAlign:"right",  //按钮位置
    exportDataType: "all",              //basic' 导出当前页的数据, 'all' 导出所有满足条件的数据, 'selected' 导出勾选中的数据.
    exportTypes:['excel'],  //导出文件类型 
    Icons:'glyphicon-export',  
    exportOptions:{  
        ignoreColumn: [0,12],  //忽略某些列的索引数组
        fileName: '用户列表',  //文件名称设置  
        worksheetName: 'sheet1',  //表格工作区名称  
        tableName: '用户列表',
        onMsoNumberFormat: doOnMsoNumberFormat,//大概是处理数字的方法
        onCellHtmlData: DoOnCellHtmlData,//这个属性方法可以重新修改每一个单元格的值
    },
    

    这样子最终得到的导出结果如图

    Paste_Image.png

    二、自定义菜单一

    在百度中找到一种方法,就是通过tableExport.js中提供的tableExport()方法执行导出的,代码如下,要特别注意Bootstrap Table中设置的参数在这里是无效的,需要按照代码中的方式重新设置

    function exportData(){
            //导出数据
            $('#dataGrid').tableExport({
                                         type: 'excel', 
                                         exportDataType: "all",
                                         escape: 'false',
                                         ignoreColumn: [0,12],  //忽略某一列的索引  
                                         fileName: '用户列表',  //文件名称设置  
                                         worksheetName: 'sheet1',  //表格工作区名称  
                                         tableName: '用户列表',
                                         onMsoNumberFormat: doOnMsoNumberFormat,
                                         onCellHtmlData: DoOnCellHtmlData,
                                      });
    }
        
        //数字
        function doOnMsoNumberFormat(cell, row, col){
            var result = "";  
            if (row > 0 && col == 0){
                result = "\\@";  
            }
            return result;  
        }
        
        //处理导出内容,这个方法可以自定义某一行、某一列、甚至某个单元格的内容,也就是将其值设置为自己想要的内容
        function DoOnCellHtmlData(cell, row, col, data){
            if(row == 0){
                return data;
            }
            
            //由于备注列超过6个字的话,通过span标签处理只显示前面6个字,如果直接导出的话会导致内容不完整,因此要将携带完整内容的span标签中title属性的值替换
            if(col == 4 || col ==11 || col == 7){
                var spanObj = $(data);//将带 <span title="val"></span> 标签的字符串转换为jQuery对象
                var title = spanObj.attr("title");//读取<span title="val"></span>中title属性的值
                //var span = cell[0].firstElementChild;//读取cell数组中的第一个值下的第一个元素
                if(typeof(title) != 'undefined'){
                    return title;
                }
            }
            
            return data;
        }
    

    将exportData()方法绑定到按钮导出一

    <button type="button" onclick="exportData();" class='btn btn-mini btn-info'>导出一</button>
    

    如图,点击导出一,就可以导出Excel文件了


    Paste_Image.png

    可以看到即使在参数列表中加入了exportDataType: "all",最终导出的结果也只是当前页面的数据,说明这个参数在这种导出方式是无效的。

    三、自定义菜单二

    在方式二导出所有数据无效之后,我再去百度找解决方法找了好久还是没有结果,实在没办法了就换一个思路,就是自己去研究bootstrap-table-export.js 和tableExport.js 两个文件的源码,最后我发现

    1、方式一导出是先执行bootstrap-table-export.js中的下面代码

    $menu.find('li').click(function () {
                    var type = $(this).data('type'),
                        doExport = function () {
                            that.$el.tableExport($.extend({}, that.options.exportOptions, {
                                type: type,
                                escape: false
                            }));
                        };
    
                    if (that.options.exportDataType === 'all' && that.options.pagination) {
                        that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
                            doExport();
                            that.togglePagination();
                        });
                        that.togglePagination();
                    } else if (that.options.exportDataType === 'selected') {
                        var data = that.getData(),
                            selectedData = that.getAllSelections();
    
                        // Quick fix #2220
                        if (that.options.sidePagination === 'server') {
                            data = {total: that.options.totalRows};
                            data[that.options.dataField] = that.getData();
    
                            selectedData = {total: that.options.totalRows};
                            selectedData[that.options.dataField] = that.getAllSelections();
                        }
    
                        that.load(selectedData);
                        doExport();
                        that.load(data);
                    } else {
                        doExport();
                    }
                });
    

    然后执行tableExport.js中的方法

    tableExport: function (options) {
          。。。。
    }
    

    2、方式二是直接执行tableExport.js中的方法

    tableExport: function (options) {
          。。。。
    }
    

    从上面的源码可以看到里面的代码

    if (that.options.exportDataType === 'all' && that.options.pagination) {
                    that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
                        doExport();
                        that.togglePagination();
                    });
                    that.togglePagination();
                }
    

    这里大意就是如果是导出 'all' ,就会去服务器查询所有的数据然后再导出。

    再用谷歌浏览器检查那个默认导出菜单的源码如下:

    <div class="export btn-group open">
    <button class="btn btn-default dropdown-toggle" aria-label="export type" title="Export data" data-toggle="dropdown" type="button" aria-expanded="true">
        <i class="glyphicon glyphicon-export icon-share"></i> 
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
        <li role="menuitem" data-type="excel">
            <a href="javascript:void(0)">MS-Excel</a>
        </li>
    </ul>
    </div>
    

    再根据bootstrap-table-export.js中的$menu.find('li').click(function () { }触发click事件,估计是这个方法是监听到点击事件然后触发导出方法。

    到这里我就想能不能通过id选择器给一个自定义的按钮加上监听事件,于是就复制了这个方法的代码加在其后面,并做一下修改,如下:

                 //自定义监听菜单,当对应ID的按钮被点击时候,会执行方法
                $("#myExportData").click(function () {
                    var type = $("#myExportData").val(),//导出文件类型,赋值在按钮标签上的value属性
                        doExport = function () {
                            that.$el.tableExport($.extend({}, that.options.exportOptions, {
                                type: type,
                                escape: false
                            }));
                        };
    
                    if (that.options.exportDataType === 'all' && that.options.pagination) {
                        that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
                            doExport();
                            that.togglePagination();
                        });
                        that.togglePagination();
                    } else if (that.options.exportDataType === 'selected') {
                        var data = that.getData(),
                            selectedData = that.getAllSelections();
    
                        // Quick fix #2220
                        if (that.options.sidePagination === 'server') {
                            data = {total: that.options.totalRows};
                            data[that.options.dataField] = that.getData();
    
                            selectedData = {total: that.options.totalRows};
                            selectedData[that.options.dataField] = that.getAllSelections();
                        }
    
                        that.load(selectedData);
                        doExport();
                        that.load(data);
                    } else {
                        doExport();
                    }
                });
    

    HTML中定义的按钮button,将其id设置为js中定义的myExportData,将导出类型excel赋值在其value属性上。

    <button type="button" id="myExportData" value="excel" class='btn btn-mini btn-info'>导出二</button>
    

    如图点击导出二,就可以导出所有符合查询条件的数据了


    Paste_Image.png

    最后贴出修改后的bootstrap-table-export.js文件的全部源码。

    /**
     * @author zhixin wen <wenzhixin2010@gmail.com>
     * extensions: https://github.com/kayalshri/tableExport.jquery.plugin
     */
    (function ($) {
    'use strict';
    var sprintf = $.fn.bootstrapTable.utils.sprintf;
    
    var TYPE_NAME = {
        json: 'JSON',
        xml: 'XML',
        png: 'PNG',
        csv: 'CSV',
        txt: 'TXT',
        sql: 'SQL',
        doc: 'MS-Word',
        excel: 'MS-Excel',
        xlsx: 'MS-Excel (OpenXML)',
        powerpoint: 'MS-Powerpoint',
        pdf: 'PDF'
    };
    
    $.extend($.fn.bootstrapTable.defaults, {
        showExport: false,
        exportDataType: 'basic', // basic, all, selected
        // 'json', 'xml', 'png', 'csv', 'txt', 'sql', 'doc', 'excel', 'powerpoint', 'pdf'
        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
        exportOptions: {}
    });
    
    $.extend($.fn.bootstrapTable.defaults.icons, {
        export: 'glyphicon-export icon-share'
    });
    
    $.extend($.fn.bootstrapTable.locales, {
        formatExport: function () {
            return 'Export data';
        }
    });
    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
    
    var BootstrapTable = $.fn.bootstrapTable.Constructor,
        _initToolbar = BootstrapTable.prototype.initToolbar;
    
    BootstrapTable.prototype.initToolbar = function () {
        this.showToolbar = this.options.showExport;
    
        _initToolbar.apply(this, Array.prototype.slice.apply(arguments));
    
        if (this.options.showExport) {
            var that = this,
                $btnGroup = this.$toolbar.find('>.btn-group'),
                $export = $btnGroup.find('div.export');
    
            if (!$export.length) {
                $export = $([
                    '<div class="export btn-group">',
                        '<button class="btn' +
                            sprintf(' btn-%s', this.options.buttonsClass) +
                            sprintf(' btn-%s', this.options.iconSize) +
                            ' dropdown-toggle" aria-label="export type" ' +
                            'title="' + this.options.formatExport() + '" ' +
                            'data-toggle="dropdown" type="button">',
                            sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.export),
                            '<span class="caret"></span>',
                        '</button>',
                        '<ul class="dropdown-menu" role="menu">',
                        '</ul>',
                    '</div>'].join('')).appendTo($btnGroup);
    
                var $menu = $export.find('.dropdown-menu'),
                    exportTypes = this.options.exportTypes;
    
                if (typeof this.options.exportTypes === 'string') {
                    var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');
    
                    exportTypes = [];
                    $.each(types, function (i, value) {
                        exportTypes.push(value.slice(1, -1));
                    });
                }
                $.each(exportTypes, function (i, type) {
                    if (TYPE_NAME.hasOwnProperty(type)) {
                        $menu.append(['<li role="menuitem" data-type="' + type + '">',
                                '<a href="javascript:void(0)">',
                                    TYPE_NAME[type],
                                '</a>',
                            '</li>'].join(''));
                    }
                });
    
                $menu.find('li').click(function () {
                    var type = $(this).data('type'),
                        doExport = function () {
                            that.$el.tableExport($.extend({}, that.options.exportOptions, {
                                type: type,
                                escape: false
                            }));
                        };
    
                    if (that.options.exportDataType === 'all' && that.options.pagination) {
                        that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
                            doExport();
                            that.togglePagination();
                        });
                        that.togglePagination();
                    } else if (that.options.exportDataType === 'selected') {
                        var data = that.getData(),
                            selectedData = that.getAllSelections();
    
                        // Quick fix #2220
                        if (that.options.sidePagination === 'server') {
                            data = {total: that.options.totalRows};
                            data[that.options.dataField] = that.getData();
    
                            selectedData = {total: that.options.totalRows};
                            selectedData[that.options.dataField] = that.getAllSelections();
                        }
    
                        that.load(selectedData);
                        doExport();
                        that.load(data);
                    } else {
                        doExport();
                    }
                });
                
                //自定义监听菜单,当对应ID的按钮被点击时候,会执行方法
                $("#myExportData").click(function () {
                    var type = $("#myExportData").val(),//导出文件类型,赋值在按钮标签上的value属性
                        doExport = function () {
                            that.$el.tableExport($.extend({}, that.options.exportOptions, {
                                type: type,
                                escape: false
                            }));
                        };
    
                    if (that.options.exportDataType === 'all' && that.options.pagination) {
                        that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () {
                            doExport();
                            that.togglePagination();
                        });
                        that.togglePagination();
                    } else if (that.options.exportDataType === 'selected') {
                        var data = that.getData(),
                            selectedData = that.getAllSelections();
    
                        // Quick fix #2220
                        if (that.options.sidePagination === 'server') {
                            data = {total: that.options.totalRows};
                            data[that.options.dataField] = that.getData();
    
                            selectedData = {total: that.options.totalRows};
                            selectedData[that.options.dataField] = that.getAllSelections();
                        }
    
                        that.load(selectedData);
                        doExport();
                        that.load(data);
                    } else {
                        doExport();
                    }
                });
                
            }
        }
    };
    })(jQuery);

    相关文章

      网友评论

        本文标题:Bootstrap Table结合tableExport.jqu

        本文链接:https://www.haomeiwen.com/subject/bmqkuxtx.html