ExtJS 4.2 Grid组件的单元格合并

ExtJS 4.2 Grid组件本身并没有提供单元格合并功能,需要自己实现这个功能。

目录

1. 原理

2. 多列合并

3. 代码与在线演示

1. 原理

1.1 HTML代码分析

首先创建一个Grid组件,然后查看下的HTML源码。

1.1.1 Grid组件

1.1.2 HTML代码

从这些代码中可以看出,Grid组件可分为grid-header和grid-body 两块区域(若含有工具栏和分页栏,它们都会含有各自的独立区域)。

其中grid-body包含了许多tr元素,每一个tr都是代表Grid组件中的一行数据;每个tr内部都包含了许多td,每个td表示一个单元格。

1.1.3 结构图

1.2 原理

1.2.1 步骤说明

具体的操作是针对tr元素,步骤如下:

1) 比较第行tr与第行tr的某个td的值,若两行的值相等:设置第行tr的td的rowspan属性的值+1;设置第行tr的td隐藏。

2) 比较第行tr与第行tr的某个td的值,若两行的值相等:设置第行tr的td的rowspan属性的值+1;设置第行tr的td隐藏。

3) 重复上面的步骤,若两行的值不相等,就跳过本次比较,进行下一次比较:当前行与下一行进行比较。

1.2.2 示例

1) tr1与tr2比较,两者值相等:设置tr1的rowspan属性的值+1;设置第tr2的td隐藏。

2) tr1与tr3比较,两者值相等:设置tr1的rowspan属性的值+1;设置第tr3的td隐藏。

3) tr1与tr4比较,两者的td不相等。跳过本次比较,进行下一次比较:tr4与tr5比较(当前行与下一行进行比较)。

2. 多列合并

Gird的合并可分为单列合并和多列合并,其中多列合并可分为两种:

第一种:逐个列合并。

第二种:相同列合并。

2.1 逐个列合并

说明:每个列在前面列合并的前提下可分别合并。

示例

2.2 全部列合并

说明:只有相邻tr所指定的td都相同才会进行合并。

示例

3. 代码与在线演示

3.1 代码

