• 原生javaScript手写简单的table.js


    JS

    ! function(global, factory) {
        typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
            typeof define === 'function' && define.amd ? define(factory) :
            (global.Table = factory());
    }(this, function() {
        return function(e) {
            //首先传递的参数必须是对象   否则报错
            function isObject(obj) {
                return typeof obj === 'object' && obj != null;
            }
    
            function isArray(arr) {
                return arr.constructor === 'Array';
            }
    
            function create(ele) {
                return _doc.createElement(ele);
            }
            var _doc = document;
            if(!isObject(e) || isArray(e)) {
                throw new Error("数据类型错误");
            }
            
            var _pros ={
                            el : e.el,
                            url : e.url || '',
                            data : e.data || [],
                            sort : typeof e.sort === 'boolean' && e.sort || false,
                            columns : e.columns || [],
                            queryParams : {},
                            rowNumber:typeof e.rowNumber === 'boolean' && e.rowNumber || false,
                            firstCheckBox:typeof e.firstCheckBox === 'boolean' && e.firstCheckBox || false,
                            slectRow:e.slectRow,
                            getSelects:e.getSelects ||''
                        }
            ///ajax(_pros.url, _pros.queryParams, init());
            var table,tableParentNode,thead,tbody,tfoot,rows;
            ~function init() {
                //获取表格的父级元素
                tableParentNode = _doc.querySelector(_pros.el);
                table = create("table");
                table.className = "Table";
                table.id = 'table' + _pros.el;
                tableParentNode.appendChild(table);
                thead = create("thead");
                table.appendChild(thead);
                tbody = create("tbody");
                table.appendChild(tbody);
                tfoot = create("tfoot");    
                table.appendChild(tfoot);
                //添加表头
                var str = "";
                if(_pros.rowNumber) str += "<th style='display:block;30px;color:#ccc0;background-color: #cccccc29;'></th>";
                if(_pros.firstCheckBox)str +="<th style='30px;color:#ccc0;background-color: #cccccc29;130px;'></th>";
                _pros.columns.forEach(function(content) {
                    str += "<th>" + content.field + "</th>";
                });
                thead.innerHTML = str;
                innsertTbody();
                innsertTfoot();
            }();
    
            function innsertTbody() {
                //添加表体
                rows = [];
                _pros.data.forEach(function(content,i) {
                    var tr = create("tr");
                    var str = "";
                    if(_pros.rowNumber)str += "<td style='background-color:rgba(81, 238, 62, 0.64);color:#FFF;display: block;30px'>" +(i+1)+ "</td>";
                    if(_pros.firstCheckBox) str += "<td style='background-color:rgba(167, 143, 30, 0.21);color:#FFF;100px;'><input type='checkbox' style='16px;'></input></td>";
                    _pros.columns.forEach(function(e) {
                        if(content[e.data]){
                            str += "<td>" + content[e.data] + "</td>";
                        }
                    });
                    rows.push(content);
                    tr.onclick =_callFn;
                    tr.innerHTML = str;
                    tbody.appendChild(tr);
                })
            }
            
            
            function _callFn(){
                //console.log(this);
                var input = this.querySelector('input');
                if(input)input.checked =!input.checked;
                _pros.slectRow.call(this,rows,this.rowIndex-1);
            }
            
            function _callGetSelects(){
                var inputs = _doc.querySelector('input');
                inputs.forEach(function(){
                    if(input.checked){
                        
                    }
                })
                _pros.getSelects.call(this,rows,this.rowIndex-1);
            }
            
            function innsertTfoot() {
                //添加表尾
                var tr = create("tr");
                var footstr = "<td style='100%'><div>尾页</div><div>1</div> <div>首页</div><button id='exportExcle'>导出EXCLE</button> </td>";
                tr.innerHTML = footstr;
                tfoot.appendChild(tr);
            }
    
            _doc.querySelector('#exportExcle').onclick = exportExcle;
            //导出EXCLE
            function exportExcle() {
                if(getExplorer() == 'ie') {
                    var curTbl = _doc.getElementById("table");
                    var oXL = new ActiveXObject("Excel.Application");
    
                    //创建AX对象excel
                    var oWB = oXL.Workbooks.Add();
                    //获取workbook对象
                    var xlsheet = oWB.Worksheets(1);
                    //激活当前sheet
                    var sel = _doc.body.createTextRange();
                    sel.moveToElementText(curTbl);
                    //把表格中的内容移到TextRange中
                    sel.select;
                    //全选TextRange中内容
                    sel.execCommand("Copy");
                    //复制TextRange中内容
                    xlsheet.Paste();
                    //粘贴到活动的EXCEL中
                    oXL.Visible = true;
                    //设置excel可见属性
    
                    try {
                        var fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls");
                    } catch(e) {
                        print("Nested catch caught " + e);
                    } finally {
                        oWB.SaveAs(fname);
    
                        oWB.Close(savechanges = false);
                        //xls.visible = false;
                        oXL.Quit();
                        oXL = null;
                        //结束excel进程,退出完成
                        //window.setInterval("Cleanup();",1);
                        idTmr = window.setInterval("Cleanup();", 1);
                    }
                } else {
                    tableToExcel(table, "报表管理信息")
                }
            }
    
            var idTmr;
    
            function getExplorer() {
                var explorer = window.navigator.userAgent;
                //ie
                if(explorer.indexOf("MSIE") >= 0) {
                    return 'ie';
                }
                //firefox
                else if(explorer.indexOf("Firefox") >= 0) {
                    return 'Firefox';
                }
                //Chrome
                else if(explorer.indexOf("Chrome") >= 0) {
                    return 'Chrome';
                }
                //Opera
                else if(explorer.indexOf("Opera") >= 0) {
                    return 'Opera';
                }
                //Safari
                else if(explorer.indexOf("Safari") >= 0) {
                    return 'Safari';
                }
            }
    
            function Cleanup() {
                window.clearInterval(idTmr);
                CollectGarbage(table);
            }
    
            /*
                template : 定义文档的类型,相当于html页面中顶部的<!DOCTYPE> 声明。(个人理解,不确定)
                encodeURIComponent:解码
                unescape() 函数:对通过 escape() 编码的字符串进行解码。
                window.btoa(window.encodeURIComponent(str)):支持汉字进行解码。
                w :匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’
                replace()方法:用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
                {(w+)}:匹配所有 {1个或更多字符} 形式的字符串;此处匹配输出内容是 “worksheet”
                        正则中的() :是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。
                        讲解(/{(w+)}/g, function(m, p) { return c[p]; } :
                    /{(w+)}/g 匹配出所有形式为“{worksheet}”的字符串;
                    function参数:  m  正则所匹配到的内容,即“worksheet”;
                                    p  正则表达式中分组的内容,即“(w+)”分组中匹配到的内容,为“worksheet”;
                    c :为object,见下图3
                    c[p] : 为“worksheet”
    
            */
            var tableToExcel = (function() {
                var uri = 'data:application/vnd.ms-excel;base64,',
                    template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
                    base64 = function(s) {
                        return window.btoa(unescape(encodeURIComponent(s)))
                    },
                    // 下面这段函数作用是:将template中的变量替换为页面内容ctx获取到的值
                    format = function(s, c) {
                        return s.replace(/{(w+)}/g,
                            function(m, p) {
                                return c[p];
                            }
                        )
                    };
                return function(table, name, filename) {
                    if(!table.nodeType) table = _doc.getElementById(table.id)
                    // 获取表单的名字和表单查询的内容
                    var ctx = {
                        worksheet: name || 'Worksheet',
                        table: table.innerHTML
                    };
                    // format()函数:通过格式操作使任意类型的数据转换成一个字符串
                    // base64():进行编码
                    window.location.href = uri + base64(format(template, ctx))
                }
            })()
    
            //获取《style》标签样式
            function getStyle(obj, attr) {
                return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
            }
    
            //添加样式
            !function addStyle() {
                var styleNode = create("style");
                var tableMargin = parseFloat(getStyle(table, "margin-right"));
                var width = table.offsetWidth - tableMargin * 2;
                styleNode.innerHTML = "table tr,th,td{" + width + "px}";
                var no_height_style="thead{padding-right: 0em;}thead tr:first-child,th{box-shadow: -1px -1.1px #CCC, 1.2px -1px #CCC;border:1px solid #ccc}";
                //自定义高度
                if(e.height) {
                    //指定了高度
                    var o = tableParentNode.offsetHeight = e.height;
                    var _height = e.height + thead.offsetHeight;
                    if(_height >= o){
                        tbody.style.height = (o - thead.offsetHeight) + "px";
                        styleNode.innerHTML += no_height_style;
                        //内容高度可以完全展示时
                        if(tbody.scrollHeight == tbody.clientHeight || tbody.scrollHeight < tbody.clientHeight) {
                            //alert();
                            styleNode.innerHTML +="tbody tr:last-child,tbody tr:last-child td{border:1px solid #ccc;border-bottom:2px solid #ccc}";
                            //styleNode.innerHTML += no_height_style;
                        }
                    } 
                } else {
                    //如果没有指定tbody高度
                    styleNode.innerHTML += no_height_style;
                }
                _doc.head.appendChild(styleNode);
            }()
    
            _pros.sort && makeSorttable(table);
            //排序
            var flag = true;
            //选择tr的第几个<td>的指进行排序
            function sortRows(table, n) {
                //var tbody = table.getElementsByTagName("tbody")[0];
                var tbody = table.tBodies[0];
                var rows = tbody.getElementsByTagName('tr');
                rows = Array.prototype.slice.call(rows, 0);
                rows.sort(function(row1, row2) {
                    var cell1 = row1.getElementsByTagName("td")[n];
                    var cell2 = row2.getElementsByTagName("td")[n];
                    if(cell1 && cell2) {
                        var val1 = cell1.textContent || cell1.innerText;
                        var val2 = cell2.textContent || cell2.innerText;
                        if(val1 > val2) return flag ? 1 : -1;
                        else if(val1 < val2) return flag ? -1 : 1;
                        else return 0;
                    }
                })
                for(var i = 0, len = rows.length; i < len; i++) {
                    tbody.appendChild(rows[i]);
                }
            };
            //选择表格th进行排序
            function makeSorttable(table) {
                var headers = table.getElementsByTagName("th");
                /*for (var i=0,len = headers.length;i<len;i++) {
                    (function(n){//使用闭包
                        headers[i].onclick=function(){
                            sortRows(table,n);
                            flag = !flag;
                        }
                    })(i)
                }*/
                //改进 
                for(let i = 0, len = headers.length; i < len; i++) {
                    headers[i].onclick = function() {
                        sortRows(table, i);
                        flag = !flag;
                    }
                }
            }
    
            // ajax封装
            function ajax(url, data, callback, cache, async, type, dataType, traditional, error) {
                // layer.load();
                var type = type || 'post'; //请求类型
                var dataType = dataType || 'json'; //接收数据类型
                var async = async || false; //异步请求
                // var alone = alone || false;//独立提交(一次有效的提交)
                var cache = cache || false; //浏览器历史缓存
                var traditional = traditional || false; //如果你想要用传统的方式来序列化数据,那么就设置为true
                var success = function(data) {
                    //  console.log(data);
                    //layer.closeAll();
                    if(data.error == 0) { //服务器处理成功
                        if(callback != null) {
                            callback(data.data);
                        }
                    } else { //服务器处理失败
                        toastr.error(data.info);
                    }
                };
                var error = error || function(data) {
                    console.log(data);
                    layer.closeAll();
                    if(data.status == 404) {
                        toastr.error('请求失败,请求未找到');
                    } else if(data.status == 503) {
                        toastr.error('请求失败,服务器内部错误');
                    } else {
                        toastr.error(data.responseText);
                    }
                };
                $.ajax({
                    'url': url,
                    'data': data,
                    'type': type,
                    'dataType': dataType,
                    'async': async,
                    'success': success,
                    'cache': cache,
                    'error': error,
                    'traditional': traditional,
                    'jsonpCallback': 'jsonp' + (new Date()).valueOf().toString().substr(-4),
                });
            }
    
            // submitAjax(post方式提交)同步
            function submitAjax(form, success, cache) {
                cache = cache || true;
                var url = form.attr('action');
                var data = form.serialize();
                ajax(url, data, success, cache, false, 'post', 'json');
            }
    
            // ajax提交(post方式提交)traditional 值为true 用传统的方式来序列化数据,同步
            function post(url, data, success, cache) {
                ajax(url, data, success, cache, false, 'post', 'json', true);
            }
        }
    })
    View Code

    CSS

    *{margin:0;padding:0}
    html,body{height: 100%;width: 100%;}
    table,tr,th,td{border-collapse:collapse ;}
    tr,th,td{
        padding: 0;
        margin: 0;
        border: 1px solid #ccc;
        border-bottom: 0;
    }
    tr:not(:first-child),td:not(:last-child),tr:not(:last-child){
        box-shadow: -1px -1.1px #CCC, 1.2px -1px #CCC;
    }
    tr:first-child,th:last-child,tr:last-child{
        border-right:0;
    }
    table,thead,tbody{display:block;}
    table{
        width: 80%;
        text-align: center;
        margin: 0 auto;
        table-layout: fixed;
        position: relative;
        word-wrap: break-word;
        word-break: break-all;
    }
    thead{
        padding-right: 0.8em;
        border: 1px solid #ccc;
    }
    
    tbody{
        
        overflow:auto;
        border: 1px solid #ccc;
    }
    
    tr:hover:not(:last-child){
        background-color:#F0AD4E;
    }
    tfoot tr, tfoot tr td{
        border: 0;
        display: block;
    }
    tfoot td div{
        color: #2a6496;
        width: 40px;
        float: right;
        margin-left: 2px;
        margin-top: 2px;
    }
        
    tfoot td div:first-child,tfoot td div:last-child{
        color: #FFF;
        border:0;
        background-color: #337ab7;
    }
    ::-webkit-scrollbar 
    { 
        width: 6px; 
        height: 16px; 
        background-color: #F5F5F5; 
    } 
       
    /*定义滚动条轨道 内阴影+圆角*/ 
    ::-webkit-scrollbar-track 
    { 
        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 
        border-radius: 10px; 
        background-color: #b6d0c5; 
    } 
       
    /*定义滑块 内阴影+圆角*/ 
    ::-webkit-scrollbar-thumb 
    { 
        border-radius: 10px; 
        -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); 
        background-color: #b9c355; 
    }
    View Code

    DEMO

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <script type="text/javascript" src="js/table.js" ></script>
            <link rel="stylesheet" href="css/table.css" />
        </head>
        <body>
            <div id="tb"></div>
        </body>
        <script>
            var t = new Table({
                el:'#tb',
                columns:[
                    {data:'sex',field:'性别'},
                    {data:'name',field:'姓名'},
                    {data:'address',field:'地址'},
                    {data:'age',field:'年龄'},
                ],
                rowNumber:true,
                height:400,
                //firstCheckBox:true,
                data:[
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'},
                    {name:'王五',age:'11',sex:'',address:'三国'},
                    {name:'赵六',age:'51',sex:'',address:'水浒'},
                    {name:'孙倩',age:'51',sex:'',address:'虹口'},
                    {name:'张三',age:'28',sex:'',address:'廊坊大城'},
                    {name:'李四',age:'41',sex:'',address:'西游'}
                ],
                sort:true,
                slectRow:function(e,i){
                    console.log("下表 ======== "+i);
                    console.log(e[i].name+"-----"+e[i].address);
                }
            });
        </script>
    </html>
    View Code
  • 相关阅读:
    Notebook ++ 设置护眼背景
    python 设置 excel 单元格颜色填充和字体效果
    python 设置 Excel 单元格边框线的各种风格
    python 对 excel sheet 的插入、复制、删除、重命名、设置标签颜色操作
    python 利用插入空行的方式制作工资条表格
    python 更新 openpyxl 到 3.0
    python 模拟 excel 宏、VBA 制作工资条表格
    Windows 系统
    python-pptx 实践 6.2:气泡图
    python-pptx 实践 6.1:添加五种基本图形(柱形图、折线图、饼图、条形图、散点图)
  • 原文地址:https://www.cnblogs.com/wang-yi/p/9867131.html
Copyright © 2020-2023  润新知