extjs4之合并单元格

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

    <title>ExtJS Merge Cells</title>

    <link type="text/css" rel="stylesheet" href="../extjs4/resources/css/ext-all-neptune.css" />
	<link type="text/css" rel="stylesheet" href="../extjs4/resources/theme/ext-theme-neptune-all.css" />
    <script type="text/javascript" src="../extjs4/ext-all-debug.js"></script>
    <script type="text/javascript" src="../MergeCellTable.js"></script>
    <script type="text/javascript" src="../MergeCellPanel.js"></script>
    <script type="text/javascript" src="example.js"></script>
    <style type="text/css">
		.x-grid-td {
			border-width: 0;
			overflow: hidden;
			vertical-align: middle;
		}
	</style>
</head>
<body>
</body>
</html>

example.js

Ext.onReady(function() {

	Ext.create('Ext.data.Store', {
		storeId:'simpsonsStore',
		fields:['cat1', 'cat2', 'cat2_desc','name'],
		data:{'items':[
			{ "cat1": "分类1", "cat2": "分类21", "name": "名称1" },
			{ "cat1": "分类1", "cat2": "分类22", "name": "名称1" },
			{ "cat1": "分类1", "cat2": "分类22", "name": "名称2" },
			{ "cat1": "分类1", "cat2": "分类23", "name": "名称1" },
			{ "cat1": "分类2", "cat2": "分类21", "name": "名称1" },
			{ "cat1": "分类2", "cat2": "分类21", "name": "名称2" },
			{ "cat1": "分类2", "cat2": "分类22", "name": "名称1" },
			{ "cat1": "分类2", "cat2": "分类23", "name": "名称1" },
			{ "cat1": "分类2", "cat2": "分类24", "name": "名称1" },
			{ "cat1": "分类2", "cat2": "分类24", "name": "名称2" },
			{ "cat1": "分类2", "cat2": "分类24", "name": "名称3" },
			{ "cat1": "分类3", "cat2": "分类21", "name": "名称1" },
			{ "cat1": "分类3", "cat2": "分类22", "name": "名称1" },
			{ "cat1": "分类3", "cat2": "分类23", "name": "名称1" },
			{ "cat1": "分类3", "cat2": "分类24", "name": "名称1" },
			{ "cat1": "分类3", "cat2": "分类24", "name": "名称2" },
			{ "cat1": "分类3", "cat2": "分类25", "name": "名称1" }
		]},
		proxy: {
			type: 'memory',
			reader: {
				type: 'json',
				root: 'items'
			}
		}
	});

    Ext.create('Ext.ux.grid.MergeCellPanel', {
		title: 'Simpsons',
        renderTo: Ext.getBody(),
        viewConfig: {
            mergeColumns: 'cat1>cat2|cat2_desc'
        },
        store: Ext.data.StoreManager.lookup('simpsonsStore'),
        columns: [
            { text: '分类1', dataIndex: 'cat1' },
            { text: '分类2', dataIndex: 'cat2' },
            { text: '分类2描述', dataIndex: 'cat2_desc', flex: 1 },
            { text: '名称', dataIndex: 'name' },
			{ text: '列合并',
			columns:[
				{ text: 'C1' },
				{ text: 'C2' },
				{ text: 'C3' },
				{ text: 'C4' },
				{ text: 'C5' }
			]}

        ]
    });

});

重要核心文件如下

MergeCellTable.js

