用html的table来布局,定制html模板,调用pd4ml生成要打印的pdf,为了方便添加了一个合并拆分单元格的方法,合并单元格来源于网络,但是有问题自己进行了修改。

网上合并单元格源码如下:

<table border="1"><script>var s = '';for (var i = 0; i < 10; i++) {s += '<tr>';for (var j = 0; j < 10; j++) {s += '<td>' + i + '-' + j + '</td>';}s += '</tr>';}document.write(s);</script>
</table><script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"></script>
<script>//需要的样式document.write('<style>.cannotselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-khtml-user-select:none;user-select:none;}td.selected{background:#0094ff;color:#fff}</style>');//jQuery表格单元格合并插件,功能和excel单元格合并功能一样,并且可以保留合并后的所有单元格内容到第一个单元格中$.fn.tableMergeCells = function () {//***请保留原作者相关信息//***power by showbo,http://www.w3dev.cnreturn this.each(function () {var tb = $(this), startTD, endTD, MMRC = { startRowIndex: -1, endRowIndex: -1, startCellIndex: -1, endCellIndex: -1 };//初始化所有单元格的行列下标内容并存储到dom对象中tb.find('tr').each(function (r) { $('td', this).each(function (c) { $(this).data('rc', { r: r, c: c }); });});//添加表格禁止选择样式和事件tb.addClass('cannotselect').bind('selectstart', function () { return false });//选中单元格处理函数function addSelectedClass() {var selected = false,  rc,t;tb.find('td').each(function () {rc = $(this).data('rc');//判断单元格左上坐标是否在鼠标按下和移动到的单元格行列区间内selected = rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex;if (!selected && rc.maxc) {//合并过的单元格,判断另外3(左下,右上,右下)个角的行列是否在区域内             selected =(rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex) ||//左下(rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex) ||//右上(rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex);//右下}if (selected)  this.className = 'selected';});var rangeChange = false;tb.find('td.selected').each(function () { //从已选中单元格中更新行列的开始结束下标rc = $(this).data('rc');t = MMRC.startRowIndex;MMRC.startRowIndex = Math.min(MMRC.startRowIndex, rc.r);rangeChange = rangeChange || MMRC.startRowIndex != t;t = MMRC.endRowIndex;MMRC.endRowIndex = Math.max(MMRC.endRowIndex, rc.maxr || rc.r);rangeChange = rangeChange || MMRC.endRowIndex != t;t = MMRC.startCellIndex;MMRC.startCellIndex = Math.min(MMRC.startCellIndex, rc.c);rangeChange = rangeChange || MMRC.startCellIndex != t;t = MMRC.endCellIndex;MMRC.endCellIndex = Math.max(MMRC.endCellIndex, rc.maxc || rc.c);rangeChange = rangeChange || MMRC.endCellIndex != t;});//注意这里如果用代码选中过合并的单元格需要重新执行选中操作if (rangeChange) addSelectedClass();}function onMousemove(e) {//鼠标在表格单元格内移动事件e = e || window.event;var o = e.srcElement || e.target;if (o.tagName == 'TD') {endTD = o;var sRC = $(startTD).data('rc'), eRC = $(endTD).data('rc'), rc;MMRC.startRowIndex = Math.min(sRC.r, eRC.r);MMRC.startCellIndex = Math.min(sRC.c, eRC.c);MMRC.endRowIndex = Math.max(sRC.r, eRC.r);MMRC.endCellIndex = Math.max(sRC.c, eRC.c);tb.find('td').removeClass('selected');addSelectedClass();}}function onMouseup(e) {//鼠标弹起事件tb.unbind({ mouseup: onMouseup, mousemove: onMousemove });if (startTD && endTD && startTD != endTD && confirm('确认合并?!')) {//开始结束td不相同确认合并var tds = tb.find('td.selected'), firstTD = tds.eq(0), index = -1, t, addBR, html = tds.filter(':gt(0)').map(function () {t = this.parentNode.rowIndex;addBR = index != -1 && index != t;index = t;return (addBR ? '<br>' : '') + this.innerHTML}).get().join(',');tds.filter(':gt(0)').remove(); firstTD.append(',' + html.replace(/,(<br>)/g, '$1'));//更新合并的第一个单元格的缓存rc数据为所跨列和行var rc = firstTD.attr({ colspan: MMRC.endCellIndex - MMRC.startCellIndex + 1, rowspan: MMRC.endRowIndex - MMRC.startRowIndex + 1 }).data('rc');rc.maxc = rc.c + MMRC.endCellIndex - MMRC.startCellIndex; rc.maxr = rc.r + MMRC.endRowIndex - MMRC.startRowIndex;console.info(rc.maxc);console.info(rc.maxr);firstTD.data('rc', rc);}tb.find('td').removeClass('selected');startTD = endTD = null;}function onMousedown(e) {var o = e.target;if (o.tagName == 'TD') {startTD = o;tb.bind({ mouseup: onMouseup, mousemove: onMousemove });}}tb.mousedown(onMousedown);});};$('table').tableMergeCells();
</script>

