javascript实现的具有EXCEL功能的table
2010-09-15 14:42
477 查看
用J***ASCRIPT实现了table的单元格合并、拆分,初步具备了EXCEL表格的功能。在网上搜了很多代码,都没有做到真正的单元格合并,要么就是代码的实现方式有问题,我对这些代码进行了整合与修改,形成了可以初步应用于项目的table操作,包括新增行、新增列、单元格合并、合并后的单元格拆分、对要合并的单元格进行是否能进行合并的校验等功能。目前已经在IE 7.0 FireFox 3.6.3下测试通过。
运行后的效果图如下:
<html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> <mce:style type="text/css" rel="stylesheet"><!-- .tds { border-collapse:collapse; border-color:#C6D8F0; border-style:solid; border-width:thin; } --></mce:style><style type="text/css" rel="stylesheet" mce_bogus="1"> .tds { border-collapse:collapse; border-color:#C6D8F0; border-style:solid; border-width:thin; } </style> <mce:script language="javascript" type="text/javascript"><!-- var isIE = (document.all) ? true : false; var isIE6 = isIE && ([/MSIE (/d)/.0/i.exec(navigator.userAgent)][0][1] == 6); var $ = function (id) { return "string" == typeof id ? document.getElementById(id) : id; }; var Extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } }; var Bind = function(object, fun) { var args = Array.prototype.slice.call(arguments,2); return function() { return fun.apply(object, args); } }; var BindAsEventListener = function(object, fun) { var args = Array.prototype.slice.call(arguments,2); return function(event) { return fun.apply(object, [event || window.event].concat(args)); } }; var CurrentStyle = function(element){ return element.currentStyle || document.defaultView.getComputedStyle(element, null); }; var addEventHandler = function(oTarget, sEventType, fnHandler) { if (oTarget.addEventListener) { oTarget.addEventListener(sEventType, fnHandler, false); } else if (oTarget.attachEvent) { oTarget.attachEvent("on" + sEventType, fnHandler); } else { oTarget["on" + sEventType] = fnHandler; } }; var removeEventHandler = function(oTarget, sEventType, fnHandler) { if (oTarget.removeEventListener) { oTarget.removeEventListener(sEventType, fnHandler, false); } else if (oTarget.detachEvent) { oTarget.detachEvent("on" + sEventType, fnHandler); } else { oTarget["on" + sEventType] = null; } }; MerTable = function(){ this.CreatTable=function(tableId,bodyId){ var _table = document.getElementById (tableId); _table.border="1px"; _table.width="800px"; for(var i=1;i<10;i++){ var row=document.createElement ("tr"); row.id=i; for(var j=1;j<6;j++){ var cell=document.createElement ("td"); cell.id =i+"/"+j; cell.appendChild(document.createTextNode ("第"+cell.id+"列")); row.appendChild (cell); } $(bodyId).appendChild(row); } this.Table = _table; }, this.init = function(tableId,bodyId){ this.CreatTable(tableId,bodyId); if(!this.Table){return;} this.SetOptions();//设置参数 this.TableId = tableId; this.BodyId = bodyId; this.HoverColor=this.Options.hoverColor; this.ActiveColor=this.Options.activeColor; this.Hover=this.Options.hover; this.Choose=this.Options.choose; this.Multiple=this.Options.multiple; this.Cancel=this.Options.cancel; this.Title=this.Options.title; this.DClick=this.Options.dclick; this.OnClick=this.Options.onClick; this.OnCancel=this.Options.onCancel; this.OnMove=this.Options.onMove; this.OnDClick=this.Options.onDClick; this.AddMouseEvent(); //添加事件 this._CurrentRow=null; //当前移动行 this.SelectedArray=new Array();//设置或返回被选中行的集合 }, this.SortSelected = function(){ if(this.SelectedArray.length>2) { this.SelectedArray.sort(function(x,y){ var x1 = x.id.split("/"); var y1 = y.id.split("/"); return (parseInt(x1[0])-parseInt(y1[0]) || parseInt(x1[1])-parseInt(y1[1])); }) }else{ return; } }, this.SetOptions=function(options){ this.Options={ hoverColor:"#FFFDD7", //移动时背景色 activeColor:"#FFFDD7", //选中时背景色 hover:true, //是否开启移动行背景色 choose:true, //是否开启选择 multiple:true, //是否开启多选,开启后按Ctrl可以多选,取消功能需要同时开启 title:true, //是否提示title cancel:true, //是否开启取消功能 dclick:true, //是否双击 onClick:function(){}, //选中时附加方法 onCancel:function(){}, //取消选择时附加方法,此时取消功能必须开启 onMove:function(){}, //鼠标移动事件 onDClick:function(){} //双击 }; Extend(this.Options,options||{}); }, this.AddMouseEvent=function(){ if(this.Hover){ addEventHandler(this.Table,"mousemove",BindAsEventListener(this, this.MouseMove)); addEventHandler(this.Table,"mouseout",Bind(this, this.MouseLeave)); } if(this.Choose){ addEventHandler(this.Table,"click",BindAsEventListener(this, this.MouseClick)); } if(this.DClick){ //addEventHandler(this.Table,"dblclick",BindAsEventListener(this, this.Edit)); } }, this.MouseClick=function(e){ var elem=this.GetCurrentElem(e); if(elem==null){return;} var index=this.SelectedIndex(elem); if(index<0){ if(this.Multiple&&this.Cancel){ this.AddSelected(elem); } else{ this.Clear(); this.AddSelected(elem); } elem.style.backgroundColor=this.ActiveColor; this.OnClick(); } else if(this.Cancel){ elem.style.backgroundColor= this.Hover ? this.HoverColor : "transparent"; this.RemoveSelected(elem); this.OnCancel(); } }, this.Clear = function(){ for(var i=0;i<this.SelectedArray.length;i++){ this.SelectedArray[i].style.backgroundColor = "transparent"; } this.RemoveAllSelected(); }, //获取当前事件对象 this.GetCurrentElem = function(e){ var elem = e.srcElement || e.target; if(elem.tagName.toUpperCase()=="TD"){ return elem; } return null; }, this.FindById = function(tdId){ for(var i=0;i<this.SelectedArray.length;i++){ if(this.SelectedArray[i].id==tdId){ return i; } } return -1; }, this.SelectedIndex=function(elem){ for(var i=0;i<this.SelectedArray.length;i++){ if(elem==this.SelectedArray[i]){ return i; } } return -1; }, this.AddSelected = function(elem){ this.SelectedArray.push(elem); }, //从集合中移除 this.RemoveSelected = function(elem){ var index=this.SelectedIndex(elem); this.SelectedArray.splice(index,1); }, this.RemoveAllSelected = function(){ var count=this.SelectedArray.length; this.SelectedArray.splice(0,count); }, this.MouseMove=function(e){ //清除选中内容 document.selection? document.selection.empty() : window.getSelection(); var elem=this.GetCurrentElem(e); if(elem==null){return;} if(this._CurrentRow!=null){ if(this.SelectedIndex(this._CurrentRow)<0){ this._CurrentRow.style.backgroundColor = "transparent"; } else{ this._CurrentRow.style.backgroundColor=this.ActiveColor; } } elem.style.backgroundColor=this.SelectedIndex(elem)<0?this.HoverColor:this.ActiveColor; this._CurrentRow=elem; //添加title if(this.Title){ var cells=elem.getElementsByTagName("td"); for(var i=0;i<cells.length;i++){ cells[i].title= isIE ? cells[i].innerText.replace(/(^/s*)|(/s*$)/g, "") : cells[i].textContent.replace(/(^/s*)|(/s*$)/g, ""); } } this.OnMove(); }, //移出表格后,恢复原色 this.MouseLeave=function(){ if(this._CurrentRow!=null&&this.SelectedIndex(this._CurrentRow)<0){ this._CurrentRow.style.backgroundColor = "transparent"; this._CurrentRow=null; } }, this.Edit = function(sender){ var elem=this.GetCurrentElem(sender); if(elem==null){return;} if(!elem.lastChild || elem.lastChild.tagName != "TEXTAREA") { var box = document.createElement("textarea"); box.style.cssText = "background-color:transparent;border:none; font:12pt 宋体;margin:-2pt -1pt;width:100%; overflow:hidden"; box.rows = 1; if(elem.align) box.style.textAlign = elem.align; box.defaultValue = box.value = elem.innerHTML; elem.innerHTML = ""; elem.appendChild(box); box.onpropertychange = function() { if(this.value) this.style.posHeight = this.scrollHeight; } box.onblur = function() { if(this.value == this.defaultValue) { elem.innerText = this.value; elem.bgColor = ""; } } box.focus(); elem.bgColor = "#effbff"; } }, this.addRow = function(){ var length=this.Table.rows.length; var tr=document.createElement("tr"); tr.id=length+1; var colno = this.getTableCols(this.Table); for(i=1;i<=colno;i++){ var td=document.createElement ("td"); td.id=tr.id+"/"+i; td.appendChild(document.createTextNode("第"+td.id+"列")); tr.appendChild(td); } $(this.BodyId).appendChild (tr); }, this.addCols = function(){ var colNum = 0; for(var i=0;i<this.Table.rows.length;i++) { if(this.Table.rows[i].cells.length>colNum){ colNum = this.Table.rows[i].cells.length; } } for(var i=0;i<this.Table.rows.length;i++) { var cell=document.createElement ("td"); cell.id =(i+1)+"/"+(colNum+1); cell.innerHTML="第"+(i+1)+"/"+(colNum+1)+"列"; this.Table.rows[i].appendChild(cell); } }, this.deleteCols = function(){ var colNum = 0; for(var i=0;i<this.Table.rows.length;i++) { if(this.Table.rows[i].cells.length>colNum){ colNum = this.Table.rows[i].cells.length; } } if(colNum<=1){ alert("表格的列数不允许少于1"); }else{ for(var i=0;i<this.Table.rows.length;i++) { var cell = $((i+1)+"/"+(colNum)) if(cell){ var parentElement=cell.parentNode; if(parentElement){ parentElement.removeChild(cell); } } } } }, this.deleteRow = function(){ var row_no = this.Table.rows.length; if(row_no<=1){ alert("表格的行数不允许少于1"); }else{ var row = $(row_no+""); if(row){ var parentElement=row.parentNode; if(parentElement){ parentElement.removeChild(row); } } } }, this.getTableCols = function(table){ var tableObject = table; if (!tableObject.rows || !tableObject.rows[0] || !tableObject.rows[0].cells){ return 0; } var cells = tableObject.rows[0].cells; var cols = 0; for (var col = 0; col < cells.length; col++){ if (cells[col].colSpan && cells[col].colSpan > 1){ cols = cols + cells[col].colSpan; } else{ cols = cols + 1; } } return cols; }, this.GetMaxRowNum = function(){ var MaxRowNum = 0; for(var i =0;i<this.SelectedArray.length;i++){ if(parseInt(this.SelectedArray[i].id.split("/")[0])>MaxRowNum){ MaxRowNum = parseInt(this.SelectedArray[i].id.split("/")[0]); } } return MaxRowNum; }, this.GetMaxColNum = function(){ var MaxColNum = 0; for(var i =0;i<this.SelectedArray.length;i++){ if(parseInt(this.SelectedArray[i].id.split("/")[1])>MaxColNum){ MaxColNum = parseInt(this.SelectedArray[i].id.split("/")[1]); } } return MaxColNum; }, this.GetMinRowNum = function(){ var MinRowNum = 999999; for(var i =0;i<this.SelectedArray.length;i++){ if(parseInt(this.SelectedArray[i].id.split("/")[0])<MinRowNum){ MinRowNum = parseInt(this.SelectedArray[i].id.split("/")[0]); } } return MinRowNum; }, this.SplitCells = function(){ if(this.SelectedArray.length<=0){ alert("请选择要拆分的单元格!"); }else{ for(var i =0;i<this.SelectedArray.length;i++){ if((this.SelectedArray[i].colSpan>1)&&(this.SelectedArray[i].rowSpan>1)){ var cellPoint = this.SelectedArray[i].id.split("/") var colNum = parseInt(cellPoint[1]); var rowNum = parseInt(cellPoint[0]); for(var m = this.SelectedArray[i].colSpan;m>0;m--){ for(var j = this.SelectedArray[i].rowSpan;j>0;j--){ //var cell=document.createElement("td"); var cellY = colNum+m-1; var cellX = rowNum+j-1; //cell.id =cellX+"/"+cellY; //cell.innerHTML="第"+cellX+"/"+cellY+"列" if($(cellX+"/"+cellY)){ }else{ var insertCellNum = cellY-1; for(var d=cellY;d>=0;d--){ if($(cellX+"/"+d)){ insertCellNum = d; break; } } var x=$(cellX+"").insertCell(insertCellNum); x.id =cellX+"/"+cellY; x.innerHTML="第"+cellX+"/"+cellY+"列"; //$(cellX+"").appendChild(cell); } } } this.SelectedArray[i].rowSpan = 1; this.SelectedArray[i].colSpan = 1; }else{ if(this.SelectedArray[i].colSpan>1 ){ var cellPoint = this.SelectedArray[i].id.split("/") var colNum = parseInt(cellPoint[1]); //for(var m = 0;m<= this.SelectedArray[i].colSpan;m++){ for(var m = this.SelectedArray[i].colSpan;m>0;m--){ //var cell=document.createElement ("td"); var cellY = colNum+m-1; //var cellId = cellPoint[0]+"/"+cellY; //cell.id =cellPoint[0]+"/"+cellY; //cell.innerHTML="第"+cellPoint[0]+"/"+cellY+"列"; //if($(cell.id)){ if($(cellPoint[0]+"/"+cellY)){ }else{ var x=$(cellPoint[0]+"").insertCell(cellY-1); x.id =cellPoint[0]+"/"+cellY; x.innerHTML="第"+cellPoint[0]+"/"+cellY+"列"; //$(cellPoint[0]+"").appendChild(cell); } } this.SelectedArray[i].colSpan = 1; } if(this.SelectedArray[i].rowSpan>1){ var cellPoint = this.SelectedArray[i].id.split("/") var rowNum = parseInt(cellPoint[0]); for(var m = this.SelectedArray[i].rowSpan;m>0;m--){ //var cell=document.createElement ("td"); var cellX = rowNum+m-1; //cell.id =cellX+"/"+cellPoint[1]; //cell.innerHTML="第"+cellX+"/"+cellPoint[1]+"列" if($(cellX+"/"+cellPoint[1])){ }else{ var x=$(cellX+"").insertCell(cellPoint[1]-1); x.id =cellX+"/"+cellPoint[1]; x.innerHTML="第"+cellX+"/"+cellPoint[1]+"列"; //$(cellX+"").appendChild(cell); } } this.SelectedArray[i].rowSpan = 1; } } } this.Clear(); this.RemoveAllSelected(); } }, this.GetMinColNum = function(){ var MinColNum = 999999; for(var i =0;i<this.SelectedArray.length;i++){ if(parseInt(this.SelectedArray[i].id.split("/")[1])<MinColNum){ MinColNum = parseInt(this.SelectedArray[i].id.split("/")[1]); } } return MinColNum; }, this.SaveTable = function(){ var tx = this.Table.parentNode.innerHTML; alert(tx); }, //对所选的单元格进行校验是否能进行合并 this.CheckMergeCells = function(){ if(this.SelectedArray.length<2){ alert("您所选择的单元格无法合并!"); } //循环判断所选单元格是否组成一个矩形,只有形成一个矩形的单元格才能合并 var addCellArray = []; for(var k=0;k<this.SelectedArray.length;k++){ if((this.SelectedArray[k].colSpan>1)&&(this.SelectedArray[k].rowSpan>1)){ var cellPoint = this.SelectedArray[k].id.split("/") var colNum = parseInt(cellPoint[1]); var rowNum = parseInt(cellPoint[0]); for(var m = this.SelectedArray[k].colSpan;m>0;m--){ for(var j = this.SelectedArray[k].rowSpan;j>0;j--){ var cell=document.createElement("td"); var cellY = colNum+m-1; var cellX = rowNum+j-1; cell.id =cellX+"/"+cellY; if(this.FindById(cell.id)<0){ addCellArray.push(cell); } } } }else{ if(this.SelectedArray[k].colSpan>1 ){ var cellPoint = this.SelectedArray[k].id.split("/") var colNum = parseInt(cellPoint[1]); for(var m = this.SelectedArray[k].colSpan;m>0;m--){ var cell=document.createElement ("td"); var cellY = colNum+m-1; cell.id =cellPoint[0]+"/"+cellY; if(this.FindById(cell.id)<0){ addCellArray.push(cell); } } } if(this.SelectedArray[k].rowSpan>1){ var cellPoint = this.SelectedArray[k].id.split("/") var rowNum = parseInt(cellPoint[0]); for(var m = this.SelectedArray[k].rowSpan;m>0;m--){ var cell=document.createElement ("td"); var cellX = rowNum+m-1; cell.id =cellX+"/"+cellPoint[1]; if(this.FindById(cell.id)<0){ addCellArray.push(cell); } } } } } for(var k=0;k<addCellArray.length;k++){ this.SelectedArray.push(addCellArray[k]); } //对所选的单元格进行排序 this.SortSelected(); //取得最小的单元格和最大的单元格 var minRow = this.GetMinRowNum(); var minCol = this.GetMinColNum(); var maxRow = this.GetMaxRowNum(); var maxCol = this.GetMaxColNum(); var canMerge = 0; for(var i = minRow;i<=maxRow;i++){ for(var j=minCol;j<=maxCol;j++){ var isMerge = false; var cellId = i+"/"+j; for(var k=0;k<this.SelectedArray.length;k++){ if(this.SelectedArray[k].id==cellId){ isMerge = true; break; } } if(isMerge == false) { canMerge = canMerge+1; break; } } } if(canMerge >0){ return false; //alert("您所选择的单元格无法合并!"); }else{ return true; //alert("您所选择的单元格已经合并!"); } }, this.MergeCells = function(){ if(!this.CheckMergeCells()){ alert("您所选择的单元格无法合并!"); this.Clear(); this.RemoveAllSelected(); return false; } var minRow = this.GetMinRowNum(); var minCol = this.GetMinColNum(); var maxRow = this.GetMaxRowNum(); var maxCol = this.GetMaxColNum(); //同行合并 if(minRow==maxRow){ var distance = parseInt(maxCol)-parseInt(minCol);//得到列差值 var tmpCell = $(minRow+"/"+minCol); tmpCell.colSpan = distance+1; for(var i=0;i<this.SelectedArray.length;i++){ if(this.SelectedArray[i].id!=tmpCell.id){ var parentElement=this.SelectedArray[i].parentNode; if(parentElement){ parentElement.removeChild(this.SelectedArray[i]); } } } } //同列合并 if(minCol == maxCol){ var distance = parseInt(maxRow)-parseInt(minRow);//得到列差值 var tmpCell = $(minRow+"/"+minCol); tmpCell.rowSpan = distance+1; for(var i=0;i<this.SelectedArray.length;i++){ if(this.SelectedArray[i].id!=tmpCell.id){ var parentElement=this.SelectedArray[i].parentNode; if(parentElement){ parentElement.removeChild(this.SelectedArray[i]); } } } } //多行多列合并 if((minRow!=maxRow)&&(minCol != maxCol)){ var row_distance = parseInt(maxRow)-parseInt(minRow);//得到行差值 var col_distance = parseInt(maxCol)-parseInt(minCol);//得到列差值 var tmpCell = $(minRow+"/"+minCol); tmpCell.rowSpan = row_distance+1; //行合并 tmpCell.colSpan = col_distance+1; //列合并 for(var i=0;i<this.SelectedArray.length;i++){ if(this.SelectedArray[i].id!=tmpCell.id){ var parentElement=this.SelectedArray[i].parentNode; if(parentElement){ parentElement.removeChild(this.SelectedArray[i]); } } } } this.Clear(); this.RemoveAllSelected(); } } // --></mce:script> </head> <body> <form id="form1" runat="server"> <div> <table border="1" cellpadding="0" cellspacing="0" width="95%"> <tr> <td> <input id="addNewRow" type="button" value="新增行" onclick="mertable.addRow();" /> <input id="addNewCol" type="button" value="新增列" onclick="mertable.addCols();"/> <input id="mergerCells" type="button" value="合并单元格" onclick = "mertable.MergeCells()"/> <input id="splitCells" type="button" value="拆分单元格" onclick = "mertable.SplitCells()" /> <input id="deleteRow" type="button" value="删除行" onclick = "mertable.deleteRow()"/> <input id="deleteCol" type="button" value="删除列" onclick = "mertable.deleteCols()"/> <input id="save" type="button" value="保存" onclick="mertable.SaveTable()"/></td> </tr> <tr> <td> <table id="designer" class=tds cellpadding=2 cellspacing=2> <tbody id="designerBody"></tbody> </table> </td> </tr> </table> <mce:script language="javascript"><!-- var mertable = new MerTable(); mertable.init("designer","designerBody"); // --></mce:script> </div> </form> </body> </html>
运行后的效果图如下:
相关文章推荐
- 通过javascript实现table表格排序分页功能(转)
- Javascript + xsl 实现把网页中 翻页的 Table 标签内容导入到excel
- 利用JQuery实现web页面中table导出excel的功能
- 转:Javascript实现把网页中table的内容导入到excel中的几种方法
- Javascript实现把网页中table的内容导入到excel中的几种方法
- Javascript实现把网页中table的内容导入到excel中的几种方法
- Javascript实现把网页中table的内容导入到excel中的几种方法
- javascript 实现 html 页面 table 导出 excel
- Javascript实现把网页中table的内容导入到excel中的几种方法
- Javascript实现把网页中table的内容导入到excel中的几种方法
- JavaScript将Table导出到Excel实现思路及代码
- 采用JavaScript+XML实现具有树形菜单功能的论坛侧边导航栏
- Javascript 实现 Excel 导入生成图表功能
- JavaScript实现类似Excel功能
- JavaScript实现打印页面表报,表单输出到word和excel功能
- Javascript实现把网页中table的内容导入到excel中的几种方法
- javascript实现web中table导出为excel
- Javascript + xsl 实现把网页中 翻页的 Table 标签内容导入到excel
- Javascript + xsl 实现把网页中 翻页的 Table 标签内容导入到excel
- JavaScript将Table导出到Excel实现思路及代码