html中补齐table表格合并导致每行td数量不一致的情况

有一个行列合并的表格如下:

|----|-----|-----|-----|
| 华东 | 100 | 120 | 正常 |
| 华东 | 80 | 90 | 正常 |
| 华北 | 150 | 180 | 良好 |
| 合计 || 330 | 390 |

可以看到表格中每行和每列最多有4个td,实际的html源文件中:

第一行有4个td,第二行只有2个td,第三行4个td,第4行3个td,我需要为每一行或者列增加一些隐藏的td,使每一行的td数量一致,修改前的源文件如下:

html 复制代码
<!DOCTYPE html>                                                                                                                                                                                                              
  <html lang="zh-CN">                                                                                                                                                                                                          
  <head>                                                                                                                                                                                                                       
      <meta charset="UTF-8">
      <title></title>                                                                                                                                                                                              
      <style>     
          table {
              border-collapse: collapse;
              width: 100%;
              max-width: 600px;
          }
          td {
              border: 1px solid #333;
              padding: 10px;
              text-align: center;
          }
      </style>
  </head>
  <body>

  <table>
      <tr>
          <td rowspan="2">华东</td>
          <td>100</td>
          <td>120</td>
          <td rowspan="2">正常</td>
      </tr>
      <tr>
          <td>80</td>
          <td>90</td>
      </tr>
      <tr>
          <td>华北</td>
          <td>150</td>
          <td>180</td>
          <td>良好</td>
      </tr>
      <tr>
          <td colspan="2">合计</td>
          <td>330</td>
          <td>390</td>
      </tr>
  </table>

  </body>
  </html>

思路是读取源文件中td的colspan和rowspan属性,在td后面增加若干个带有display:none的td:

java 复制代码
import com.zhou.util.NumberUtil;
import com.zhou.common.model.Point;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.*;

/**
 * 表格数据读取转换工具类
 * @author lang.zhou
 * @since  2022/7/25 10:17
 */
@Slf4j
public class TableUtil {






    /**
     * 补齐合并导致每行td数量不一致的情况
     * 添加隐藏td用于占位,降低程序处理逻辑的复杂性
     * @return 返回与某个单元格合并行或列的其他单元格坐标集合
     */
    @SneakyThrows
    public static Map<Point,Set<Point>> fixedTd(Element element){
        int colSize = TableUtil.getColSize(element);
        //读取td的style提供给前端
        Map<Integer, String> tdStyle = new HashMap<>();

        Elements rows = element.select("tr");
        Map<Point,Set<Point>> sameCells = new HashMap<>();

        for (int i = 0; i < rows.size(); i++) {
            Element row = rows.get(i);
            lineY(rows, row, colSize,i,colSize, tdStyle,sameCells);
        }
        return sameCells;
    }

    private static void cellX(Elements rows, Element td, int colSize, int rowIndex, int colIndex, Map<Integer, String> tdStyle, Map<Point,Set<Point>> sameCells){
        Integer rowSpan = NumberUtil.safeToInteger(td.attr("rowspan"), 1);
        Point point = new Point(rowIndex, colIndex);
        Set<Point> points = sameCells.computeIfAbsent(point, l -> new LinkedHashSet<>());
        if(rowSpan > 1){
            for (int k = 1; k < rowSpan; k++) {
                String style = tdStyle.getOrDefault(colIndex + k,"");
                Element nextRow = rows.get(rowIndex + k);
                lineY(rows,nextRow,colSize,rowIndex + k,colIndex,tdStyle,sameCells);
                Element e = new Element("td").attr("style", style + ";display:none");
                e.appendElement("p");
                nextRow.insertChildren(colIndex , e);
                points.add(new Point(rowIndex + k, colIndex));
            }
        }
    }

    private static void lineY(Elements rows,Element row, int colSize, int rowIndex, int to, Map<Integer, String> tdStyle, Map<Point,Set<Point>> sameCells){
        for (int i = 0; i < to; i++) {
            Elements select = row.select("td");
            if (i < select.size()) {
                Element td = select.get(i);
                Point point = new Point(rowIndex, i);
                if(sameCells.containsKey(point)){
                    continue;
                }
                sameCells.computeIfAbsent(point, l -> new LinkedHashSet<>());
                i += cellY(rows,td,colSize,rowIndex,i,tdStyle,sameCells);
            }
        }
    }
    private static int cellY(Elements rows, Element td, int colSize, int rowIndex, int colIndex, Map<Integer, String> tdStyle, Map<Point,Set<Point>> sameCells){
        Integer colSpan = NumberUtil.safeToInteger(td.attr("colspan"), 1);
        Integer rowSpan = NumberUtil.safeToInteger(td.attr("rowspan"), 1);
        String style = tdStyle.get(colIndex);
        Point point = new Point(rowIndex,colIndex);
        Set<Point> pointSet = sameCells.computeIfAbsent(point, l -> new LinkedHashSet<>());
        for (int m = 1; m < colSpan; m++) {
            pointSet.add(new Point(rowIndex,colIndex + m));
            Element e = new Element("td").attr("style", style + ";display:none");
            e.appendElement("p");
            td.after(e);
        }
        for (int n = 0; n < rowSpan; n++) {
            Element row = rows.get(rowIndex + n);
            Elements tds = row.select("td");
            Element nd = tds.get(colIndex);
            cellX(rows,nd,colSize,rowIndex + n,colIndex,tdStyle,sameCells);
        }
        return colSpan - 1;
    }

    /**
     * 得到表格最大列数(考虑合并列)
     */
    public static int getColSize(Element table){
        Element row = table.select("tr").first();
        int cnt = 0;
        Elements cols = row.select("td");
        for (int j = 0; j < cols.size(); j ++) {
            Element td = row.select("td").get(j);
            Integer colSpan = NumberUtil.safeToInteger(td.attr("colspan"), 1);
            cnt += colSpan;
        }
        return cnt;
    }

}

补齐隐藏td后的table源文件如下:

html 复制代码
  <table>
      <tr>
          <td rowspan="2">华东</td>
          <td>100</td>
          <td>120</td>
          <td rowspan="2">正常</td>
      </tr>
      <tr>
          <td style="display: none"></td>
          <td>80</td>
          <td>90</td>
          <td style="display: none"></td>
      </tr>
      <tr>
          <td>华北</td>
          <td>150</td>
          <td>180</td>
          <td>良好</td>
      </tr>
      <tr>
          <td colspan="2">合计</td>
          <td style="display: none"></td>
          <td>330</td>
          <td>390</td>
      </tr>
  </table>
相关推荐
Csvn8 小时前
OpenSpec 详细使用教程
前端
之歆9 小时前
Day19_LESS 完全指南——从入门到工程实践
前端·css·less
云水一下9 小时前
HTML5 从入门到精通:实战收官——从零搭建完整静态网站,综合运用所有知识
前端·html5
不总是10 小时前
Windows 系统 Node.js 免安装版(zip)安装与配置教程(2026 最新)
前端·windows·node.js
冬奇Lab10 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
zhangyao94033011 小时前
开发pc端时,表格的高度怎么设置才能铺满页面
前端·javascript·elementui
kjs--11 小时前
浏览器书签执行脚本
前端
之歆11 小时前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化
沄媪11 小时前
CSRF 跨站请求伪造
前端·ctf·csrf
kyriewen12 小时前
我关掉了Copilot:因为我写的代码出现在了别人的建议里
前端·javascript·ai编程