他在初始化所有单元格的行列下标内容并存储到dom对象中是有问题的,他没有考虑到表格已存在跨行跨列的问题。

修改初始化表格下标的方法如下:

//给表格单元格标记索引function setTdIndex($table) {var $trs = $table.find("tr");//总行数var all_row = $trs.length;//总列数var all_col = 0;$trs.eq(0).children().each(function() {all_col += parseInt($(this).attr("colspan")) || 1;});//单元格索引数组,用于标记单元格对应的索引是否被占用var tdsIndex = [];for (var i = 0; i < all_row; i++) {tdsIndex[i] = new Array();for (var j = 0; j < all_col; j++) {tdsIndex[i][j] = 0;}}//单元格索引站位,为了获取当前行下一个单元格索引位置function tdsIndex_zw(i, j, colspan, rowspan) {for (var a = i; a < i + colspan; a++) {for (var b = j; b < j + rowspan; b++) {tdsIndex[b][a] = 1;}}}//获取第n行下一个单元格的索引function getTdIndex(n) {for (var i = 0; i < all_col; i++) {if (tdsIndex[n][i] == 0) {return i;continue;}}}$trs.each(function(i) {$(this).children().each(function(j) {//td的索引,即td的x坐标var x = getTdIndex(i); var rc = {r: i, c: x };$(this).data('rc', rc);var td_colspan = parseInt($(this).attr("colspan") || 1);var td_rowspan = parseInt($(this).attr("rowspan") || 1);//在对象位置数组中站位tdsIndex_zw(x, i, td_colspan, td_rowspan); //设置跨行跨列信息(单元格合并信息)if(td_rowspan >1){rc.maxr = i + td_rowspan -1;}if(td_colspan >1){rc.maxc = x + td_colspan -1;}});});}

修改后拆分单元格代码如下:

