<!-- Auther:yangwen csdn:y430124(方丈) QQ:794436243 E-mail:[email protected] Current Time:2011-1-6 为了方便你我联系,希望您能保留上边我的个人信息,谢谢。 Help: 最近苦恼于找工作的事,简历投出去后多半是石沉大海,这是一份我随简历发送的一份习作, 该作品是以前在北京一家软件公司实习参与电子报表研发时独立开发的的一个设计器雏形,属于设计器第一版的一部分。 由于只是当初用于简单测试的代码,所以没有考虑界面美观的因素。 现简介习作主要功能如下: 含有横向和纵向拖拽、合并、拆分、区域选取(点击行头或列头选中整行或整列,暂时不支持“ctrl+点击”选取多行)、删除行和列(支持多删)、添加行和列(支持多添)、行列折叠等功能。 提示: 双击输入数据,摁下左键不放选取区域。 合并功能中的重复合并功能在特殊情况下会出现bug,暂时被屏蔽。 多删,多添均是删除或者添加当前被选取的单元格区域中行或者列的数目,添加时默认值为1. 折叠:拖拽行往左时该列的宽度为0或者负数时,可以实现该列的折叠,与excel相仿。 添加操作建议不要超过26列,因为Z列之后没有对列头标索引进行对26的取模处理操作,会出现非字母的头标^_^ Tip: 我将不断完善其功能,并与大家共享,如果您在此基础上对其进行了改进,希望您能发一份给我,在此非常感谢您。 Message: 因为目前我还是无业游民,在此写下求职信息,希望大家不要反感,同时希望好心人能推荐一些.Net开发岗位,最好是在南方,小弟不胜感激。 **********个人信息********** 工作年限: 两个月 到岗时间: 一周以内 工作性质: 全职 希望行业: 计算机软件 目标职位: .Net开发人员 期望薪水: 1500-2000/月,目前只求能养活自己就行啦,日后凭实力加薪^_^ 个人技能: 1. 熟悉C#编程,能熟练应用B/S结构和C/S结构的应用开发中。 2. 熟悉数据结构及各类常用算法,曾参加湖南省ACM竞赛培训,能熟练运用C、C++和Java实现 3. 熟悉Ajax、XML、XHTML、Javascript脚本语言,具有项目开发经验。 4. 熟悉ASP.NET编程,并熟练运用工厂模式进行Asp.NET网站的开发。 5. 熟悉SQL-Server操作并进行开发应用,知道Oracle, mysql等主流数据库的操作。 6. 知道div+css页面布局,并且能运用到具体开发中。 7. 了解Java三大架构。 8. 知道UML统一建模语言及PowerDesigner数据库建模工具。 9. 熟悉软件工程思想,能将其运用于软件开发的整个过程 10. 熟悉需求分析和设计,数据库的设计,以及相关文档的编写。 11. 知道面向对象分析设计、软件测试与软件质量保证,了解QTP单元测试框架等。 12. 语言能力:在校接受NIIT双语教学,具备一定数量的英文文档阅读能力。 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>E Table</title> <style type="text/css"> table { border-collapse: collapse; /*默认为 separate*/ empty-cell: show; /*默认为 hide*/ } #tbData { onmousedown: expression(onmousedown=function(){clickEventDown(event);}); onmouseup: expression(onmouseup=function(){clickEventUp(event);}); onmousemove: expression(onmousemove=function(){clickEventMove(event);}); ondblclick: expression(ondblclick=function(){dblclickEvent(event)}); } #tbData td { border-bottom: 1px solid #D0D0C8; border-right: 1px solid #D0D0C8; width: 60px; height: 19px; text-align: center; } #tbTopHead { onclick: expression(onclick=function(){SelectCol(event);}); } #tbLeftHead { onclick: expression(onclick=function(){SelectRow(event);}); } .cssDivTop { background-color: #D0D0C8; border-top: 1px solid white; border-left: 1px solid white; z-index: 5; position: absolute; width: 35px; height: 21px; } #tbTopHead td { border-right: 1px solid Black; width: 60px; font-size: 13px; } #tbLeftHead td { border-bottom: 1px solid Black; width: 30px; height: 19px; text-align: center; } </style> </head> <body style="background-color: white; overflow: hidden"> <input type="button" id="btnAddColToLeft" onclick="AddCol('left')" value="左添列" /> <input type="button" id="btnAddColToRight" onclick="AddCol('right')" value="右添列" /> <input type="button" id="btnAddRowToUp" onclick="AddRow('up')" value="上添行" /> <input type="button" id="btnAddRowToDown" onclick="AddRow('down')" value="下添行" /> <input type="button" id="btnDelRow" onclick="DelRow()" value="删除行" /> <input type="button" id="btnDelRow" onclick="DelCol()" value="删除列" /> <input type="button" id="btnUniteCells" onclick="UniteCells()" value="合并" /> <input type="button" id="btnSplitCells" onclick="SplitCells()" value="拆分" /> <table id="MathBar" width="99%" style="background-color: #D0D0C8; position: absolute; table-layout: fixed; height: 22px; top: 45px; left: 1px;background-image:url(skins/blue/img/background.jpg);"> <tr align="center"> <td id="colName" width="50px" align="center"> Pos </td> <td width="20px" align="center"> = </td> <td> <input type="text" id="txtMathExp" style="border-bottom: medium; width: 100%" onkeyup="CopyEditText(this)" value="Math Expression" /> </td> </tr> </table> <table id="splitLine" style="width: 100%; border-bottom: 2px solid #6E7274; position: absolute; top: 67px; left: 1px;"> <tr> <td /> </tr> </table> <div id="divAll" style="position: absolute; left: 0px; top: 22px;"> <div id="divTopHead" style="background-color: #D0D0C8; z-index: 5; position: absolute; top: 48px; left: 37px; height: 21px; width: 500px; overflow: hidden"> <table id="tbTopHead" cellpadding="0" cellspacing="0" style="table-layout: fixed;"> <tr align="center" style="line-height: 22px;"> <td id="A" onmousedown="MouseDown()" onmouseup="MouseUp()" onmousemove="MouseMove(this)"> A </td> <td id="B" onmousedown="MouseDown()" onmouseup="MouseUp()" onmousemove="MouseMove(this)"> B </td> <td id="C" onmousedown="MouseDown()" onmouseup="MouseUp()" onmousemove="MouseMove(this)"> C </td> <td id="D" onmousedown="MouseDown()" onmouseup="MouseUp()" onmousemove="MouseMove(this)"> D </td> <td id="E" onmousedown="MouseDown()" onmouseup="MouseUp()" onmousemove="MouseMove(this)"> E </td> </tr> </table> </div> <div id="divLeftHead" class="cssDivTop" style="height: 383px;top:69px;left: 0px; overflow: hidden;"> <table id="tbLeftHead" cellpadding="0" cellspacing="0" style="table-layout: fixed;"> <tr> <td id="1" onmousedown="MouseDown()" onmousemove="MouseMove(this)"> 1 </td> </tr> <tr> <td id="2" onmousedown="MouseDown()" onmousemove="MouseMove(this)"> 2 </td> </tr> <tr> <td id="3" onmousedown="MouseDown()" onmousemove="MouseMove(this)"> 3 </td> </tr> <tr> <td id="4" onmousedown="MouseDown()" onmousemove="MouseMove(this)"> 4 </td> </tr> <tr> <td id="5" onmousedown="MouseDown()" onmousemove="MouseMove(this)"> 5 </td> </tr> </table> </div> <div id="divTopLeft" style="background-color: #D0D0C8; z-index: 5; position: absolute; top: 48px; left: 1px; height: 21px; width: 37px; overflow: hidden"> <table> <tr> <td style="width: 35px; border-right: 1px solid black;"> </td> </tr> </table> </div> <div id="divMain" style="width: 970px; height: 383px; z-index: -5; position: absolute; top: 69px; left: 36px; overflow: scroll; background-color: white; padding: 0px; border-left: 1px solid white; border-bottom: 1px solid white;" onscroll="scrollHead()"> <table id="tbData" cellpadding="0" cellspacing="0" style="table-layout: fixed;"> <colgroup> <col style="width: 60px;" /> <col style="width: 60px;" /> <col style="width: 60px;" /> <col style="width: 60px;" /> <col style="width: 60px;" /> </colgroup> <tr> <td /> <td /> <td /> <td /> <td /> </tr> <tr> <td /> <td /> <td /> <td /> <td /> </tr> <tr> <td /> <td /> <td /> <td /> <td /> </tr> <tr> <td /> <td /> <td /> <td /> <td /> </tr> <tr> <td /> <td /> <td /> <td /> <td /> </tr> </table> <!--隐藏的输入文本框--> <input name="txtEdit" id="txtEdit" style="display: none; z-index: 0; position: absolute; text-align: ; width: 69px; height: 16px; font-family: ; font-weight: ; overflow: hidden; top: 132px; left: 94px; border-left: medium none; border-top: medium none; border-right: medium none; border-bottom: medium none;" onkeyup="CopyEditText(this)" onfocus="oRng=this.createTextRange();oRng.collapse(true);oRng.moveStart('character',this.value.length);oRng.select()" type="text" value="txtEdit" /> <!--西边竖线隐藏层--> <div id="divWestLine" style="background-color: blue; display: none; width: 2px; height: 20px; position: absolute; top: 50px; left: 12px;"> </div> <!--北边横线隐藏层 --> <div id="divNorthLine" style="background-color: blue; display: none; width: 60px; height: 2px; position: absolute; top: 50px; left: 12px; overflow: hidden"> </div> <!--东边竖线隐藏层--> <div id="divEastLine" style="background-color: blue; display: none; width: 2px; height: 20px; position: absolute; top: 50px; left: 12px;"> </div> <!--南边横线隐藏层--> <div id="divSouthLine" style="background-color: blue; display: none; width: 60px; height: 2px; position: absolute; top: 50px; left: 12px; overflow: hidden"> </div> </div> </div> <!--竖线的隐藏层--> <div id="myDivCol" style="filter: progid:DXImageTransform.Microsoft.Chroma(color='blue'); background-color: blue; display: none; height: 50px; left: 12px; position: absolute; top: 50px; width: 100px;" align="center" onmousemove="MouseMove(this)" onmouseup="MouseUp()"> <div id="myLineCol" style="width: 1px; height: 50px; background-color: Black;"> </div> </div> <!--横线的隐藏层--> <div id="myDivRow" style="filter: progid:DXImageTransform.Microsoft.Chroma(color='blue'); background-color: blue; display: none; height: 100px; width: 50px; left: 12px; position: absolute; top: 50px; vertical-align: middle; text-align: center;" onmousemove="MouseMove(this)" onmouseup="MouseUp()"> <div style="height: 49px"> </div> <div id="myLineRow" style="width: 50px; height: 1px; background-color: black; overflow: hidden"> </div> </div> <script type="text/javascript"> window.onload = function () { //解决window.onresize事件多次调用问题 var resizeTimer = null; window.onresize = function () { if (resizeTimer) clearTimeout(resizeTimer); resizeTimer = setTimeout("AdjustSize()", 10); } AdjustSize(); } function scrollHead() { var oDivHead = document.getElementById("divTopHead"); var oDivLeft = document.getElementById("divLeftHead"); oDivHead.scrollLeft = event.srcElement.scrollLeft; oDivLeft.scrollTop = event.srcElement.scrollTop; //SetTextFrame(indexX, indexY, endX, endY); } </script> </body> <script type="text/javascript"> /* * 作者:yangwen, 2010-12-3 * 版本 :1.0 * 维护日志: * yangwen, 2010-12-17, 注释信息替换 * yangwen, 2011-1-6, 修复竖线可见层的一个bug * * 文档说明: * 设计器界面事件源码集合 */ //全局变量说明: var isChecked = 0; /* * isChecked 变量值说明: * * 0,没有发生拖拽; * 1,水平向东拖拽; * 2,水平向东西拖拽; * 3,竖直向北拖拽; * 4,竖直向南北拖拽; */ var toMove = false; //标识鼠标是否摁下 var toTdMove = false; //标识鼠标是否在数据区摁下 var originalX, originalY, currentX, currentY, indexValue; /* * originalX, originalY, currentX, currentY, indexValue 变量说明: * * originalX,鼠标摁下瞬间鼠标指针的x坐标 * originalY,鼠标摁下瞬间鼠标指针的y坐标 * currentX,鼠标释放瞬间鼠标指针的x坐标 * currentY,鼠标释放瞬间鼠标指针的y坐标 * 以上四个变量主要用于数据区域选取时,便于蓝色边框框选选中区域 * * indexValue 鼠标松开时所在单元格的索引,主要用于拖拽表示要改变宽度或者高度的列或者行 */ var cellWidth, cellHeight; //单元格宽、高 var oTdPos = { x: -1, y: -1 }; //记录当前焦点TD的相对table位置(因为合会并补Pnet) var indexX = -1, indexY = -1, endX = -1, endY = -1; //记录当前焦点TD的位置 /* * indexX, indexY, endX, endY变量说明: * 默认值:-1,其目的在于表示没有单元格或区域被选取 * * indexX, 鼠标《摁下》时所在单元格位置的《列》索引 * indexX, 鼠标《释放》时所在单元格位置的《列》索引 */ //拖拽时的鼠标事件 function MouseDown() { if (isChecked > 0) { toMove = true; //IF块判断是否是水平拖拽,否则为竖直方向拖拽 if (isChecked == 1 || isChecked == 2) { myDivCol.style.display = ""; //竖直层可见,默认为none //动态设置竖直标识线和竖直层的高度 myLineCol.style.height = myDivCol.style.height = divTopHead.offsetHeight + divMain.offsetHeight - 15; //动态确定竖直标识线的坐标位置,竖直表示线主要在水平拖拽中起到跟随鼠标位置水平移动 //如下的event.x为当前鼠标的水平坐标值,因为竖直层的宽度是100px, //用竖直层左端坐标减去50个像素正好可以使竖直线处于坐标指针的正下方 //附录:宽度设置为100个像素是为了加强层对鼠标移动的敏感程度,如下的+5意在于字母行完美结合 myDivCol.style.top = divTopHead.offsetTop + 20; myDivCol.style.left = event.x - 50; } else { //详细注释如上所叙 myDivRow.style.display = ""; //水平层可见,默认为none myLineRow.style.width = myDivRow.style.width = divTopLeft.offsetWidth + divMain.offsetWidth; myDivRow.style.top = event.y - 50; myDivRow.style.left = divTopLeft.offsetLeft; } //记录鼠标的原始位置 originalX = event.x; originalY = event.y; } } //拖拽时的鼠标事件 function MouseUp() { //下面的判断: //如果之前没有摁下鼠标,则不做任何处理, //主要用于屏蔽在行头或列头摁下鼠标,而在数据区松开鼠标, //导致对象为空的情况 if (toMove == false) { return; } //鼠标松开,表示当前的水平坐标和竖直坐标 currentX = event.x; currentY = event.y; var minStep = 5; //该变量主要用于拖拽改变鼠标形状的最小敏感像素, //建议不要将该值甚至过大或过小 //以下if块用于释放鼠标时改变列宽或者行高 //当然如果拖拽的像素大小小于最小敏感像素则不做任何处理 //isChecked为1、2为水平拖拽,3、4为竖直拖拽 if ((isChecked == 1 || isChecked == 2) && Math.abs(currentX - originalX) >= minStep) { //isChecked为1为水平向东拖拽,2为水平向西拖拽 //这里之所以划分东西方向在于水平向西拖拽时, //若拖拽区域大于相邻列的宽度,则需要折叠相邻列的所有单元格 if (isChecked == 1) { if (cellWidth + currentX > originalX) { //“document.getElementById("tbData").firstChild”为数据区单元格对象 document.getElementById("tbData").firstChild.childNodes[indexValue].style.width = document.getElementById("tbTopHead").rows[0].cells[indexValue].style.width = cellWidth + currentX - originalX; } else { //折叠单元格;indexValue 鼠标松开时所在单元格的索引 document.getElementById("tbData").firstChild.childNodes[indexValue].style.width = document.getElementById("tbTopHead").rows[0].cells[indexValue].style.width = 0; } } else { //详情参考上方注释 if (parseInt(document.getElementById("tbData").firstChild.childNodes[indexValue - 1].style.width) + currentX > originalX) { document.getElementById("tbData").firstChild.childNodes[indexValue - 1].style.width = document.getElementById("tbTopHead").rows[0].cells[indexValue - 1].style.width = parseInt(document.getElementById ("tbTopHead").rows[0].cells[indexValue - 1].currentStyle.width) + currentX - originalX; } else { document.getElementById("tbData").firstChild.childNodes[indexValue - 1].style.width = document.getElementById("tbTopHead").rows[0].cells[indexValue - 1].style.width = 0; } } } else if ((isChecked == 3 || isChecked == 4) && Math.abs(currentY - originalY) >= minStep) { if (isChecked == 3) { if (parseInt(document.getElementById("tbLeftHead").rows[indexValue - 1].cells[0].currentStyle.height) + currentY > originalY) { document.getElementById("tbData").rows[indexValue - 1].style.height = document.getElementById ("tbLeftHead").rows[indexValue - 1].cells[0].style.height = parseInt(document.getElementById("tbLeftHead").rows [indexValue - 1].cells[0].currentStyle.height) + currentY - originalY; } else { document.getElementById("tbData").rows[indexValue - 1].style.height = document.getElementById ("tbLeftHead").rows[indexValue - 1].cells[0].style.height = 0; } } else { if (cellHeight + currentY > originalY) { document.getElementById("tbData").rows[indexValue].style.height = document.getElementById ("tbLeftHead").rows[indexValue].cells[0].style.height = cellHeight + currentY - originalY; } else { document.getElementById("tbData").rows[indexValue].style.height = document.getElementById ("tbLeftHead").rows[indexValue].cells[0].style.height = 0; } } } isChecked = 0; //改为默认值,标识为没有发生拖拽 toMove = false; //隐藏竖线和水平线 myDivCol.style.display = "none"; myDivRow.style.display = "none"; //重新加载文本框 if (divNorthLine.style.display != "none") { var oTd = tbData.rows[indexY].cells[indexX]; SetTextFrame(indexX, indexY, endX, endY); txtEdit.style.display = "none"; } } //拖拽时的鼠标事件 function MouseMove(oCell) { //判断是否摁下了鼠标右键,event.button == 1为true表示摁下了左键 if (toMove && event.button == 1) { //水平拖拽 if (isChecked == 1 || isChecked == 2) { //设置层离理左端的距离,其中-50是因为该层的总宽度为100,如此可让竖直线居中 myDivCol.style.left = event.x - 50; //该表鼠标样式 oCell.style.cursor = "col-resize"; return; } else { //设置层离上端端的距离,其中-50是因为该层的总高度为100,如此可让水平直线居中 myDivRow.style.top = event.y - 50; oCell.style.cursor = "row-resize"; return; } } else { var minStep = 2; //设置敏感边框区域的像素 var cellPos = getCoordinate(oCell); //单元格的左上角坐标集合 //cellPos如果为false,说明获取单元格坐标失败 if (cellPos == "false") { toMove = false; return; } //屏蔽掉头标签行最左边单元格的敏感区域,防止引发不必要的错误 if (oCell.id == "A" || oCell.id == "1") { oCell.style.cursor = "default"; //不该表鼠标样式,因为鼠标样式直接关系到能否拖拽 return; } cellWidth = oCell.offsetWidth; //记录鼠标所在单元格的宽度 cellHeight = oCell.offsetHeight; //记录鼠标所在单元格的高度 var mouseX = window.event.clientX; //鼠标的x坐标 var mouseY = window.event.clientY; //鼠标的y坐标 var leftX = cellPos.left; //单元格左上角的点坐标x坐标 var leftY = cellPos.top; //单元格做上角点坐标y坐标 var rightX = cellWidth + leftX; //单元格的右下角的点x坐标 var rightY = cellHeight + leftY; //单元格的右下角的点y坐标 //改变鼠标的样式 //首先判断是在上端水平字母头标签还是左边竖直数字头标签 if (oCell.parentNode.parentNode.parentNode.id == "tbTopHead") { //正东 if (rightX - mouseX > 0 && rightX - mouseX < minStep) { oCell.style.cursor = "col-resize"; //横向拖拽的鼠标样式 isChecked = 1; //记录拖拽方向 } //正西 else if (mouseX > leftX && mouseX - leftX < minStep + 2) { oCell.style.cursor = "col-resize"; isChecked = 2; //记录拖拽方向 } //其他,则为默认鼠标样式 else { oCell.style.cursor = "default"; isChecked = 0; //记录拖拽方向 return false; } indexValue = oCell.id.charCodeAt() - 65; } else { //正北 if (mouseY > leftY && mouseY - leftY < minStep + 2) { oCell.style.cursor = "row-resize"; isChecked = 3; } //正南 else if (rightY > mouseY && rightY - mouseY < minStep) { oCell.style.cursor = "row-resize"; isChecked = 4; } else { oCell.style.cursor = "default"; return false; } indexValue = oCell.id.charCodeAt() - 49; } } } //End MouseMove Event //获取单元格左上角相对于body的左上角离左边和顶端的距离 //参数:单元格对象 //返回值:表格左上角坐标,left->X,top->Y function getCoordinate(oCell) { try { for (var sumTop = 0, sumLeft = 0; oCell && oCell != document.body; ) { sumTop += oCell.offsetTop, sumLeft += oCell.offsetLeft, oCell = oCell.offsetParent; } return { left: sumLeft, top: sumTop } } catch (err) { return "false"; } } //数据区的单击选取事件,鼠标摁下 var onselstart = null; function clickEventDown(event) { //下面的方法作用为:摁下鼠标后,不能选中数据区的数据,用于数据区的区域选择时不选中数据,造成样式美观问题 onselstart = document.getElementById("divAll").onselectstart; document.getElementById("divAll").onselectstart = function () { return false; } toTdMove = true; //表明在数据区摁下了鼠标左键,能够触发数据区td的移动事件 var oTd = event.srcElement; var oTr = oTd.parentNode; //获得单元格坐标 indexX = getX(oTd); indexY = oTr.rowIndex; //获得单元格真实坐标 oTdPos.y = oTd.cellIndex; oTdPos.x = oTr.rowIndex; //拷贝单元格内容 txtMathExp.value = oTd.innerText; //设置单元格的位置展示,形式如:B2,C3 colName.innerHTML = String.fromCharCode(65 + indexX) + (indexY + 1); //可编辑文本框不可见 txtEdit.style.display = "none"; } //数据区的单击选取事件,鼠标松开 function clickEventUp(event) { if (toTdMove == false) { return; } var oTd = event.srcElement; var oTr = oTd.parentNode; if (onselstart != null) { document.getElementById("divAll").onselectstart = onselstart; } //获取单元格位置 endX = getX(oTd); endY = oTr.rowIndex; if (endX == indexX && endY == indexY) { txtEdit.style.display = "none"; } //重新画边框 SetTextFrame(indexX, indexY, endX, endY); } function clickEventMove(event) { if (toTdMove == false || event.button != 1) { return; } var oTd = event.srcElement; var oTr = oTd.parentNode; //获得文本框的原始列索引位置 endX = getX(oTd); endY = oTr.rowIndex; //重新设置边框选区 SetTextFrame(indexX, indexY, endX, endY); } //数据区的双击事件 function dblclickEvent(event) { var oTd = event.srcElement; var oTr = oTd.parentNode; var cellPos = getCoordinate(oTd); //获得文本框的原始列索引位置 indexX = getX(oTd); indexY = oTr.rowIndex; //Set the around W,N,E,S Lines //设置单元格的选取边框 endX = indexX, endY = indexY; SetTextFrame(indexX, indexY, endX, endY); txtEdit.style.display = ""; //拷贝单元格属性 txtEdit.style.fontFamily = oTd.currentStyle.fontFamily; txtEdit.style.fontSize = oTd.currentStyle.fontSize; txtEdit.style.fontWeight = oTd.currentStyle.fontWeight; txtMathExp.value = txtEdit.value = oTd.innerText; colName.innerHTML = String.fromCharCode(65 + indexX) + (indexY + 1); //设置文本框位置 txtEdit.style.top = cellPos.top - 91; txtEdit.style.left = cellPos.left - 34; //设置文本框的高宽 txtEdit.style.width = oTd.offsetWidth; txtEdit.style.height = oTd.offsetHeight; //文本框获得输入焦点 txtEdit.focus(); } //获取当前单元格原始索引,即没有发生合并前的索引位置 function getX(oTd) { var count = -1; while (oTd != null) { oTd = oTd.previousSibling; count++; } return count; } //坐标均为页面单元格索引坐标(x为所在列的索引值,y为所在行的索引值),从零开始 //x1,y1为鼠标摁下时的单元格坐标 //x2,y2为鼠标松开时的单元格坐标 //区域划分为九个区域(八个方向+原点) function SetTextFrame(x1, y1, x2, y2) { if (x1 == undefined || y1 == undefined || x2 == undefined || y2 == undefined) { return; } var cellPos, w, h; if (x1 == x2) { if (y1 == y2) {//中心区,摁下鼠标时的单元格区域 cellPos = getCoordinate(tbData.rows[y1].childNodes[x1]); w = tbData.rows[y1].childNodes[x1].offsetWidth; h = tbData.rows[y1].childNodes[x1].offsetHeight; } else if (y1 > y2) {//正北区 cellPos = getCoordinate(tbData.rows[y2].childNodes[x2]); w = tbData.rows[y2].childNodes[x2].offsetWidth; h = 0; for (var i = 0; i <= y1 - y2; i++) { h += tbData.rows[y2 + i].childNodes[x2].offsetHeight; i += tbData.rows[y2 + i].childNodes[x2].rowSpan - 1; } } else {//正南区 cellPos = getCoordinate(tbData.rows[y1].childNodes[x1]); w = tbData.rows[y1].childNodes[x1].offsetWidth; h = 0; for (var i = 0; i <= y2 - y1; i++) { h += tbData.rows[y1 + i].childNodes[x1].offsetHeight; i += tbData.rows[y1 + i].childNodes[x1].rowSpan - 1; } } } else if (x1 < x2) { if (y1 == y2) {//正东区 cellPos = getCoordinate(tbData.rows[y1].childNodes[x1]); w = 0; for (var i = 0; i <= x2 - x1; i++) { w += tbData.rows[y1].childNodes[x1 + i].offsetWidth; i += tbData.rows[y1].childNodes[x1 + i].colSpan - 1; } h = tbData.rows[y1].childNodes[x1].offsetHeight; } else if (y1 > y2) {//东北区 cellPos = getCoordinate(tbData.rows[y2].childNodes[x1]); w = h = 0; for (var i = 0; i <= x2 - x1; i++) { w += tbData.rows[y2].childNodes[x1 + i].offsetWidth; i += tbData.rows[y2].childNodes[x1 + i].colSpan - 1; } for (var i = 0; i <= y1 - y2; i++) { h += tbData.rows[y2 + i].childNodes[x1].offsetHeight; i += tbData.rows[y2 + i].childNodes[x1].rowSpan - 1; } } else {//东南区 cellPos = getCoordinate(tbData.rows[y1].childNodes[x1]); w = h = 0; for (var i = 0; i <= x2 - x1; i++) { w += tbData.rows[y1].childNodes[x1 + i].offsetWidth; i += tbData.rows[y1].childNodes[x1 + i].colSpan - 1; } for (var i = 0; i <= y2 - y1; i++) { h += tbData.rows[y1 + i].childNodes[x1].offsetHeight; i += tbData.rows[y1 + i].childNodes[x1].rowSpan - 1; } } } else { if (y1 == y2) {//正西区 cellPos = getCoordinate(tbData.rows[y2].childNodes[x2]); w = 0; for (var i = 0; i <= x1 - x2; i++) { w += tbData.rows[y2].childNodes[x2 + i].offsetWidth; i += tbData.rows[y2].childNodes[x2 + i].colSpan - 1; } h = tbData.rows[y2].childNodes[x2].offsetHeight; } else if (y1 > y2) {//西北区 cellPos = getCoordinate(tbData.rows[y2].childNodes[x2]); w = h = 0; for (var i = 0; i <= x1 - x2; i++) { w += tbData.rows[y2].childNodes[x2 + i].offsetWidth; i += tbData.rows[y2].childNodes[x2 + i].colSpan - 1; } for (var i = 0; i <= y1 - y2; i++) { h += tbData.rows[y2 + i].childNodes[x2].offsetHeight; i += tbData.rows[y2 + i].childNodes[x2].rowSpan - 1; } } else {//西南区 cellPos = getCoordinate(tbData.rows[y1].childNodes[x2]); w = h = 0; for (var i = 0; i <= x1 - x2; i++) { w += tbData.rows[y1].childNodes[x2 + i].offsetWidth; i += tbData.rows[y1].childNodes[x2 + i].colSpan - 1; } for (var i = 0; i <= y2 - y1; i++) { h += tbData.rows[y1 + i].childNodes[x2].offsetHeight; i += tbData.rows[y1 + i].childNodes[x2].rowSpan - 1; } } } //该函数的以下代码用于设置四个方向的单元格选中框的边框线 divWestLine.style.display = divNorthLine.style.display = divEastLine.style.display = divSouthLine.style.display = ""; //四条边框线可见 //因为线的层位于数据层内,下面的加减操作主要是获得单元格相对于数据层的坐标 cellPos.top -= 91; cellPos.left -= 36; //设置西线的位置和高度,宽度默认为1px divWestLine.style.top = cellPos.top; divWestLine.style.left = cellPos.left; divWestLine.style.height = h; //设置北西线的位置和宽度,高度默认为1px divNorthLine.style.top = cellPos.top; divNorthLine.style.left = cellPos.left; divNorthLine.style.width = w - 1; //设置东线的位置和高度(+2是减去重叠区的高度),宽度默认为1px divEastLine.style.top = cellPos.top; divEastLine.style.left = cellPos.left + w - 1; divEastLine.style.height = h + 2; //设置南线的位置和宽度,高度默认为1px divSouthLine.style.top = cellPos.top + h; divSouthLine.style.left = cellPos.left; divSouthLine.style.width = w - 1; } //拷贝单元格内容 function CopyEditText(oText) { //setTimeout(code, time); if (indexX == -1) { alert("您当前未选择单元格"); //屏蔽输入的键值 event.keyCode = 0; event.returnValue = false; return; } if (event.keyCode == 37 || event.keyCode == 39) { return event.returnValue = true; } tbData.rows[indexY].childNodes[indexX].innerHTML = txtMathExp.value = txtEdit.value = oText.value; } //添加行 //包含同时添加多行的情况 function AddRow(direction) { if (indexY == -1) { alert("您当前还没有选择单元格"); return; } //统计一共要添加多少行 var areaTotal = getSelectedObject(); var total = areaTotal.rightBottomPoint_Y - areaTotal.leftTopPoint_Y + 1; //统计有多少列 var colCount = tbTopHead.rows[0].cells.length; var oRow, pos; //判断是上添加还是下添加 if (direction == "up") { pos = areaTotal.leftTopPoint_Y; for (var i = 0; i < total; i++) { oRow = tbData.insertRow(pos); for (var j = 0; j < colCount; j++) { oRow.insertCell(); } } indexY += total; endY += total; } else { pos = areaTotal.rightBottomPoint_Y + 1; for (var i = 0; i < total; i++) { oRow = tbData.insertRow(pos); for (var j = 0; j < colCount; j++) { oRow.insertCell(); } } } //移动选择框的位置 SetTextFrame(indexX, indexY, endX, endY); //在左边最末尾添加一个行的标号 var rowCount = tbLeftHead.rows.length; for (var i = 0; i < total; i++) { oRow = tbLeftHead.insertRow(pos); var oTd = oRow.insertCell(); //添加事件 oTd.onmousedown = MouseDown; oTd.onmousemove = function () { MouseMove(this); }; oTd.innerText = pos + total - i; oTd.setAttribute("id", oTd.innerText); } rowCount = tbLeftHead.rows.length; for (var i = pos + total; i < rowCount; i++) { tbLeftHead.rows[i].cells[0].innerText = i + 1; } //重新设置id,因为增删查该会改变单元格的id ResetId(); } //添加列 //包含同时添加多列的情况 function AddCol(direction) { if (indexX == -1) { alert("您当前还没有选择单元格"); return; } //统计一共要添加多少列 var areaTotal = getSelectedObject(); var total = areaTotal.rightBottomPoint_X - areaTotal.leftTopPoint_X + 1; var rowCount = tbData.rows.length; var colCount = tbTopHead.rows[0].cells.length; var leftPos = -1; var oTemp = tbData.rows[0].cells[(direction == "right") ? areaTotal.rightBottomPoint_X : areaTotal.leftTopPoint_X]; while (oTemp != null) { oTemp = oTemp.previousSibling; leftPos++; } //判断是右添加还是左添加 if (direction == "right") { for (var obj, i = 0; i < rowCount; i++) { for (var j = 0; j < total; j++) { oTemp = tbData.rows[i].childNodes[leftPos].cloneNode(true); tbData.rows[i].childNodes[leftPos].replaceNode(document.createElement("<td/>")); tbData.rows[i].insertBefore(oTemp, tbData.rows[i].childNodes[leftPos]); } } } else { for (var obj, i = 0; i < rowCount; i++) { for (var j = 0; j < total; j++) { tbData.rows[i].insertBefore(document.createElement("<td/>"), tbData.rows[i].childNodes[leftPos]); } } } //设置行的字母标号 for (var i = 0; i < total; i++) { var oCell = tbTopHead.rows[0].insertCell(areaTotal.leftTopPoint_X); oCell.innerHTML = String.fromCharCode(areaTotal.leftTopPoint_X + total - i + 64); oCell.setAttribute("id", oCell.innerHTML); //添加事件 oCell.onmousedown = function () { MouseDown() }; oCell.onmouseup = function () { MouseUp() }; oCell.onmousemove = function () { MouseMove(this); }; //设置列集合中该列的跨度 var obj = tbData.firstChild.childNodes[colCount - 1].cloneNode(true); obj.style.width = 60; //tbData.firstChild.appendChild(obj); tbData.firstChild.insertBefore(obj, tbData.firstChild.firstChild); } //更新字符 colCount = tbTopHead.rows[0].cells.length; for (var i = areaTotal.leftTopPoint_X + total; i < colCount; i++) { tbTopHead.rows[0].cells[i].id = tbTopHead.rows[0].cells[i].innerText = String.fromCharCode(i + 65); } //设置单元格选中区域 if (direction == "left") { indexX += total; endX += total; } //重新设置id ResetId(); //重新设置蓝色边框的区域 SetTextFrame(indexX, indexY, endX, endY); } //删除行 //包括同时删除多行的情况 function DelRow() { if (indexY == -1) { alert("您当前还没有选择单元格"); return; } var areaTotal = getSelectedObject(); var total = areaTotal.rightBottomPoint_Y - areaTotal.leftTopPoint_Y + 1; var colCount = tbTopHead.rows[0].cells.length; var pos = -1; var oTd = tbData.rows[indexY].cells[areaTotal.leftTopPoint_X]; while (oTd != null) { oTd = oTd.previousSibling; pos++; } //删除多列 for (var i = 0; i < total; i++) { //采用一次删除一列的机制 for (var j = 0; j < colCount; j++) { if (tbData.rows[areaTotal.rightBottomPoint_Y - i].childNodes[j].nodeName == "Pnet") { var oTemp = tbData.rows[areaTotal.rightBottomPoint_Y - i].childNodes[j]; var oTdIndexY = areaTotal.leftTopPoint_Y; while (oTemp.nodeName.toLowerCase() != "td") { oTemp = tbData.rows[oTdIndexY].childNodes[j]; oTdIndexY -= 1; } var total = oTemp.colSpan; if (oTemp.rowSpan > 1) { oTemp.rowSpan -= 1; j += total - 1; } } } tbData.deleteRow(areaTotal.rightBottomPoint_Y - i); } var rowCount = tbLeftHead.rows.length - 1; for (var i = indexY; i < rowCount; i++) { tbLeftHead.rows[i].cells[0].style.height = tbLeftHead.rows[i + 1].cells[0].style.height } //删除操作完成后初始化文本框和边框线条 divWestLine.style.display = divNorthLine.style.display = divEastLine.style.display = divSouthLine.style.display = txtEdit.style.display = "none"; indexX = indexY = endX = endY = -1; for (var i = 0; i < total; i++) { //"-1"将删除tbLeftHead表最后一行记录,删除左边行的最后一个标号 tbLeftHead.deleteRow(-1); } //重新设置id ResetId(); } //删除列 //包括同时选中多列的情况 function DelCol() { if (indexX == -1) { alert("您当前还没有选择单元格"); return; } var areaTotal = getSelectedObject(); var total = areaTotal.rightBottomPoint_X - areaTotal.leftTopPoint_X + 1; var rowCount = tbData.rows.length; var pos = -1; var oTd = tbData.rows[indexY].cells[areaTotal.leftTopPoint_X]; while (oTd != null) { oTd = oTd.previousSibling; pos++; } //同时删除多列 for (var j = 0; j < total; j++) { //采用一次删除一行的单删机制 for (var i = 0; i < rowCount; i++) { //如果出现已经剔除的单元格 if (tbData.rows[i].childNodes[pos].nodeName == "Pnet") { var oTemp = tbData.rows[i].childNodes[pos]; //遍历兄弟节点,寻找单元格 while (oTemp.nodeName.toLowerCase() != "td") { oTemp = oTemp.previousSibling; } var oRowTotal = oTemp.rowSpan; if (oRowTotal > 1) { oTemp.colSpan -= 1; } //删除跨行框内的Pnet标签 for (var k = 0; k < oRowTotal; k++) { tbData.rows[i + k].childNodes[pos].removeNode(true); } i += oRowTotal - 1; } //如果出现跨列的情况 else if (tbData.rows[i].childNodes[pos].colSpan > 1) { var oTemp = tbData.rows[i].childNodes[pos]; oTemp.colSpan -= 1; oTemp.nextSibling.replaceNode(oTemp.cloneNode(true)); oTemp.removeNode(true); } //如果出现跨行的情况 else if (tbData.rows[i].childNodes[pos].rowSpan > 1) { var oTemp = tbData.rows[i].childNodes[pos]; var oRowTotal = oTemp.rowSpan; for (var k = 0; k < oRowTotal; k++) { tbData.rows[i + k].childNodes[pos].removeNode(true); } i += oRowTotal - 1; } else { tbData.rows[i].childNodes[pos].removeNode(true); } } } //改变列的头字号标签 var colCount = tbTopHead.rows[0].cells.length - 1; for (var i = 0; i < total; i++) { tbTopHead.rows[0].deleteCell(colCount); tbData.firstChild.childNodes[indexX].removeNode(true); colCount = tbTopHead.rows[0].cells.length - 1; } for (var i = indexX; i < colCount; i++) { tbTopHead.rows[0].cells[i].style.width = tbData.firstChild.childNodes[i].style.width; } //删除操作完成后初始化文本框和边框线条 divWestLine.style.display = divNorthLine.style.display = divEastLine.style.display = divSouthLine.style.display = txtEdit.style.display = "none"; indexX = indexY = endX = endY = -1; //重新设置id ResetId(); } //调整整个显示区域界面的大小 function AdjustSize() { try { divMain.style.width = document.body.offsetWidth - parseInt(tbLeftHead.style.width == "" ? 0 : tbLeftHead.style.width) - 40; divTopHead.style.width = document.body.offsetWidth - parseInt(tbLeftHead.style.width == "" ? 0 : tbLeftHead.style.width) - 60; divLeftHead.style.height = divMain.offsetHeight - 20; splitLine.style.width = document.body.offsetWidth; MathBar.style.width = document.body.offsetWidth - 15; } catch (e) { } } //合并单元格 function UniteCells() { var oSelected = getSelectedObject(); if (oSelected == null) { alert("您当前还没有选择单元格"); return; } //选中区域只有一个单元格时,不做任何操作 if (indexX == endX && indexY == endY) { return; } var colsCount = oSelected.rightBottomPoint_X - oSelected.leftTopPoint_X + 1; var rowsCount = oSelected.rightBottomPoint_Y - oSelected.leftTopPoint_Y + 1; var oTable = document.getElementById("tbData"); //判断是否同时存在多个内容框 var textTemp = ""; for (var i = 0; i < rowsCount; i++) { for (var j = 0; j < colsCount; j++) { var objTd = oTable.rows[oSelected.leftTopPoint_Y + i].childNodes[oSelected.leftTopPoint_X + j]; //判断是否选中了带有pent标签或者跨行跨列的节点 if (objTd.nodeName == "Pnet" || objTd.rowSpan > 1 || objTd.colSpan > 1) { alert("您选择的区域内已经存在合并区域,无法合并..."); return; } //判断事都同时存在超过一个文本节点 if (objTd.innerText.length > 0) { if (textTemp.length > 0) { alert("您选择的区域内存在多个文字框,无法合并..."); return; } else { textTemp = objTd.innerText; } } } } var oCell = oTable.rows[indexY].childNodes[indexX].cloneNode(true); oCell.colSpan = colsCount; oCell.rowSpan = rowsCount; oCell.innerText = textTemp; //单独处理选区左上角所在行 var oTemp = oTable.rows[oSelected.leftTopPoint_Y].childNodes(oSelected.leftTopPoint_X); var leftStep = -1; while (oTemp != null) { leftStep++; oTemp = oTemp.previousSibling; } //用pnet标签替换td标签 for (var i = 1; i < colsCount; i++) { oTable.rows[oSelected.leftTopPoint_Y].childNodes[leftStep + i].replaceNode(document.createElement ("<Pnet/>")); } for (var i = 1; i < rowsCount; i++) { for (var j = 0; j < colsCount; j++) { oTable.rows[oSelected.leftTopPoint_Y + i].childNodes[leftStep + j].replaceNode(document.createElement ("<Pnet/>")); } } if (oSelected.leftTopPoint_X == 0) { oTable.rows[oSelected.leftTopPoint_Y].firstChild.replaceNode(oCell); } else { oTable.rows[oSelected.leftTopPoint_Y].childNodes[oSelected.leftTopPoint_X].replaceNode(oCell); } endX = indexX = oSelected.leftTopPoint_X; endY = indexY = oSelected.leftTopPoint_Y; //重新设置id ResetId(); } //拆分单元格 function SplitCells() { if (indexX > -1 && (indexX == endX) && (indexY == endY)) { var oTable = document.getElementById("tbData"); var oTd = oTable.rows[indexY].childNodes[indexX]; //获得节点对象 //统计节点的跨行跨列情况 var rowsCount = oTd.rowSpan; var colsCount = oTd.colSpan; var oTemp = oTable.rows[indexY].childNodes[indexX]; oTemp.colSpan = 1; oTemp.rowSpan = 1; var leftStep = -1; while (oTemp != null) { leftStep++; oTemp = oTemp.previousSibling; } //操作首行 for (var i = 1; i < colsCount; i++) { oTable.rows[indexY].childNodes[leftStep + i].replaceNode(document.createElement("<td/>")); } //用td标签替换pent标签 for (var i = 1; i < rowsCount; i++) { for (var j = 0; j < colsCount; j++) { oTable.rows[indexY + i].childNodes[leftStep + j].replaceNode(document.createElement("<td/>")); } } endX = indexX + colsCount - 1; endY = indexY + rowsCount - 1; SetTextFrame(indexX, indexY, endX, endY); //重新设置id ResetId(); } else { alert("您选择的单元格不具备取消合并的条件"); } } //返回选中去对象的一个集合 //返回参数说明: //leftTopPoint_X为左上角坐标X坐标索引 //leftTopPoint_Y为左上角坐标Y坐标索引 //rightBottomPoing_X为右下角X坐标索引 //rightBottomPoint_Y为右下角Y坐标索引 function getSelectedObject() { //没有选择区域时,返回空。 if (divWestLine.style.display == "none") { return null; } var lx, ly, rx, ry; if (indexX > endX) { lx = endX; rx = indexX; } else { lx = indexX; rx = endX; } if (indexY > endY) { ly = endY; ry = indexY; } else { ly = indexY; ry = endY; } return { leftTopPoint_X: lx, leftTopPoint_Y: ly, rightBottomPoint_X: rx, rightBottomPoint_Y: ry } } //选择一列 function SelectCol(event) { var r = event.srcElement.cellIndex; endX = indexX = r; indexY = 0; endY = document.getElementById("tbData").rows.length - 1; SetTextFrame(indexX, indexY, endX, endY); } //选择一行 function SelectRow(event) { var r = event.srcElement.parentNode.rowIndex; indexX = 0; endY = indexY = r; endX = document.getElementById("tbData").rows[r].cells.length - 1; SetTextFrame(indexX, indexY, endX, endY); } //重新设置单元格的id属性 function ResetId() { var colsCount = document.getElementById("tbTopHead").rows[0].cells.length; var rowsCount = document.getElementById("tbLeftHead").rows.length; var oTable = document.getElementById("tbData"); for (var i = 0; i < rowsCount; i++) { for (var j = 0; j < colsCount; j++) { if (oTable.rows[i].childNodes[j].nodeName != "Pnet") { oTable.rows[i].childNodes[j].setAttribute("id", String.fromCharCode(j + 65) + (i + 1)); } } } } //同步滚动条动作 function scrollHead() { document.getElementById("divTopHead").scrollLeft = event.srcElement.scrollLeft; document.getElementById("divLeftHead").scrollTop = event.srcElement.scrollTop; SetTextFrame(indexX, indexY, endX, endY); } </script> </html>