Ext.define('Ext.ux.view.MergeCellTable', {
    extend: 'Ext.view.Table',

    alias: ['widget.mergecelltableview'],
    type: 'mergecelltableview',
    baseCls: Ext.baseCSSPrefix + 'mergegrid-view',

    stripeRows: false,

    separator: '>', // 不同级别分割符
    sameLevelSeparator: '|', // 同级别分割符
    __rowspans: null, // 缓存要合并的列中每个单元格的rowspan, refresh时会删除重新计算
    __merge_columns: null, // 缓存要合并的列, refresh时会删除重新获取
    cellTpl: [ // 增加了rowspan属性
        '<td role="gridcell" class="{tdCls}" {tdAttr} id="{[Ext.id()]}" rowspan="{rowspan}" <tpl if="hidden">style="display:none"</tpl>>',
            '<div {unselectableAttr} class="' + Ext.baseCSSPrefix + 'grid-cell-inner {innerCls}"',
                'style="height:auto;text-align:{align};<tpl if="style">{style}</tpl>">{value}</div>',
        '</td>', {
            priority: 0
        }
    ],
    renderCell: function(column, record, recordIndex, columnIndex, out) { // 添加rowspan与隐藏td
        var me = this,
            rowspans = me.getRowspans();

        var rowspan = (rowspans[recordIndex] || {})[column.dataIndex];

        cellValues = me.cellValues,
        cellValues.rowspan = rowspan;
        // cellTpl采用了display:none而不是不生成td, 因为若不生成td在使用rowediting时会出错
        cellValues.hidden = rowspan === 0;

        me.callParent(arguments);
    },
    onAdd: function(store, records, index, cfg) {
        this.refresh();
    },
    onRemove: function() {
        this.refresh();
    },
    onUpdate: function() {
        this.refresh();
    },
    refresh: function() {
        var me = this;

        // 刷新时要重新计算rowspan
        delete me.__rowspans;
        delete me.__merge_columns;

        me.callParent(arguments);
    },
    getRowspans: function() {
        var me = this;

        // 已经计算过直接返回
        var rowspans = me.__rowspans;
        if (rowspans != null) {
            return rowspans;
        }

        // 计算rowspan
        rowspans = [];
        var store = me.dataSource,
            mergeColumns = me.getMergeColumns();
        var setSameLevelRowspan = function(rowspans, rowIndex, columns, rowspan) {// 设置同级其他列的rowspan
            var i, temp, len = columns.length;
            for (i = 1; i < len; i++) {
                temp = columns[i];
                rowspans[rowIndex][temp] = rowspan;
            }
        };
        var calculateRowspans = function(rowspans, mergeColumns, currentColumnIndex, store, from, to) {
            if (currentColumnIndex >= mergeColumns.length) {
                return;
            }

            var columns = mergeColumns[currentColumnIndex],
                i, current, prev, mergeStart = 0;
            var column = columns[0];

            try {
                for (i = from; i < to + 1; i++) {
                    current = store.getAt(i).get(column);
                    if (current !== prev) {
                        rowspans[i] = rowspans[i] || {};
                        rowspans[i][column] = 1;
                        setSameLevelRowspan(rowspans, i, columns, 1);

                        // 递归获取子列
                        if (prev != null) {
                            calculateRowspans(rowspans, mergeColumns, currentColumnIndex + 1, store, mergeStart, i - 1);
                        }

                        prev = current;
                        mergeStart = i;
                    } else {
                        rowspans[mergeStart][column]++;
                        setSameLevelRowspan(rowspans, mergeStart, columns, rowspans[mergeStart][column]);

                        rowspans[i] = rowspans[i] || {};
                        rowspans[i][column] = 0;
                        setSameLevelRowspan(rowspans, i, columns, 0);
                    }
                }
                if (i > mergeStart) {
                    calculateRowspans(rowspans, mergeColumns, currentColumnIndex + 1, store, mergeStart, i - 1);
                }
            } catch(e) {
                if (console) {
                    console.error(e);
                }
            }
        };
        calculateRowspans(rowspans, mergeColumns, 0, store, 0, store.data.length - 1);

        // 缓存
        me.__rowspans = rowspans;

        return rowspans;
    },
    getMergeColumns: function() {
        var me = this;
        var columns = me.__merge_columns;
        if (columns != null) {
            return columns;
        }

        // 未配置时直接返回
        var mergeColumns = me.mergeColumns;
        if (Ext.isEmpty(mergeColumns)) {
            return [];
        }

        // 转换合并规则
        var separator = me.separator,
            sameLevelSeparator = me.sameLevelSeparator;
        columns = mergeColumns.split(separator);
        var i, len = columns.length;
        for (i = 0; i < len; i++) {
            columns[i] = columns[i].split(sameLevelSeparator);
        }

        // 缓存
        me.__merge_columns = columns;

        return columns;
    }
});

MergeCellPanel.js

