将excel表格转换为element table(下)

在‘将excel表格转换为element table(上)’我们把excel 转换后通过数据重构绑定到了element table上,现在要做的就是根据源文件进行行列进行合并操作

先看看最终处理的结果
最终效果图

这里在一步步分析实现步骤。

先分析一下合并的逻辑
合并逻辑
大致思路理理如上。

思路有了接下来就是一步步的去实现了

  • 第一步
    首先通过分组的数据找到哪些行有合并操作
      this.existMergeRow = {};
      this.existMergeCol = {};
      this.mergeColAtRow = {};
      const existMergeRow = this.existMergeRow// 合并行行为记录
      const existMergeCol = this.existMergeCol // 合并列行为记录
      const mergeColAtRow = this.mergeColAtRow;// 记录合并列是属于哪一行的
      // 计算出哪些行有合并参与合并行为,因为有的行完全没有合并操作,在table merge操作是需要特殊处理renter {rowspan:1,colspan:1}
      Object.keys(categoryCN).map(key => {
        categoryCN[key].forEach((e) => {
          // 有e.rowspan才执行如下操作
          if (e.rowspan) {
            if (!existMergeRow[key]) { existMergeRow[key] = {} }
            let rowspanNum = parseInt(e.rowspan);
            const rowNum = e.rowNum - 4;// 行数
            existMergeRow[key][rowNum] = true;// 标识他合并了
            let step = 1;
            while (rowspanNum > 1) {
              existMergeRow[key][rowNum + step] = true;// 标识他合并了
              step++;
              rowspanNum -= 1;
            }
          }
})
  • 第二步
    根据分组数据找到哪些列有合并操作,我们直接找上面的方法中添加如下代码来记录有合并操作的列
          if (e.colspan) {
            const keynum = parseInt(key) - 1
            const rowNumm = e.rowNum - 4;
            const colNum = e.colNum;// 列数
            // 行号:列号
            if (!mergeColAtRow[rowNumm]) { mergeColAtRow[rowNumm] = {} }
            mergeColAtRow[rowNumm][colNum] = true;


            if (!existMergeCol[keynum]) { existMergeCol[keynum] = {} }
            let colspanNum = parseInt(e.colspan);

            existMergeCol[keynum][colNum] = true;// 标识他合并了
            let colstep = 1;
            while (colspanNum > 1) {
              existMergeCol[keynum][colNum + colstep] = true;// 标识他合并了
              mergeColAtRow[rowNumm][colNum + colstep] = true;
              colstep++;
              colspanNum -= 1;
            }
          }

  • 第三步
    拷贝objectSpanMethod 来进行合并操作,大致如下
    objectSpanMethod ({ rowIndex, columnIndex }) {
      // 需要合并的列
      const mergeRow = this.categoryCN[columnIndex];
      // 合并列先找到那一例属于哪一行
      const mergeColAtRow = this.mergeColAtRow[rowIndex];
      // 通过列index 获取这一列,哪些行有合并行为
      const existMergeRow = this.existMergeRow[columnIndex]
      const existMergeCol = this.existMergeCol[columnIndex]
      if (mergeRow) {
        let rowspanObj = mergeRow.find((ee, index) => (ee.rowNum - 4) == rowIndex)
        // 第一列
        if (columnIndex == 0) {

          // 判断改行是否参与合并行为
          if (existMergeRow[rowIndex]) {
            if (rowspanObj) {
              const _row = rowspanObj.rowspan
              const _col = rowspanObj.colspan
              return {
                rowspan: _row ? _row : _col ? 1 : 0,
                colspan: _col ? _col : _row ? 1 : 0
              }
            } else {
              return {
                rowspan: 0,
                colspan: 0
              }
            }
          }
        } else {  // 其它列,合并操作
          // 有行合并也有列合并
          if (existMergeRow && existMergeRow[rowIndex] && existMergeCol && existMergeCol[columnIndex]) {
            if (rowspanObj) {
              const _row = rowspanObj.rowspan
              const _col = rowspanObj.colspan
              return {
                rowspan: _row ? _row : _col ? 1 : 0,
                colspan: _col ? _col : _row ? 1 : 0
              }
            } else {
              return {
                rowspan: 0,
                colspan: 0
              }
            }
          } else if (existMergeRow && existMergeRow[rowIndex]) {// 只有行合并行为

            if (rowspanObj) {
              const _row = rowspanObj.rowspan
              const _col = rowspanObj.colspan
              return {
                rowspan: _row ? _row : _col ? 1 : 0,
                colspan: _col ? _col : _row ? 1 : 0
              }

            } else {
              // 除开第一列,其它行进行合并后,未合并的行需要隐藏,避免出现多行错乱问题
              return {
                rowspan: 0,
                colspan: 0
              }
            }
          }
        }
      }

      // 找合并列对应的那一行,避免所有列做重复操作
      if (mergeColAtRow && mergeColAtRow[columnIndex]) {
        const mergeRowPlus = this.categoryCN[columnIndex];
        if (mergeRowPlus) {
          // 只有列表合并,
          let colspanObj = mergeRowPlus.find((ee, index) => ee.colNum == columnIndex && (ee.rowNum - 4) == rowIndex)
          if (colspanObj) {
            const _col = colspanObj.colspan
            return {
              rowspan: 1,
              colspan: _col
            }
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    },

这个逻辑有的多 , 因为第一列合并操作有点特殊需要单独操作,后面的行合并又是单独的,而列合并又需要单独写逻辑。

哎不管了经过上面一系列的折腾简单的行列合并算是可以实现了,其它的情况后续再研究研究…

补充【20240704】:上面完成了行,列简单的合并操作,但是在具有行列同时合并的操作时就会出现问题,于是今个几个晚上的思考找到了解决方案

分析图
如图

1、 存在行列同时合并的情况比较特殊,如合并一个两行两列, 那么在合并第一行时就已经完成了行列合并操作,下面的一行在同一个位置就不需要做任何操作

2、 找到存在有行列同时合并的那一行数据,根据columnIndex 再从分组数据组查找是否存在真正合并的操作
如果没有那就代表改行只是参与了合并行为,但他本身不需要进行合并(上一行或列已经完成了合并操作)

核心代码如下

1、收集哪些存在与行列合并相关的所有行数据,在数据组装方法assemblyTableData中增加如下判断

      if (e.rowspan && e.colspan) {
            const keynum = parseInt(key) - 1
            const rowNumm = e.rowNum - 4;
            const colNum = e.colNum;// 列数
            // 行号:列号
            if (!existRowColMerge[rowNumm]) { existRowColMerge[rowNumm] = {} }
            existRowColMerge[rowNumm][colNum] = true;

            // 他合并了几行,记录下一次合并
            let rowspanNum = parseInt(e.rowspan);


            // if (!existMergeCol[keynum]) { existMergeCol[keynum] = {} }
            let colspanNum = parseInt(e.colspan);

            // existMergeCol[keynum][colNum] = true;// 标识他合并了
            let colstep = 1;
            while (colspanNum > 1) {
              // existMergeCol[keynum][colNum + colstep] = true;// 标识他合并了
              existRowColMerge[rowNumm][colNum + colstep] = true;
              colstep++;
              colspanNum -= 1;
            }

            // 存在行列同时合并的情况比较特殊,如合并一个两行两列,
            // 那么在合并第一行时就已经完成了行列合并操作,下面的一行在同一个位置就不需要做任何操作
            let step = 1;
            while (rowspanNum > 1) {
              if (!existRowColMerge[rowNumm + step]) { existRowColMerge[rowNumm + step] = {} }
              existRowColMerge[rowNumm + step] = existRowColMerge[rowNumm];// 下一行 标识他合并了,可以直接使用上一行的数据
              step++;
              rowspanNum -= 1;
            }

2、在合并方法objectSpanMethod中增加如下行列合并判断

  // 【存在行列同时合并】找到存在有行列同时合并的那一行数据,根据columnIndex 再从分组数据组查找是否存在真正合并的操作
      // 如果没有那就代表改行只是参与了合并行为,但他本身不需要进行合并(上一行或列已经完成了合并操作)
      if (existRowColMerge && existRowColMerge[columnIndex]) {
        const mergeRowPlus = this.categoryCN[columnIndex];
        if (mergeRowPlus) {
          // 存在行列同时合并,
          let colspanObj = mergeRowPlus.find((ee, index) => ee.colNum == columnIndex && (ee.rowNum - 4) == rowIndex)
          if (colspanObj) {
            const _col = colspanObj.colspan
            const _row = colspanObj.rowspan
            return {
              rowspan: _row,
              colspan: _col
            }
          } else {
            return {
              rowspan: 0,
              colspan: 0
            }
          }
        } else {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }

最后的合并效果
合并效果

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的痕迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值