`

可编辑的自动合并单元格的表格

阅读更多

N久没来了,最近项目中用到一个报表,需要能单元格自动合并,并且支持修改,在分页后重新生成表格。所以写了一个小插件在此做个记录。(感觉代码有点罗嗦,层次有点复杂,结构不太清晰,需进一步优化)

 

附件内容:代码、测试页面、操作截图

 

代码如下:

/*
表格插件是一个可编辑、可自动合并单元格的表格
TableView:表格类,
	主要初始化表格参数
	this.data:表格中的数据,要求是一个二维数组,第一维是行,第二维是列
	this.columns:是Column类的集合,对列属性的配置,是否隐藏,是否合并(和合并规则),是否可编辑
	this.tableName:表头需要用户自己设计,所以这里需要配置表格的Id
	this.noDataStr:如果没有数据时,显示的提示信息。
	
Column:列的配置类,列的信息和数据的信息是对应的
	this.isHidden:是否隐藏
	this.isMerged:是否需要合并
	this.mergeConditions:合并条件,是一个MergeCondition的数组
	this.isModified:是否可以修改
	
MergeCondition:合并依据类,根据这些条件决定当前列是否合并
	this.columnIndex:列索引,从0开始,和数据的列对应
	this.conditionType:合并方式,目前只支持列值相等(“eq”),默认可以不填

*/
//定义第一个table类
TableView = function(config){
	this.data = config.data;
	this.columns = config.columns;
	this.tableName = config.tableName;
	this.noDataStr = config.noDataStr?noDataStr:"抱歉,没有找到您需要的数据";
}
TableView.prototype.paint = function(){
	if(this.tableName==null || this.columns==null || this.columns.length<1)return;
	var __table = getE(this.tableName);
	if(__table==null)return;
	//如果没有数据集
	if(this.data==null || this.data.length<1){
		var __tr = __table.insertRow(-1);
		var __td = __tr.insertCell(-1);
		__td.innerHTML = this.noDataStr;
		var colNum = 0;
		for(var j=0; j<this.columns.length; j++){
			if(!this.columns[j].isHidden){
				colNum++;
			}
		}
		__td.setAttribute("colSpan", colNum);
		return;
	}
	//加载表格
	//合并后单元格的Id,只保存td
	var __mergeColumn = [];
	//合并的单元格的个数
	var __mergeNum = [];
	for(var i=0; i<this.data.length; i++){
		var __rowData = this.data[i];
		var __tr = __table.insertRow(-1);
		for(var j=0; j<this.columns.length; j++){
			var __createFlag = true;
			var __column = this.columns[j];
			/*
			如果不需要合并,创建一个新的单元格,
			如果需要合并,
				首先检查内容是否和合并字段内容一致,
				如果一致,直接跳过
				如果不一致,创建新的单元格
			*/
			//根据行和列生成单元格Id
			var __id = getColStr(j)+"_"+i;
			if(__column.isMerged){
				//第一行除外
				if(i>0&&__column.mergeConditions){
					for(var k=0; k<__column.mergeConditions.length; k++){
						var con = __column.mergeConditions[k];
						if(con.columnIndex>=0 && (!con.conditionType || con.conditionType=="eq")){
							__createFlag = this.data[i][con.columnIndex]!=this.data[i-1][con.columnIndex];
						}
						if(__createFlag)break;
					}
				}
			}	
			
			if(__createFlag){
				if(__column.isHidden){
					var __input = document.createElement("input");
					__input.setAttribute("id", __id);
					__input.setAttribute("name", __id);
					__input.setAttribute("type", "hidden");
					__input.setAttribute("value", __rowData[j]);
					__table.appendChild(__input);
				}else{
					var __td = __tr.insertCell(-1);
					__td.innerHTML = __rowData[j];
					__td.setAttribute("id", __id);
					__td.setAttribute("name", __id);
					//如果是可编辑的单元格,添加编辑事件
					if(__column.isModified){
						//双击单元格可编辑
						__td.ondblclick = function(event){
							var __tdinput = document.createElement("input");
							__tdinput.setAttribute("id", "temp_input");
							__tdinput.setAttribute("name", "temp_input");
							__tdinput.setAttribute("type", "text");
							var td;
							if(event==null){
								td=window.event.srcElement;
							}else{
								td=event.target;
							}
							__tdinput.setAttribute("value", td.innerHTML);
							td.innerHTML = "";
							td.appendChild(__tdinput);
							__tdinput.focus();
							__tdinput.select();
							
							//单元格失去焦点时,内容变成输入框的内容
							__tdinput.onblur = function(event){
								var td;
								if(event==null){
									td=window.event.srcElement.parentNode;
								}else{
									td=event.target.parentNode;
								}
								td.innerHTML = getE("temp_input").value;
							}
							//按下回车键时,内容变成输入框的内容
							__tdinput.onkeyup = function(event){
								if(event.keyCode!=13)return;
								var td;
								if(event==null){
									td=window.event.srcElement.parentNode;
								}else{
									td=event.target.parentNode;
								}
								td.innerHTML = getE("temp_input").value;
							}
						}
					}
					__mergeColumn[j] = __id;
					__mergeNum[j] = 1;
				}
			}else{
				getE(__mergeColumn[j]).setAttribute("rowSpan", (++__mergeNum[j]));
			}
		}
	}
}
//Table的列
Column = function(config){
	//是否隐藏
	this.isHidden = config&&(config.typeof("hidden")!="undefined")?config.hidden:false;
	//是否需要合并
	this.isMerged = config&&(config.typeof("isMerged")!="undefined")?config.hidden:false;
	//合并条件
	this.mergeConditions = config&&config.mergeConditions?config.mergeConditions:null;
	//是否可以修改
	this.isModified = config&&(config.typeof("isModified")!="undefined")?config.hidden:false;
	
}

//合并条件 索引从0开始
MergeCondition = function(config){
	this.columnIndex = config&&config.columnIndex?config.columnIndex:null;
	this.conditionType = config&&config.conditionType?config.conditionType:"eq";
}

//**************************************************
//utils
function getE(id){
	return document.getElementById(id);
}

function getColStr(num){
	var cs = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
	if(num<cs.length){
		return cs[num];
	}
	return (getColNum(Math.floor(num/cs.length))+getColNum(num%cs.length));
}

function getColNum(str){
	var cs = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
	if(num<=cs.length){
		return cs[num-1];
	}
	return (getColNum(Math.floor(num/cs.length))+getColNum(num%cs.length));
}

 
分享到:
评论

相关推荐

    富文本编辑器以及表格操作,可拉伸单元格宽度、增加行、增加列、合并单元格

    4. **合并单元格**:合并单元格功能允许用户将相邻的单元格组合成一个大的单元格,常用于创建标题或合并相同的数据。用户可以选择多个单元格,然后执行“合并单元格”操作,以实现这一效果。 5. **其他表格操作**:...

    DevExpress 编辑GridControl中合并单元格

    在DevExpress GridControl中,单元格合并通常用于创建具有复杂布局的表格,比如合并相同值的行或列,或者为了美观和数据组织的需要。以下是实现这一功能的关键步骤和知识点: 1. **设置MergeStrategy**: 要开启...

    可编辑的,单元格自动合并的表格

    标题中的“可编辑的,单元格自动合并的表格”指的是一个功能完善的电子表格工具,它不仅支持用户编辑数据,还能自动处理单元格的合并。在IT领域,这样的表格通常用于数据管理和分析,尤其是在Web应用程序中,可以...

    excel合并单元格自适应行高的宏

    在Excel中,我们经常需要合并单元格以美化表格或突出显示特定信息。然而,一个常见的问题在于,当合并了单元格后,Excel默认不会自动调整行高以适应合并后单元格内的全部内容,这可能会导致部分文字无法完全显示。在...

    vue-easytable合并单元格

    在这个“vue-easytable合并单元格”的主题下,我们将深入探讨如何利用Vue Easytable实现表格中的单元格合并。 在传统的HTML表格中,合并单元格通常使用`&lt;td&gt;`的`colspan`和`rowspan`属性来完成,但在Vue Easytable...

    DataGridView合并单元格

    在.NET框架中,`DataGridView`控件是Windows Forms应用程序中常用的数据展示工具,它允许用户以表格形式查看和编辑数据。在某些情况下,我们可能需要对`DataGridView`的单元格进行合并,例如创建标题行或者汇总行。...

    datagridview横向合并单元格

    6. **事件处理**:在处理用户交互时,需要考虑合并单元格的影响,如选择、编辑和排序等。可能需要重写一些事件处理程序,以确保它们对合并的单元格行为正常。 7. **自定义绘制**:对于更复杂的合并需求,可能需要...

    Exce自动调整行高的宏:解决合并后的单元格自适应行高的问题

    在Excel中,自动调整行高是一项非常实用的功能,尤其在处理大量数据或合并单元格时。标题中的"Exce自动调整行高的宏"指的是利用VBA(Visual Basic for Applications)宏来实现对Excel表格行高的智能调整。宏是Excel...

    最新PHPword整合,优化添加导出表格,表格内部换行,合并单元格

    3. **合并单元格**:在某些情况下,我们需要合并表格中的单元格以达到特定的布局效果。PHPWord提供了`setMerge()`方法来实现这一点。例如,`$cell-&gt;setMerge($startRow, $endRow, $startCol, $endCol)`,可以合并从...

    横向、纵向的合并单元格dataGreatViewMergeCells.zip

    设计师需要确保合并后的单元格在视觉上清晰易读,同时保持控件的可操作性,例如,确保用户可以正确地选择、编辑和排序数据。 6. **测试与调试**: 自定义控件的测试非常重要,需要确保在各种场景下都能正常工作,...

    vue+elementUI实现动态表格合并单元格.zip

    - 表格的可编辑性通常通过将表格单元格设置为输入框(`&lt;input&gt;`)实现。Vue 的事件绑定(如 `@click`、`@input`)可以监听用户对单元格的交互,如点击开启编辑模式,输入后保存数据。 - 可能使用 Vue 的 `v-model`...

    一款可以像excel一样进行编辑的前端表格,可以进行表格的编辑,合并,删除行,插入行等操作

    本主题聚焦于一款能够实现类似Excel功能的前端表格工具,它允许用户进行编辑、合并单元格、删除和插入行等操作,极大地提高了数据管理和交互的便利性。下面将详细探讨这款表格组件的关键特性和实现技术。 首先,该...

    python自动办公源码_在Word表格中将上下行相同内容的单元格自动合并.rar

    需要注意的是,在合并单元格时,需要处理好单元格的宽度、高度以及其他格式问题,确保合并后文档的布局保持整洁。 此外,描述中提到“python源码实例可直接运行”,这意味着这个压缩包中的代码应该已经完成了所有...

    delphi xe 10.2.3 fmx grid 多元化表格 支持合并单元格 单独设置背景色

    3,可以合并单元格(横向竖向均可合并,支持横竖同时合并单元格效果) 4,边框线宽度可以设置(外边框线,内边框线可以分开设置) 5,边框颜色可以设置(内外线色可以设置不同颜色) 6,可以设置编辑状态(此属性是新建单元格属性...

    列表库GridCtrl,包含源码、说明和两种实现合并单元格功能的库

    8. **示例与文档**:压缩包中可能包含了两个不同的库,这些库是在GridCtrl基础之上增加了合并单元格功能的实现,以及相关的示例代码,帮助开发者快速理解和使用。同时,完整的说明文档可以帮助开发者更好地理解...

    datagrid合并单元格,MecGrid实现

    1. **单行合并**:在某些情况下,我们可能希望合并同一行内的多个单元格,例如创建带有标题的表格。在`MecGrid`中,你可以通过设置`columnSpan`属性来实现这一点。为数据提供程序中的特定数据项指定`columnSpan`值,...

    spreadjs_包含合并单元格的数据绑定-demo.zip

    《SpreadJS:实现合并单元格的数据绑定》 SpreadJS 是一款功能强大的JavaScript...通过这个示例,开发者可以学习到如何有效地管理和更新包含合并单元格的表格数据,这对于构建高度交互性和数据驱动的Web应用至关重要。

    Word2021怎么合并和拆分单元格.docx

    **合并单元格**是指将两个或多个相邻的单元格合并为一个单元格,这对于制作复杂表格时经常需要用到。 ##### 方法一:通过上下文菜单合并单元格 1. **步骤解析:** - 打开Word2021文档。 - 选择需要合并的一个或多...

    c# tablelayoutpanel 动态增加和删除列 已测试通过 动态合并单元格 动态添加控件

    这个标题和描述提到的主题聚焦于如何动态地管理和操作`TableLayoutPanel`,包括增加和删除列、动态合并单元格以及动态添加控件。这些功能在创建可自定义或数据驱动的用户界面时非常有用。 首先,让我们详细讨论如何...

    易语言高级表格合并列相同内容

    易语言的高级表格功能提供了丰富的数据操作和展示手段,可以方便地进行数据的读取、编辑、排序和格式化。在处理大量数据时,如果某列中有重复的信息,为了提高数据的可读性和减少冗余,我们可能会选择合并这些重复的...

Global site tag (gtag.js) - Google Analytics