<script type="text/javascript">//给表格单元格标记索引function setTdIndex($table) {var $trs = $table.find("tr");//总行数var all_row = $trs.length;//总列数var all_col = 0;$trs.eq(0).children().each(function() {all_col += parseInt($(this).attr("colspan")) || 1;});//单元格索引数组,用于标记单元格对应的索引是否被占用var tdsIndex = [];for (var i = 0; i < all_row; i++) {tdsIndex[i] = new Array();for (var j = 0; j < all_col; j++) {tdsIndex[i][j] = 0;}}//单元格索引站位,为了获取当前行下一个单元格索引位置function tdsIndex_zw(i, j, colspan, rowspan) {for (var a = i; a < i + colspan; a++) {for (var b = j; b < j + rowspan; b++) {tdsIndex[b][a] = 1;}}}//获取第n行下一个单元格的索引function getTdIndex(n) {for (var i = 0; i < all_col; i++) {if (tdsIndex[n][i] == 0) {return i;continue;}}}$trs.each(function(i) {$(this).children().each(function(j) {//td的索引,即td的x坐标var x = getTdIndex(i); var rc = {r: i, c: x };$(this).data('rc', rc);var td_colspan = parseInt($(this).attr("colspan") || 1);var td_rowspan = parseInt($(this).attr("rowspan") || 1);//在对象位置数组中站位tdsIndex_zw(x, i, td_colspan, td_rowspan); //设置跨行跨列信息(单元格合并信息)if(td_rowspan >1){rc.maxr = i + td_rowspan -1;}if(td_colspan >1){rc.maxc = x + td_colspan -1;}});});}//需要的样式document.write('<style>.cannotselect{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;-khtml-user-select:none;user-select:none;}td.selected{background:#0094ff;color:#fff}</style>');//jQuery表格单元格合并插件,功能和excel单元格合并功能一样,并且可以保留合并后的所有单元格内容到第一个单元格中$.fn.tableMergeCells = function () {//***请保留原作者相关信息//***power by showbo,http://www.w3dev.cnreturn this.each(function () {var tb = $(this), startTD, endTD, MMRC = { startRowIndex: -1, endRowIndex: -1, startCellIndex: -1, endCellIndex: -1 };//初始化所有单元格的行列下标内容并存储到dom对象中/* tb.find('tr').each(function (r) { $('td', this).each(function (c) { $(this).data('rc', { r: r, c: c }); console.info($(this).data('rc'));});  }); */setTdIndex(tb);//添加表格禁止选择样式和事件tb.addClass('cannotselect').bind('selectstart', function () { return false });//选中单元格处理函数function addSelectedClass() {var selected = false,  rc,t;tb.find('td').each(function () {rc = $(this).data('rc');//判断单元格左上坐标是否在鼠标按下和移动到的单元格行列区间内selected = rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex;if (!selected && rc.maxc) {//合并过的单元格,判断另外3(左下,右上,右下)个角的行列是否在区域内             selected =(rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.c >= MMRC.startCellIndex && rc.c <= MMRC.endCellIndex) ||//左下(rc.r >= MMRC.startRowIndex && rc.r <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex) ||//右上(rc.maxr >= MMRC.startRowIndex && rc.maxr <= MMRC.endRowIndex && rc.maxc >= MMRC.startCellIndex && rc.maxc <= MMRC.endCellIndex);//右下}if (selected)  this.className = 'selected';});var rangeChange = false;tb.find('td.selected').each(function () { //从已选中单元格中更新行列的开始结束下标rc = $(this).data('rc');t = MMRC.startRowIndex;MMRC.startRowIndex = Math.min(MMRC.startRowIndex, rc.r);rangeChange = rangeChange || MMRC.startRowIndex != t;t = MMRC.endRowIndex;MMRC.endRowIndex = Math.max(MMRC.endRowIndex, rc.maxr || rc.r);rangeChange = rangeChange || MMRC.endRowIndex != t;t = MMRC.startCellIndex;MMRC.startCellIndex = Math.min(MMRC.startCellIndex, rc.c);rangeChange = rangeChange || MMRC.startCellIndex != t;t = MMRC.endCellIndex;MMRC.endCellIndex = Math.max(MMRC.endCellIndex, rc.maxc || rc.c);rangeChange = rangeChange || MMRC.endCellIndex != t;});//注意这里如果用代码选中过合并的单元格需要重新执行选中操作if (rangeChange) addSelectedClass();}function onMousemove(e) {//鼠标在表格单元格内移动事件e = e || window.event;var o = e.srcElement || e.target;if (o.tagName == 'TD') {endTD = o;var sRC = $(startTD).data('rc'), eRC = $(endTD).data('rc'), rc;MMRC.startRowIndex = Math.min(sRC.r, eRC.r);MMRC.startCellIndex = Math.min(sRC.c, eRC.c);MMRC.endRowIndex = Math.max(sRC.r, eRC.r);MMRC.endCellIndex = Math.max(sRC.c, eRC.c);tb.find('td').removeClass('selected');addSelectedClass();}}function onMouseup(e) {//鼠标弹起事件tb.unbind({ mouseup: onMouseup, mousemove: onMousemove });}function hbdyg(){//合并单元格if (startTD && endTD && startTD != endTD) {//开始结束td不相同确认合并var tds = tb.find('td.selected'), firstTD = tds.eq(0), index = -1, t, addBR, html = tds.filter(':gt(0)').map(function () {t = this.parentNode.rowIndex;addBR = index != -1 && index != t;index = t;return (addBR ? '<br>' : '') + this.innerHTML;}).get().join(',');tds.filter(':gt(0)').remove(); //firstTD.append(',' + html.replace(/,(<br>)/g, '$1'));//更新合并的第一个单元格的缓存rc数据为所跨列和行//console.log(firstTD.data('rc'));var rc = firstTD.attr({ colspan: MMRC.endCellIndex - MMRC.startCellIndex + 1, rowspan: MMRC.endRowIndex - MMRC.startRowIndex + 1 }).data('rc');rc.maxc = rc.c + MMRC.endCellIndex - MMRC.startCellIndex; rc.maxr = rc.r + MMRC.endRowIndex - MMRC.startRowIndex;firstTD.data('rc', rc);//alert("合并完成!");}//清除多选qcdx();}function qcdx(){//清除多选tb.find('td').removeClass('selected');startTD = endTD = null;}tb.on("hbdyg",hbdyg);tb.on("qcdx",qcdx);function onMousedown(e) {//鼠标按下事件var o = e.target;if (o.tagName == 'TD') {startTD = o;tb.bind({ mouseup: onMouseup, mousemove: onMousemove });}return false;}tb.mousedown(onMousedown);});};</script>