/**
* 合并Grid的数据列
* @param grid {Ext.Grid.Panel} 需要合并的Grid
* @param colIndexArray {Array} 需要合并列的Index(序号)数组;从0开始计数,序号也包含。
* @param isAllSome {Boolean} 是否2个tr的colIndexArray必须完成一样才能进行合并。true:完成一样;false:不完全一样
*/
function mergeGrid(grid, colIndexArray, isAllSome) {
    isAllSome = isAllSome == undefined ? true : isAllSome; // 默认为true

    // 1.是否含有数据
    var gridView = document.getElementById(grid.getView().getId() + ‘-body‘);
    if (gridView == null) {
        return;
    }

    // 2.获取Grid的所有tr
    var trArray = [];
    if (grid.layout.type == ‘table‘) { // 若是table部署方式,获取的tr方式如下
        trArray = gridView.childNodes;
    } else {
        trArray = gridView.getElementsByTagName(‘tr‘);
    }

    // 3.进行合并操作
    if (isAllSome) { // 3.1 全部列合并:只有相邻tr所指定的td都相同才会进行合并
        var lastTr = trArray[0]; // 指向第一行
        // 1)遍历grid的tr,从第二个数据行开始
        for (var i = 1, trLength = trArray.length; i < trLength; i++) {
            var thisTr = trArray[i];
            var isPass = true; // 是否验证通过
            // 2)遍历需要合并的列
            for (var j = 0, colArrayLength = colIndexArray.length; j < colArrayLength; j++) {
                var colIndex = colIndexArray[j];
                // 3)比较2个td的列是否匹配,若不匹配,就把last指向当前列
                if (lastTr.childNodes[colIndex].innerText != thisTr.childNodes[colIndex].innerText) {
                    lastTr = thisTr;
                    isPass = false;
                    break;
                }
            }

            // 4)若colIndexArray验证通过,就把当前行合并到‘合并行‘
            if (isPass) {
                for (var j = 0, colArrayLength = colIndexArray.length; j < colArrayLength; j++) {
                    var colIndex = colIndexArray[j];
                    // 5)设置合并行的td rowspan属性
                    if (lastTr.childNodes[colIndex].hasAttribute(‘rowspan‘)) {
                        var rowspan = lastTr.childNodes[colIndex].getAttribute(‘rowspan‘) - 0;
                        rowspan++;
                        lastTr.childNodes[colIndex].setAttribute(‘rowspan‘, rowspan);
                    } else {
                        lastTr.childNodes[colIndex].setAttribute(‘rowspan‘, ‘2‘);
                    }
                    // lastTr.childNodes[colIndex].style[‘text-align‘] = ‘center‘;; // 水平居中
                    lastTr.childNodes[colIndex].style[‘vertical-align‘] = ‘middle‘;; // 纵向居中
                    thisTr.childNodes[colIndex].style.display = ‘none‘;
                }
            }
        }
    } else { // 3.2 逐个列合并:每个列在前面列合并的前提下可分别合并
        // 1)遍历列的序号数组
        for (var i = 0, colArrayLength = colIndexArray.length; i < colArrayLength; i++) {
            var colIndex = colIndexArray[i];
            var lastTr = trArray[0]; // 合并tr,默认为第一行数据
            // 2)遍历grid的tr,从第二个数据行开始
            for (var j = 1, trLength = trArray.length; j < trLength; j++) {
                var thisTr = trArray[j];
                // 3)2个tr的td内容一样
                if (lastTr.childNodes[colIndex].innerText == thisTr.childNodes[colIndex].innerText) {
                    // 4)若前面的td未合并,后面的td都不进行合并操作
                    if (i > 0 && thisTr.childNodes[colIndexArray[i - 1]].style.display != ‘none‘) {
                        lastTr = thisTr;
                        continue;
                    } else {
                        // 5)符合条件合并td
                        if (lastTr.childNodes[colIndex].hasAttribute(‘rowspan‘)) {
                            var rowspan = lastTr.childNodes[colIndex].getAttribute(‘rowspan‘) - 0;
                            rowspan++;
                            lastTr.childNodes[colIndex].setAttribute(‘rowspan‘, rowspan);
                        } else {
                            lastTr.childNodes[colIndex].setAttribute(‘rowspan‘, ‘2‘);
                        }
                       // lastTr.childNodes[colIndex].style[‘text-align‘] = ‘center‘;; // 水平居中
                        lastTr.childNodes[colIndex].style[‘vertical-align‘] = ‘middle‘;; // 纵向居中
                        thisTr.childNodes[colIndex].style.display = ‘none‘; // 当前行隐藏
                    }
                } else {
                    // 5)2个tr的td内容不一样
                    lastTr = thisTr;
                }
            }
        }
    }
}

  

3.2 在线演示

在线演示http://www.akmsg.com/ExtJS/index.html#App.Demo.MergeGridTab

==================================系列文章==========================================

本篇文章:7.8  ExtJS 4.2 Grid组件的单元格合并

Web开发之路系列文章

时间: 2024-10-17 17:36:00

ExtJS 4.2 Grid组件的单元格合并的相关文章

SNF快速开发平台MVC-表格单元格合并组件