Ext.define('Ext.ux.grid.MergeCellPanel', {
    extend: 'Ext.grid.Panel',

    alias: ['widget.mergecellgrid'],
    viewType: 'mergecelltableview',

    initComponent: function() {
        var me = this;

        Ext.apply(me, {
            selType: 'cellmodel', // 按单元格选择
            sortableColumns: false, // 禁止排序
            columnLines: true, // 显示网格线
            rowLines: true, // 显示网格线
            trackMouseOver: false // 禁止跟踪鼠标变色
        });

        me.callParent();
    }
});

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 13:30:59

extjs4之合并单元格的相关文章

Datatables js 复杂表头 合并单元格

x →Datatables官网← x 项目中用到的Table都是用Datatables插件来搞得: 以前都是生成一般性的table: 近期要生成一些复杂表头,合并单元格之类的: 研究了一下. x 去官网上也查到了[复杂表头(rowspan 和 colspan)(Complex headers (rowspan and colspan))],[复杂表头], 但是只是html代码,蛋疼啊... 后来看到了[创建行回调(Row created callback)]哪里的时候 ,豁然开朗!!!   先上

DataGrid合并单元格(wpf)

在网上搜索wpf合并单元格,一直没搜索到,没办法,只能自己想办法搞定了.其实就是DataGrid套DataGrid,为了方便支持Column拖动,在合并的DataGridColumn那一列的Header也放一个DataGrid,但是合并的这一个连续列中只支持一列的拖动,效果如下,上图 代码如下 首先定义两个模板,一个用于合并的Header显示 <DataTemplate x:Key="MergeHeader">             <DataGrid Horizo

jQuery_easyUI 合并单元格 (DataGrid 数据表格)

<table id="dg" style="height:350px;z-index:-5555; " class="easyui-datagrid" rownumbers="true" data-options="fitColumns: true, iconCls: 'icon-edit', scrollbarSize:0, multiSort:true, remoteSort:true, paginatio

【记录】解析具有合并单元格的Excel

最近公司让做各种数据表格的导入导出,就涉及到电子表格的解析,做了这么多天总结一下心得. 工具:NOPI 语言:C# 目的:因为涉及到导入到数据库,具有合并单元格的多行必然要拆分,而NPOI自动解析的时候拆分单元格除第一个单元格外其余值都是空,对于列头有合并项目的,数据库设计一般才有合并单元格下面的最小列单元作为数据库字段.于是希望达到这样一个效果.于是有了一个思路就是把读入的Excel复制到新建的Excel,然后再去读新的Excel.总体思路就是把合并单元格所包含的所有最小单元格的值都设置成合并

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

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

前端页面表格实现合并单元格

做报表,查询的时候,经常用到表格. 页面展示多条数据时,时常表格的第一列都是相同的,所以合并单元格,让表格看起来更直观. 写这个函数,其它js里面直接调用unionTab (tb,collength);其中第一个参数tb为表格ID,第二个参数为你想要进行单元格合并的表格列数. 缺点:只能实现前N列,不能实现某一列实现合并. /**/ window.unionTab = function (tb, colLength) { var id = tb; tb = $("#" + tb).ge

Extjs3.4 合并单元格

Ext3.4合并单元格 表格上添加grid-row-span样式 列Renderer绑定 预览效果 样式: 代码: 原文:http://www.sencha.com/forum/showthread.php?103133-GridPanel-row-spanning-%28well-sort-of...%29

DevExpress XtraGrid网格控件示例六:自定义合并单元格

假设 "Order Date" 列中包含日期/时间值.如果视图的GridOptionsView.AllowCellMerge选项设置为true,若相邻两个单元格值是日期/时间值的话,这两个相邻单元格便会合并.下面的代码介绍了如何合并例单元格的日期部分,要覆盖默认的单元格合并机制,需要处理一下GridView.CellMerge事件. C# using DevExpress.XtraGrid.Views.Grid; // ... private void gridView1_CellMe

easyui datagrid 合并单元格

整理以前做的东西,这个合并单元格的问题再新浪博客也写过了..... 下面这段代码是列表数据 //载入排放系数管理报表数据 function LoadEmissionReportData() { //获取计算ID var CountID = getUrlParam("CountID"); $.ajax({ type: "POST", url: "../Ashx/GetGasInventoryListInfo.ashx?type=getParamReport&