调用合并的方法如下:

var selectTdTables = $('#dm_view table').tableMergeCells();//合并单元格
function mm_hbdyg(){selectTdTables.each(function () {$(this).trigger("hbdyg");});
}

拆分单元格代码如下:

//拆分单元格
function mm_cfdyg(select_dom_id){var $td = $("#"+select_dom_id);//当前选中的tdvar $tb = $td.parents('table:first');//td所在的tablevar $trs = $tb.find("tr");//table下所有的行var rc = $td.data("rc");//单元格下标信息//console.info(rc);var rowIndex = rc.r;var colIndex = rc.c;var td_rowspan = parseInt($td.attr("rowspan") || 1);var td_colspan = parseInt($td.attr("colspan") || 1);if(td_rowspan == 1 && td_colspan == 1){return;}for(var i=rowIndex;i<rowIndex + td_rowspan;i++){//循环行$trs.eq(i).children().each(function(n){//循环单元格var td_rc = $(this).data("rc");//单元格下标if(td_rc.c >= colIndex){//当前td索引(下标)大于或等于合并单元格的索引时,取前一个td,取不到前一个直接用当前的//上一个单元格var $sygdyg = $(this).prev().length == 0 ? $(this) : $(this).prev();for(var j=colIndex;j<colIndex + td_colspan;j++){var $newTd = $("<td></td>");$sygdyg .after($newTd);} return false;}});}$td.remove();setTdIndex($tb);//删除后需要重新设置td下标
}

点击单元格时取消多选方法:

$("#"+dom_id).parents('table:first').trigger("qcdx");//清除多选

转载于:https://my.oschina.net/u/142987/blog/1486099

