html td 的横向与纵向合并,【Javascript】Javascript横向/纵向合并单元格TD

本文讨论了在报表系统中如何通过HTML和JavaScript处理TD单元格的合并,以提高数据展示的清晰度。作者分享了两种方法,一种是在编写HTML时设置单元格合并,另一种是后期使用JavaScript完成合并。文中指出,早期的JavaScript合并方法存在错误,可能导致已合并单元格的处理问题。随后,作者提供了两个改进的方法,分别用于合并相同文本的单元格和按序号合并单元格,并给出了示例代码和应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

> 需求是这样滴(>_

在报表系统中,涉及“HTML的TD单元格的合并”恐怕为数不少。

比如,从DB查得数据并经过后台的整理后,可能是这样的:

Table1

JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO

1

ANALYST

6000

1

7788

SCOTT

ANALYST

7566

4/19/1987

3000.00

20

1

ANALYST

6000

2

7902

FORD

ANALYST

7566

12/3/1981

3000.00

20

2

CLERK

4150

3

7934

MILLER

CLERK

7782

1/23/1982

1300.00

10

2

CLERK

4150

4

7900

JAMES

CLERK

7698

12/3/1981

950.00

30

2

CLERK

4150

5

7369

SMITH

CLERK

7902

12/17/1980

800.00

20

2

CLERK

4150

6

7876

ADAMS

CLERK

7788

5/23/1987

1100.00

20

3

MANAGER

8275

7

7698

BLAKE

MANAGER

7839

5/1/1981

2850.00

30

3

MANAGER

8275

8

7566

JONES

MANAGER

7839

4/2/1981

2975.00

20

3

MANAGER

8275

9

7782

CLARK

MANAGER

7839

6/9/1981

2450.00

10

4

PRESIDENT

5000

10

7839

KING

PRESIDENT

11/17/1981

5000.00

10

5

SALESMAN

5600

11

7844

TURNER

SALESMAN

7698

9/8/1981

1500.00

0.00

30

5

SALESMAN

5600

12

7654

MARTIN

SALESMAN

7698

9/28/1981

1250.00

1400.00

30

5

SALESMAN

5600

13

7521

WARD

SALESMAN

7698

2/22/1981

1250.00

500.00

30

5

SALESMAN

5600

14

7499

ALLEN

SALESMAN

7698

2/20/1981

1600.00

300.00

30

为了让用户更清晰地查看报表,结果可能需要是这样的(各职位的薪水总额及分布明细):

Table2

JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO

1

ANALYST

6000

1

7788

SCOTT

ANALYST

7566

4/19/1987

3000.00

20

2

7902

FORD

ANALYST

7566

12/3/1981

3000.00

20

2

CLERK

4150

3

7934

MILLER

CLERK

7782

1/23/1982

1300.00

10

4

7900

JAMES

CLERK

7698

12/3/1981

950.00

30

5

7369

SMITH

CLERK

7902

12/17/1980

800.00

20

6

7876

ADAMS

CLERK

7788

5/23/1987

1100.00

20

3

MANAGER

8275

7

7698

BLAKE

MANAGER

7839

5/1/1981

2850.00

30

8

7566

JONES

MANAGER

7839

4/2/1981

2975.00

20

9

7782

CLARK

MANAGER

7839

6/9/1981

2450.00

10

4

PRESIDENT

5000

10

7839

KING

PRESIDENT

11/17/1981

5000.00

10

5

SALESMAN

5600

11

7844

TURNER

SALESMAN

7698

9/8/1981

1500.00

0.00

30

12

7654

MARTIN

SALESMAN

7698

9/28/1981

1250.00

1400.00

30

13

7521

WARD

SALESMAN

7698

2/22/1981

1250.00

500.00

30

14

7499

ALLEN

SALESMAN

7698

2/20/1981

1600.00

300.00

30

这就需要我们对单元格进行相应的合并。

一般来说,有两种处理方法,

在编写HTML时已设置单元格的合并;

在编写HTML时未作合并处理,后期由Javascript完成单元格合并工作。

本文讲的是第2种情况。

合并单元格的步骤

比如,我要把上表Table1中数值为ANALYST的两个单元格合并。

JOB

ANALYST

ANALYST

我们首先需要将第二个ANALYST的单元格删除掉

然后设置第一个ANALYST的单元格的rowSpan属性为2(表示“跨越2行”)

> 写得不好的公用方法

之前写了一个公用Javascript方法,用以合并相邻间文本相同的单元格。

这个方法写得不好,有明显的Bug。对已做过合并的Table,这个方法有可能导致合并单元格错误。

主要的原因在于,对于合并过单元格的表格,那么被合并的行就会相应的少一个TD,而此方法依旧按未合并过单元格的情况来获取TD对象。

比如,获取第二列的所有单元格,此程序用“获取全部TR中的第二个TD”来实现,这在未合并过单元格的Table是正确的,但对于合并过单元格的Table,则未必,因为被合并的行相应地少一个单元格。

此处将代码贴出,希望大家引以为鉴。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

functionmergeCell(tableObj, col) {var $tab =$(tableObj);var $trs = $tab.find("tr");varoldval;varfirstTD;var counter = 0;

$trs.each(function(index) {if (!oldval && !firstTD) {

oldval= $(this).find("td:eq(" + col + ")").text();

firstTD= $(this).find("td:eq(" + col + ")").get(0);

counter= 0;

counter++;

}else{if ($(this).find("td:eq(" + col + ")").text() ==oldval) {

$(this).find("td:eq(" + col + ")").remove();

counter++;

}else{

$(firstTD).attr("rowSpan", counter);

oldval= $(this).find("td:eq(" + col + ")").text();

firstTD= $(this).find("td:eq(" + col + ")").get(0);

counter= 0;

counter++;

}

}if (index >= $trs.length - 1) {

$(firstTD).attr("rowSpan", counter);

}

});

}

mergeCell

页面DEMO如下(HTML代码,较长):

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Insert title here

$().ready(function() {

mergeCell($("#list_table").get(0),1);

mergeCell($("#list_table").get(0),2);

});functionmergeCell(tableObj, col) {var$tab=$(tableObj);var$trs=$tab.find("tr");varoldval;varfirstTD;varcounter= 0;

$trs.each(function(index) {if(!oldval&& !firstTD) {

oldval=$(this).find("td:eq(" +col+ ")").text();

firstTD=$(this).find("td:eq(" +col+ ")").get(0);

counter= 0;

counter++;

}else{if($(this).find("td:eq(" +col+ ")").text()==oldval) {

$(this).find("td:eq(" +col+ ")").remove();

counter++;

}else{

$(firstTD).attr("rowSpan", counter);

oldval=$(this).find("td:eq(" +col+ ")").text();

firstTD=$(this).find("td:eq(" +col+ ")").get(0);

counter= 0;

counter++;

}

}if(index>=$trs.length- 1) {

$(firstTD).attr("rowSpan", counter);

}

});

}

   JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO1ANALYST600017788SCOTTANALYST75664/19/19873000.00 201ANALYST600027902FORDANALYST756612/3/19813000.00 202CLERK415037934MILLERCLERK77821/23/19821300.00 102CLERK415047900JAMESCLERK769812/3/1981950.00 302CLERK415057369SMITHCLERK790212/17/1980800.00 202CLERK415067876ADAMSCLERK77885/23/19871100.00 203MANAGER827577698BLAKEMANAGER78395/1/19812850.00 303MANAGER827587566JONESMANAGER78394/2/19812975.00 203MANAGER827597782CLARKMANAGER78396/9/19812450.00 104PRESIDENT5000107839KINGPRESIDENT 11/17/19815000.00 104SUPER PRESIDENT5000107839KINGPRESIDENT 11/17/19815000.00 105SALESMAN5600117844TURNERSALESMAN76989/8/19811500.000.00305SALESMAN5600127654MARTINSALESMAN76989/28/19811250.001400.00305SALESMAN5600137521WARDSALESMAN76982/22/19811250.00500.00305SALESMAN5600147499ALLENSALESMAN76982/20/19811600.00300.0030

WrongMergeTD.html

> 写得不好怎么办?卷土重来呗

于是,重新写了两个公用方法来合并单元格。

一个是合并相邻值相同的单元格;

另外一个是合并指定序号的单元格,比如2-5,6-8,是“合并第2个至第5个单元格、第6个和至第8个单元格”。

这俩方法将“获取需要合并的TD元素”的动作交由方法调用者,只负责对入参单元格作对应的合并。

JS

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/**

* Meger cells with same text

* @param $tds TDs jquery object

* @param type row/col*/

functionmergeCell4SameText($tds, type) {varoldval;varfirstTD;var counter = 0;

$tds.each(function(index) {if (index == 0) {

oldval= $(this).text();

firstTD= $(this).get(0);

counter= 0;

counter++;

}else{if ($(this).text() ==oldval) {

$(this).remove();

counter++;

}else{if (type == 'col') {

$(firstTD).attr("rowSpan", counter);

}else if (type == 'row') {

$(firstTD).attr("colSpan", counter);

}

oldval= $(this).text();

firstTD= $(this).get(0);

counter= 0;

counter++;

}

}if (index >= $tds.length - 1) {if (type == 'col') {

$(firstTD).attr("rowSpan", counter);

}else if (type == 'row') {

$(firstTD).attr("colSpan", counter);

}

}

});

}/**

* Meger cells by the parameters "index"

* @param $tds TDs jquery object

* @param type row/col

* @param index for example, 0-1,2-5,6-8,10-13*/

functionmergeCellByIndex($tds, type, index) {var indexArrs = index.split(',');varfromTo;varfrom;varto;for (var i inindexArrs) {

fromTo=indexArrs[i];

from= new Number(fromTo.split('-')[0]);

to= new Number(fromTo.split('-')[1]);for (var j = 1 + from; j <= to; j++) {

$($tds.get(j)).remove();

}if (type == 'col') {

$($tds.get(from)).attr("rowSpan", to - from + 1);

}else if (type == 'row') {

$($tds.get(from)).attr("colSpan", to - from + 1);

}

}

}

tdmerger

调用的页面(HTML代码,较长):

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

Insert title here

$().ready(function() {

$col1tds=$("table tr td:nth-child(1)");

$col2tds=$("table tr td:nth-child(2)");

$col3tds=$("table tr td:nth-child(3)");

mergeCellByIndex($col1tds,'col','0-1,2-5,6-8,10-13');

mergeCellByIndex($col2tds,'col','0-1,2-5,6-8,10-13');

mergeCellByIndex($col3tds,'col','0-1,2-5,6-8,10-13');/*$row2tds = $("table tr:eq(2) td");

mergeCellByIndex($row2tds, 'row', '6-11');*/});

   JOBTOTAL SALINDEXEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO1ANALYST600017788SCOTTANALYST75664/19/19873000.00 201ANALYST600027902FORDANALYST756612/3/19813000.00 202CLERK415037934MILLERCLERK77821/23/19821300.00 102CLERK415047900JAMESCLERK769812/3/1981950.00 302CLERK415057369SMITHCLERK790212/17/1980800.00 202CLERK415067876ADAMSCLERK77885/23/19871100.00 203MANAGER827577698BLAKEMANAGER78395/1/19812850.00 303MANAGER827587566JONESMANAGER78394/2/19812975.00 203MANAGER827597782CLARKMANAGER78396/9/19812450.00 104PRESIDENT5000107839KINGPRESIDENT 11/17/19815000.00 105SALESMAN5600117844TURNERSALESMAN76989/8/19811500.000.00305SALESMAN5600127654MARTINSALESMAN76989/28/19811250.001400.00305SALESMAN5600137521WARDSALESMAN76982/22/19811250.00500.00305SALESMAN5600147499ALLENSALESMAN76982/20/19811600.00300.0030

mergeTD

对于合并单元格,这两种方式都不太满意,可是,也想不到更好的方法对此操作作封装。

如果童靴有更好的方法,请指点!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值