Easy Grid 最简单的Javascript 表格控件

      表格是很常用的html控件之一, 为了使用的方便以及美观, Easy就出现了Easy.Grid ,这个表格简单易用,符号Easy的宗旨。

用户只要会html 、Javascript ,看了Easy.Grid 的Demo 就不使用,并且运用自如。演示地址:http://easy.apphb.com/unit/ui/index.htm

都是程序员就不多说了,看源码(一下常用的方法封装在Easy的核心库里):

Easy.data.Store =  function (cfg) {
     var me =  this;
    Easy.apply(me, cfg);
    me.callback =  function () { };
     var pubs = {
        start: 0,
        load:  function (params) {
             var pms = Easy.applyIf(params || {}, me.baseParams);
            me.start = pms.start;
             var mk =  new Easy.UI.Mask({
                message: '正在加载数据...'
            });
            mk.show();
            me.loader = Easy.Ajax.post({
                url: me.url,
                params: pms,
                callback:  function (rsp, cfg) {
                     try {
                         if ( this.status == 200) {
                            me.callback();
                             var json = Easy.decode(rsp);
                             if (json.exception) {
                                alert(json.message);
                                 return  false;
                            }
                            me.processResponse.call(me, rsp);
                        }  else {
                            me.exception.call(me, rsp,  this.statue);
                        }
                    }  catch (e) {
                        mk.close();
                    }  finally {
                        mk.close();
                    }
                }
            });
        },
        on:  function (en, fn, scope) {
             var me =  this;
            (scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
        },
        fireEvent:  function (eventName, scope) {
             return (scope["on" + Easy.String.toPascal(eventName)] || Easy.emptyFn).apply(scope, Easy.slice(arguments, 2));
        },
        processResponse:  function (resText, option) {
             var o = Easy.decode(resText);
             if (o && !o.exception)
                me.drawRow(o);
             else {
                me.exception.call(resText, me.loader.statue);
            }
            me.fireEvent('load', me);
        },
        exception:  function (resT, state) {

            me.fireEvent('exception', me);
        }
    };

    Easy.apply(me, pubs);
     return me;
}

Easy.UI.Grid = Easy.extend(Easy.UI.Base, {
    url: "/base.ashx",
    root: 'Records',
    count: "Count",
    tpl: "",
    noPaging:  false,
    mutilSelect:  false,
    model: 'remote',
    rows: [],
    checkboxs: [],
    headerTDs: [],
    mutilSelectTip: "你选择了多条数据!",
    noSelectTip: "你没有选择要操作的数据!",
    constructor:  function (cfg) {
         var me =  this;
        Easy.apply(me, cfg);
         if (!me.store && me.model === "remote") {
             if (me.url) {
                me.store =  new Easy.data.Store({
                    url: me.url,
                    baseParams: Easy.apply({
                        className: me.className,
                        methodName: me.methodName || "PageData",
                        start: 0, limit: me.limit || 17, sort: '', dir: 'desc'
                    }, me.baseParams)
                });
            }
        }
         if (me.store)
            me.store.drawRow = Easy.delegate(me.drawRow, me);
        Easy.UI.Grid.superclass.constructor.call( this);
    },
    initComponent:  function () {
         var me =  this;
         var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
                    "<tbody>" +
                        (Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
                    "</tbody>" +
                "</table><div class='clear'></div>";
         var wrap = Easy.get(me.renderTo);
        wrap.innerHTML = tpl;
         if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
            me.table = wrap.firstChild;
         if (me.model === 'remote')
            me.store.load();
        me.initGrid =  true;
        me.wrap = wrap;
        me.headerTDs = [];
        me.clearDiv = me.table.nextSibling;
        Easy.each(me.table.firstChild.rows[0].cells,  function (td, i) {
             var w = Easy.DOM.getStyle(td, "width");
             if (Easy.DOM.hasClass(td, "e-row"))
                w = 30;
            w = w || (td.offsetWidth - 10);
            me.headerTDs.push(w);
        })
    },
    drawRow:  function (rows) {
         var me =  this, wrap = Easy.get(me.renderTo);
        me.data = {};
        me.getCount =  function () {
             return rows[me.Count];
        };
        me.tplStr = Easy.isArray(me.tpl) ? me.tpl.join("\n") : me.tpl;
        wrap.innerHTML = "";
        me.rows = [];
        me.checkboxs = [];
         var tpl = "<table class='e-grid' border='0' cellpadding='0' cellspacing='0'>" +
                    "<tbody>" +
                        (Easy.isArray(me.header) ? me.header.join("\n") : me.header) +
                       ( function () {
                            var sb = [], tmp, cutIndex = 0, orow = me.root ? rows[me.root] : rows;
                           Easy.each(orow,  function (it) {
                               me.data[it["FID"]] = it;
                               tmp = me.tplStr;

                                var optn = /\{(\w+)\}[.](\w+)/i, m = optn.exec(tmp);
                                while (m !=  null) {
                                   tmp = tmp.replace(m[0], it[m[1]][m[2]]);
                                   m = optn.exec(tmp);
                               }
                               Easy.each(it,  function (v, k) {
                                   v = v ==  null ? "" : v;
                                    if (Easy.isDate(v)) {
                                       v = Easy.Date.format(v, "yyyy-MM-dd hh:mm");
                                   }
                                   tmp = tmp.replace( new RegExp("{" + k + "}", "g"), v);
                               });
                               cutIndex += 1 + (me.model === 'remote' ? me.store.baseParams.start : 0);
                                if (tmp.indexOf("{fn:") > -1) {
                                    var ptn = /\{fn:(.*)\/fn\}/i, match = ptn.exec(tmp);
                                    while (match !=  null) {
                                        var fn = match[1];
                                        var rel = ( new Function(fn));
                                       tmp = tmp.replace(match[0], rel);

                                       match = ptn.exec(tmp);
                                   }
                               }

                               tmp = tmp.replace("{rowIndex}", cutIndex).replace(/\{\w*\}/ig, " ");
                               sb.push(tmp);
                           });
                            return sb.join("");
                       })() +
                    "</tbody>" +
                "</table><div class='clear'></div>";
        wrap.innerHTML = tpl;
         if (wrap.firstChild && Easy.isElement(wrap.firstChild) && wrap.firstChild.tagName == "TABLE")
            me.table = wrap.firstChild;
        me.initEvent.call(me);
         if (!me.noPaging) {
             var p =  new Easy.UI.Pagingbar(Easy.apply(me.pagingbar || {}, {
                renderTo: wrap,
                data: rows,
                pageSize: me.store.baseParams.limit,
                start: me.store.baseParams.start,
                store: me.store,
                width: wrap.scrollWidth || wrap.offsetWidth || "auto"
            }));
            p.currentPageCtl.value = Math.ceil(me.store.start / me.store.baseParams.limit + 1);
        }
        me.clearDiv = me.table.nextSibling;
        me.wrap = wrap;
        me.fireEvent("render", me);
    },
    on:  function (en, fn, scope) {
         var me =  this;
         if (en == "rowdblclick") {
            Easy.each(me.rows,  function (r, i) {
                Easy.DOM.on(r, "dblclick", Easy.delegate(fn, scope || me, [r, i]));
            })
        }
        (scope || me)["on" + Easy.String.toPascal(en)] = Easy.delegate(fn, scope || me, Easy.slice(arguments, 3));
    },
    onRender:  function () {
         var me =  this, style = {};
         if (me.height) {
            style.height = Math.max(me.height - me.table.offsetHeight - 75, 0);
        }
        Easy.DOM.setStyle(me.clearDiv, style);
    },
    initEvent:  function () {
         var me =  this, tb = me.table.firstChild;
         var ths = tb.rows[0].cells, rows = tb.childNodes;
        me.checkboxs = [];
         for ( var i = 0, len = ths.length; i < len; i++) {
             var cel = ths[i];
             if (cel && cel.sort) {
                Easy.DOM.on(cel, "click", Easy.delegate(me.sort, me, [cel.sort, cel]));
                 if (me.initGrid) {
                     var sortFlag = Easy.DOM.create({
                        tag: "span",
                        cls: 'e-sort-asc'
                    }, cel);
                    Easy.DOM.addClass(cel, "e-cansort");
                }
            }
        }
         var ck = rows[0].getElementsByTagName("input")[0];
         if (ck && ck.type.toLowerCase() === "checkbox") {
             //             me.checkboxs.push(ck);
            Easy.DOM.on(ck, "click", Easy.delegate(me.selectAll, me, [ck]));
        }
         for ( var i = 1, len = rows.length; i < len; i++) {
             var r = rows[i];
            me.rows.push(r);
             var ckb = r.getElementsByTagName("input")[0];
             if (ckb && ckb.type.toLowerCase() === "checkbox") {
                me.checkboxs.push(ckb)
                Easy.DOM.on(ckb, "click", Easy.delegate(me.checkClick, me, [ckb, r]));
            }
            Easy.DOM.on(r, "mouseover", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
            Easy.DOM.on(r, "mouseout", Easy.delegate(me.toogleClass, me, [r, "e-row-over"]));
            Easy.DOM.on(r, "click", Easy.delegate(me.rowClick, me, [r, i]));
            Easy.DOM.on(r, "dblclick", Easy.delegate(me.rowDblClick, me, [r, i]));

            Easy.each(r.cells,  function (c, colIndex) {
                 var sp = c.firstChild;
                 if (sp && sp.tagName.toLowerCase() == "span") {
                    Easy.DOM.setStyle(sp, {
                        width: me.headerTDs[colIndex] || "auto"
                    });
                }
                Easy.DOM.on(c, "click", Easy.delegate(me.cellClick, me, [c, r, colIndex, i]));
                Easy.DOM.on(c, "dblclick", Easy.delegate(me.cellDblClick, me, [c, r, colIndex, i]));
            });
        }
    },
    load:  function (params) {
         this.store.load(params);
    },
    refresh:  function (p) {
         this.store.load(p);
    },
    sort:  function (sort, cel) {
         var me =  this;
        me.initGrid =  false;
        Easy.DOM.toogleClass(cel.lastChild, "e-sort-desc");
         var params = { sort: sort, dir: "desc" };
         if (Easy.DOM.hasClass(cel.lastChild, "e-sort-desc")) {
            params["dir"] = "desc";
        }  else {
            params["dir"] = "asc";
        }
        me.header = me.table.firstChild.firstChild.outerHTML;
        me.load(params);
    },
    selectAll:  function (ck) {
         var me =  this;
        Easy.each(me.checkboxs,  function (c, i) {
            c.checked = ck.checked;
            Easy.DOM[ck.checked ? "addClass" : "removeClass"](me.rows[i], "e-row-select");
        });
    },
    checkClick:  function (c, r) {
        Easy.DOM.toogleClass(r, "e-row-select");
        Easy.Event.stopPropagation(window.event);
         this.fireEvent('check',  this, r, c);
    },
    rowClick:  function (r, i, cked) {
         if (!window.event.ctrlKey && ! this.mutilSelect)
            Easy.each( this.rows,  function (r) {
                Easy.DOM.removeClass(r, "e-row-select");
                r.cells(0).firstChild.checked =  false;
            });
        Easy.DOM.addClass(r, "e-row-select");
         this.rows[i - 1].cells(0).firstChild.checked = cked !==  false ?  true : cked;
         this.fireEvent('click',  this, r, i, cked);
    },
    rowDblClick:  function (row, idex) {
         this.fireEvent('rowdblclick',  this, row, idex);
    },
    cellClick:  function (cell, row, colIndex, rowIndex) {
         this.fireEvent('cellclick',  this, cell, row, colIndex, rowIndex);
    },
    cellDblClick:  function (cell, row, colIndex, rowIndex) {
         this.fireEvent('celldblclick',  this, cell, row, colIndex, rowIndex);
    },
    toogleClass:  function (r, cls) {
        Easy.DOM.toogleClass(r, cls);
    },
    getSelection:  function () {
         var me =  this, sel = [];
        Easy.each(me.rows,  function (r) {
             var ck = r.cells(0).firstChild;
             if (ck.checked ===  true) {
                sel.push(me.data[ck.value]);
            }
        });
         return sel;
    },
    getValues:  function (key, canempty) {
         var me =  this, v = [];
         var sls = me.getSelection.call(me);
        Easy.each(sls,  function (s) {
            v.push(s[key]);
        });
         if (v.length == 0 && !canempty) {
            alert(me.noSelectTip);
            v =  false;
        }
         return v;
    },
    getValue:  function (key, canempty) {
         var me =  this, v = [];
         var sls = me.getSelection.call(me);
         if (sls.length == 1) {
             return sls[0][key];
        }  else  if (!canempty) {
            alert(me[sls.length == 0 ? "noSelectTip" : "mutilSelectTip"]);
             return  false;
        }
    }
});

看了这么长的源码后, 看看这个grid的到底能出现什么效果呢, 现在看看效果,

效果图如下:

 

看到效果后我们看看穿件这个grid的代码:

 

var grid =  new Easy.UI.Grid({
       id: "roleGrid",
       renderTo: 'grid',
       baseParams: {
           className: "RoleServer",
           methodName: "PageData"
       },
       header: ["<tr class='e-header'>",
                            "<td class='e-checkbox'><input type='checkbox' /></td>",
                            "<td style='width:150px;' sort='FName'><span>名 称</span></td>",
                            "<td style='width:200px;' sort='FOrgID'><span>所属组织</span></td>",
                            "<td style='width:150px;' sort='FSort'><span>排 序</span></td>",
                            "<td><span>说明</span></td>",
                        "</tr>"],
       tpl: ["<tr>",
                            "<td><input type='checkbox' value='{FID}' /></td>",
                            "<td><span>{FName}</span></td>",
                            "<td><span>{OrgName}</span></td>",
                            "<td><span style='width:100px;'>{FSort}</span></td>",
                            "<td><span>{FRemark}</span></td>",
                        "</tr>"]
});

 穿件这个grid的代码仅此而已,  效果还可以的吧 !

转载于:https://www.cnblogs.com/Easyjs/archive/2011/10/27/grid.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 以前很想做关于自定义界面的东东,但是一直都在用PB的公司上班(目前都是), 时间又紧就一直没有做了,前段时间在做一个系统时,觉得有必要采用灵活多 变的自定义界面方式来实现(觉得还是delphi这些方面强,pb可能不好实现), 从技术上来说采用控件在窗口上拖拉来实现也不 会太难。由于我接触的财务比较多,觉得还是用表格来实现好些。中国财务的 填写多是表格!我也看到网上也有用 XLGrid 做成功的,好象这个东东不能在单 元格中嵌入表格,列表框之类的,不能实现主从表录入(好象是啊)。2) 如果自己来做表格控件,工作量较大。我以前用过王寒松的表格,觉得还是可以, 但是觉得不能象Excel而是类似于Word的表格,这是本身设计思想的结果,最后还 是选用了EasyGrid。 该控件是由Delphi中Grids的修改过来的。而且也改的很好。3) 由于时间紧,而且现在手中有项目要做(都拖了快一周了),因此作的很简单。 好多东西都没有作好,还有很多要完善,目前只是简单的实现了单元格连接了字段 和字段标签以及在单元格中嵌入表格,目的实现主从录入。嵌入的表格在IDE 环境中可以保存,但是在运行时期表格的保存还没有做,而且需要做一个在运行时期。 的编辑器,可以在运行时期对表格编辑。同样单元格还可以嵌入图片和ListBox,TreeView。 但是现在确实不能再写了,公司的事还是要作的,否者饭碗丢了,就掺了。我算了一下 要作的基本差不多,还要三周时间,有时间的话我一定会写完的。我个人分析一下: 用这个东东再结合语法解析器,来实现开发平台可性行是很高的。4) 经常看到在网上有人要计算表达式,顺便把我以前写的表达式解析器也送上来。 可以计算字段和数值的混合运算,支持If。最多支持两个数据集的字段运算。 改写人 : liuzhigang 地址 : 四川.成都 (德阳) Email : [email protected]
安装时请按照以下序列: Component->Install Packges-> <Add> 选择Discovery.bpl Options->Library->Search Path 中加入搜索路径。 EasyGrid 使用说明: 一、单元格属性; // ************************************************** // EasyGrid 的 Cells[i,j] 属性不同于 StringGrid。 // StringGrid 的 Cells 仅仅是一个字符串,而 EasyGrid // 的 Cells 可以存储丰富的数据类型。 // // 使用范例: // EasyGrid1.Cells[1,2].Color := clRed; // 将第一列第二行的一个单元格背景置为红色。 // // !!! 需要注意的是: // 上述语法不会导致网格自动刷新(即结果不会马上反映),因为上述语法 // 实际上是对内存地址直接写入,这样做的好处在于,如果大批量写入数据,这 // 是最快的方法,不会出现慢镜头式的现象。 // 用 EasyGrid1.Colors[1,2] := clRed; 可以实现同样效果并实时刷新, // 但大批量写入数据时速度较慢。 // 对大批量写入数据的处理一般需要使用 AutoUpdate 属性: // EasyGrid1.AutoUpdate := False; // ... 大批量写入数据 // EasyGrid1.AutoUpdate := True; // AutoUpdate 属性的使用类似于一个与 DbGrid 关联的 DataSource 控件, // 当 DataSource 内容改变时,需要把 DataSource 的 Enabled 属性置为 False。 // 以防止 DbGrid 出现慢镜头式的现象。 // ************************************************** // ************************************************** // 单元格属性说明如下: TCellInfo = record DataStyle : TDataStyle; // 数据格式 // 可用数据格式为: // TDataStyle = (dsText,dsNumber,dsDate,dsTime,dsFormula); AlignMode : TAlignMode; // 对齐方式 // 可用对齐方式为: // TAlignMode = (taTopLeft, taTop, taTopRight, // taLeft, taCenter, taRight, // taBottomLeft, taBottom, taBottomRight); ReadOnly : Boolean; // 单元格是否可编辑 AutoWordBreak : Boolean; // 文字自动折行 ShowForeText : Boolean; // 显示控制(Default True) // 说明:每个单元格允许存放两个字符串: // ForeText 与 BackText // ShowForeText 属性用于指定该网格显示哪一个字符串 DrawTop : Boolean; // 画顶线 DrawLeft : Boolean; // 画左线 DrawBottom : Boolean; // 画底线 DrawRight : Boolean; // 画右线 // 下面七个属性对于 DataStyle 为 dsNumber (数值型)的网格有效 AllowNegative : Boolean; // 是否允许输入负数 TrailingZero : Boolean; // 是否在小数后面补 0 ZeroNull : Boolean; // 输入数值 0 时是否当作空串处理 ThousandSep : Boolean; // 是否有千分号 MaxLength : Integer; // 最大编辑长度 IntLength : Integer; // 整数部分最大长度 DecLength : Integer; // 小数部分最大长度 LineWidth : Integer; // 边框线宽 PenStyle : TPenStyle; // 线形(TPenStyle 为Delphi定义类型) // Number 用于存储额外的数据,甚至可以用 Pointer() // 强制成32位结构指针,使得网格理论上可以挂接任意类型的数据 Number : Integer; // 存储数值 Color : TColor; // 网格背景颜色
使用 Alibaba Easy Excel 可以简单地设置 Excel 表格大小,下面是示例代码: ```java import com.alibaba.excel.EasyExcelFactory; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.TableStyle; import com.alibaba.excel.write.ExcelBuilder; import com.alibaba.excel.write.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class ExcelDemo { public static void main(String[] args) throws IOException { // 准备测试数据 List<List<Object>> data = new ArrayList<>(); for (int i = 0; i < 5; i++) { List<Object> rowData = new ArrayList<>(); for (int j = 0; j < 10; j++) { rowData.add("Data " + i + "-" + j); } data.add(rowData); } // 创建一个新的工作簿 ExcelWriter excelWriter = EasyExcelFactory.getWriter(new FileOutputStream("example.xlsx")); // 设置表格样式 TableStyle tableStyle = new TableStyle(); tableStyle.setTableContentBackGroundColor(IndexedColors.WHITE); tableStyle.setTableContentFont(FontData.createDefaultFont("宋体", 12)); tableStyle.setTableHeaderBackGroundColor(IndexedColors.GREY_25_PERCENT); tableStyle.setTableHeaderTextFont(FontData.createDefaultFont("宋体", 12, true)); // 创建一个新的工作表 WriteSheet writeSheet = EasyExcelFactory.writerSheet("Sheet1").build(); // 设置行高和列宽 writeSheet.setColumnWidth(0, 20); // 第一列的宽度为20个字符宽度 writeSheet.setHead(createHead()); // 设置表头 writeSheet.setTableStyle(tableStyle); // 设置表格样式 // 设置数据 WriteTable writeTable = EasyExcelFactory.writerTable(0).build(); writeTable.setHead(createHead()); // 设置表头 writeTable.setTableStyle(tableStyle); // 设置表格样式 writeTable.setClazz(String.class); // 设置数据类型 excelWriter.write1(data, writeSheet, writeTable); // 关闭工作簿 excelWriter.finish(); } // 创建表头 private static List<List<String>> createHead() { List<List<String>> head = new ArrayList<>(); for (int i = 0; i < 10; i++) { List<String> header = new ArrayList<>(); header.add("Header " + i); head.add(header); } return head; } } ``` 在这个示例中,我们使用`writeSheet.setColumnWidth()`方法设置第一列的宽度为20个字符宽度。你可以根据你的需求修改这个值。最后,使用`excelWriter.write1()`方法将数据写入工作簿中,然后关闭工作簿。 需要注意的是,Easy Excel 写入数据时会自动根据数据的长度调整列宽,如果你想强制使用固定的列宽,可以使用`LongestMatchColumnWidthStyleStrategy`类,如下所示: ```java // 设置固定的列宽 HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy( new LongestMatchColumnWidthStyleStrategy(), new TableStyle(), new TableStyle() ); writeSheet.setHead(createHead()); // 设置表头 writeSheet.setTableStyle(tableStyle); // 设置表格样式 writeSheet.setHorizontalCellStyleStrategy(horizontalCellStyleStrategy); // 设置列宽策略 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值