jQuery仿excel表格实现单元格拆分合并功能相关推荐

  1. 在Excel表格中如何快速拆分合并单元格

    在Excel表格中如何快速拆分合并单元格 目录 在Excel表格中如何快速拆分合并单元格 1.例如:将销售人列中的合并单元格拆分还原 2.选中销售人姓名,点击[开始]选项卡中[合并居中] 3.再点击[ ...

  2. python处理Excel实现自动化办公教学(数据筛选、公式操作、单元格拆分合并、冻结窗口、图表绘制等)【三】

    相关文章: python处理Excel实现自动化办公教学(含实战)[一] python处理Excel实现自动化办公教学(含实战)[二] python处理Excel实现自动化办公教学(数据筛选.公式操作 ...

  3. excel表格中单元格里面有个斜杠怎么写字?

    在使用excel时可能会遇到表头区域单元格中有条斜杠,这种表格要怎么写字呢?下面小编就给大家带来excel表格中单元格里面有个斜杠要如何写字的教程. excel表格中单元格里面有个斜杠怎么写字? 1. ...

  4. EXCEL表格中单元格的左上角的绿颜色小三角形怎么添加?怎么消除?

    EXCEL表格中单元格的左上角绿颜色的小三角形: 因为EXCEL有个自动检查错误的功能,出现绿色小三角是在提示用户:这里的单元格和周围的单元格存储的形式不一样,一般周围的是用数据形式存储的而带上绿色小 ...

  5. 如何将Excel多行单元格文字合并到一个单元格中

    如何将Excel多行单元格文字合并到一个单元格中 参考网址:https://jingyan.baidu.com/article/ed15cb1b28042c5ae369819f.html 1.打开需要 ...

  6. table表格中单元格的合并

    目录 table表格中单元格的合并 table表格中单元格的合并很多朋友不一定了解,今天我就写一篇博客来跟大家分享一下table表格中的跨行合并和跨列合并. 我们先看一个合并过的表格,大家可以先思考一 ...

  7. Excel VBA中单元格的合并与拆分

    对于合并单元格这里提供"从上到下"和"从下到上"合并单元格两种方式,"从上到下"的方法需要记录当前列有多少个相同的单元格和判断相应的单元格是 ...

  8. 计算机删除等级列在哪里,插入与删除Excel表格的单元格、行和列

    您可以在Excel工作表中活动单元格的上方或左侧插入空白单元格,同时将同一列中的其他单元格下移或将同一行中的其他单元格右移.同样,您可以在一行的上方插入多行和在一列的左边插入多列.您还可以删除单元格. ...

  9. 设置单元格填充方式_【WPS神技能】Excel表格中单元格内的双色填充效果有点意思!...

    在Excel表格中做数据报表时,如果有需要重点突出的单元格数据,简单的操作自然是选中相关单元格,在"开始"菜单栏中找到"填充颜色",选择自己想要的颜色即可,如下 ...

最新文章

  1. Pytorch Bi-LSTM + CRF 代码详解
  2. 1107 Social Clusters
  3. 2018-3-7 Hadoop简介1(名字的由来,以及基本的结构)
  4. 人脸识别损失函数综述(附开源地址)
  5. 使用多态来实现数据库之间的切换
  6. sessionState 配置方案
  7. git学习(6):删除github镜像
  8. Dev Express Report 学习总结(五)在分组中使用聚集表达式AggregateExpression
  9. ssm整合spring,springmvc,mybatis-day12
  10. ESP32-IDF给FATFS添加长文件名支持,更改_USE_LFN以支持大于8.3格式的文件名
  11. 程序设计竞赛(ACM)与认证(CCF)的概念集(百度百科)
  12. 13.0.高等数学3-空间曲线
  13. linux没有cpufreq目录,【原创】Linux cpufreq framework
  14. 计算机网络微课堂笔记
  15. 行人轨迹论文阅读SSAGCN: Social Soft Attention Graph Convolution Network for Pedestrian Trajectory Prediction
  16. PT100高精度测温电路 AD623+REF3030(转)
  17. 简单的给数字加密解密
  18. 上海电影院分布数据接口
  19. hdoj杭电问题分类
  20. Linux驱动开发-proc接口介绍

热门文章

  1. 杭州跨境电商实践成果 亮相联合国贸发会议电子商务周
  2. 自动驾驶系统进阶与项目实战(九)基于行锚框和全局信息的深度学习车道线检测方法
  3. FL Studio21水果编曲高级版本音乐编曲工具
  4. 对P300的一点认知
  5. 一个数被异或两次等于没有异或,原理研究
  6. 写个小爬虫:camera360一拍即传照片直播平台 照片一键下载
  7. 判断IP地址是否在同一个网段
  8. python turtle 画几株草
  9. 实施绩效考核有什么目的和作用?对企业有什么重要性?
  10. python对list中的每个元素进行某种操作_python对list中的每个元素进行某种操作的方法...