1.   表格单元格合并组件 1.1.      效果展示 1.1.1.    页面展现表格合并单元格 图 4.1 1.1.2.    导出excel合并单元格 图 4.2 1.2.      调用说明 1.2.1.    表格合并单元格调用说明 首先,要有一个在viewModel中绑定的表格,例如,我们有一个绑定对象为this.grid的表格 我们要在表格的onLoadSuccess事件中添加一个方法 snf.mergeCellsByParentField ("grid", &quo

JTable 单元格合并 【转】

单元格合并 一.单元格合并.(1)我们可以使用Jtable的三个方法:getCellRect(),columnAtPoint(),and rowAtPoint().第一个方法返回一个单元格的边界(Rectangle类),第二.三个方法分别返回屏幕指定位置的列和行.为了实现单元格合并,我们需要重载(overwrite)这三个方法. (2)另外我们需要找出渲染Jtable的ComponentUI对象,并且修改它以达到我们的目的. (3)创建新的类记录单元格合并情况的数据模型,它要包涵一个方法来取得单

修改TreeList单元格格式(实现类似单元格合并效果)

关键点:(1)TreeList中显示的单元格默认不显示上.下.左.右边框,显示的是TreeList自身的行横边框.列纵边框,具体对应TreeList属性中OptionView项下的ShowVertLines.ShowHorzLines两项,将其对应默认值由默认False改为True即可去除行横边框.列纵边框,然后设置怎样的单元格格式显示什么样的单元格格式: (2)在*_CustomDrawNodeCell中修改函数,而不是*_NodeCellStyle中修改,另外需要注意,前者在后者前运行,因此

Qt实现表格控件-支持多级列表头、多级行表头、单元格合并、字体设置等

目录 一.概述 二.效果展示 三.定制表头 1.重写数据源 2.重写QHeaderView 四.设置属性 五.相关文章 原文链接:Qt实现表格控件-支持多级列表头.多级行表头.单元格合并.字体设置等 一.概述 最近在研究QTableView支持多级表头的事情,百度了下网上资料还是挺多的.实现的方式总的来说有2种,效果都还不错,最主要是搞懂其中的原理,做到以不变应万变. 实现多级表头的方式有以下两种方案 行表头和列表头都是用一个表格去模拟 重写QHeadView 以上两种方式都可以实现多级表头,各

DataGridView单元格合并

本文章转载:http://www.cnblogs.com/xiaofengfeng/p/3382094.html 图: 代码就是如此简单 文件下载:DataGridView单元格合并源码

devexpress实现单元格合并以及依据条件合并单元格

1.devexpress实现单元格合并非常的简单,只要设置属性[AllowCellMerge=True]就可以了,实现效果如下图: 2.但是在具体要求中并非需要所有的相同单元格都合并,可能需要其他的条件来控制合并.这个时候我们就需要在事件gridView1_CellMerge中来控制了.下图为根据最后一列判断是否合并单元格的效果图(其中第四列设置为不合并<非必需>,这里只是为了达到一个比较效果.). 3.重要代码: int row1 = e.RowHandle1; int row2 = e.R

关于table动态添加数据 单元格合并 数组合并

var newArr = [ {"BranchID":1,"BranchName":"城二","BranchFullName":"城二分公司","IssueTypeID":101,"IssueTypeName":"宏蜂窝连片弱覆盖","Total":242,"WithoutDemand":139,"

NPOI 生成Excel (单元格合并、设置单元格样式:字段,颜色、设置单元格为下拉框并限制输入值、设置单元格只能输入数字等)

NPIO源码地址:https://github.com/tonyqus/npoi NPIO使用参考:源码中的 NPOITest项目 下面代码包括: 1.包含多个Sheet的Excel 2.单元格合并 3.设置单元格样式:字段,颜色 4.设置单元格为下拉框并限制输入值 5.设置单元格只能输入数字 // // GET: /Excel/ public ActionResult Write() { var workbook = new HSSFWorkbook();//从流内容创建Workbook对象

mysql GROUP_CONCAT 函数 将相同的键的多个单元格合并到一个单元格

mysql GROUP_CONCAT 函数 将相同的键的多个单元格合并到一个单元格 MemberID MemberName FruitName -------------- --------------------- -------------- 1 Al Apple 1 Al Cherry Desired output MemberID MemberName FruitName ----------- -------------- ------------ 1 Al Apple, Cherry