将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
          }
        }
      }
    },

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

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

  • 最后把源码与测试数据保存一份到 github.com/dengxiaoning/excelToTable,如有需要的小伙伴请自取

补充【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
          }
        }
      }

最后的合并效果
合并效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/779259.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序的农产品商城-计算机毕业设计源码46732

摘 要 随着社会经济的发展和人们消费观念的升级,农产品电商行业逐渐壮大。但传统的农产品销售模式存在信息不透明、中间环节复杂等问题,而微信小程序作为一种便捷的移动应用平台,为农产品商城的建设提供了新的可能性。通过微信小程序的设计与…

上位机图像处理和嵌入式模块部署(mcu项目1:用户手册)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 一个完整的产品,除了上位机软件、固件、硬件、包装之外,一般还需要一个用户手册。好的用户手册应该能够兼顾到大多数人的认…

开发个人Go-ChatGPT--1 项目介绍

开发个人Go-ChatGPT--1 项目介绍 开发个人Go-ChatGPT--1 项目介绍知识点大纲文章目录项目地址 开发个人Go-ChatGPT–1 项目介绍 本文将以一个使用Ollama部署的ChatGPT为背景,主要还是介绍和学习使用 go-zero 框架,开发个人Go-ChatGPT的服务器后端&#x…

电脑为什么会提示丢失msvcp140.dll?怎么修复msvcp140.dll文件会靠谱点

电脑为什么会提示丢失msvcp140.dll?其实只要你的msvcp140.dll文件一损坏,然而你的电脑程序需要运用到这个msvcp140.dll文件的时候,就回提示你丢失了msvcp140.dll文件!因为没有这个文件,你的很多程序都用不了的。今天我…

Redis基础教程(十三):Redis lua脚本

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

[240706] 史蒂夫·乔布斯近40年前就预言了苹果智能 | Globalping 用于网络诊断和性能测试的命令行工具

目录 史蒂夫.乔布斯近40年前就预言了苹果智能Globalping 用于网络诊断和性能测试的命令行工具功能1. Ping2. Traceroute3. DNS 查询4. HTTP 请求 使用场景1. 网络性能监测2. 故障排除3. 网站性能优化4. 服务可用性监控 优势1. [全球覆盖](https://www.jsdelivr.com/network)2. …

[Vite]Vite插件生命周期了解

[Vite]Vite插件生命周期了解 Chunk和Bundle的概念 Chunk: 在 Vite 中,chunk 通常指的是应用程序中的一个代码片段,它是通过 Rollup 或其他打包工具在构建过程中生成的。每个 chunk 通常包含应用程序的一部分逻辑,可能是一个路由视…

5个实用的文章生成器,高效输出优质文章

在自媒体时代,优质内容的持续输出是吸引读者、提升影响力的关键。然而,对于许多自媒体创作者来说,频繁的创作难免会遭遇灵感枯竭、创作不出文章的困扰。此时,文章生成器便成为了得力的助手。文章生成器的优势能够快速自动生成高质…

C++怎么解决不支持字符串枚举?

首先,有两种方法:使用命名空间和字符串常量与使用 enum class 和辅助函数。 表格直观展示 特性使用命名空间和字符串常量使用 enum class 和辅助函数类型安全性低 - 编译器无法检查字符串有效性,运行时发现错误高 - 编译期类型检查&#xf…

SCI论文发表:构建清晰论文框架的10个原则 (附思维导图,建议收藏)

我是娜姐 迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 论文框架是什么?对我们完成一篇论文有哪些作用? 之前娜姐分享过一篇深圳湾实验室周耀旗教授关于论文写作的文章,他提出的第一个重要原则就…

Linux笔记之二

Linux笔记之二 一、文件属性学习二、软链接和硬链接1.软链接2.硬链接 三、Vim编辑器四、账号管理总结 一、文件属性学习 Linux 系统是一种典型的多用户系统,不同的用户处于不同的地位,拥有不同的权限。为了保护系统的安全性,Linux系统对不同…

前后端分离系统

前后端分离是一种现代软件架构模式,特别适用于Web应用开发,它强调将用户界面(前端)与服务器端应用逻辑(后端)相分离。两者通过API接口进行数据交互。这种架构模式的主要优势在于提高开发效率、维护性和可扩…

【LInux】从动态库的加载深入理解页表机制

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

Xilinx FPGA:vivado关于同步fifo的两个小实验

一、实验一:在同步fifo里写一个读一个(写入是8个位宽,读出是16个位宽) 程序: timescale 1ns / 1ps //要求写一个读一个 //读写时钟一致,写是8个位宽,读是16个位宽 module sync_fifo_test(inpu…

Nuxt框架中内置组件详解及使用指南(一)

title: Nuxt框架中内置组件详解及使用指南(一) date: 2024/7/6 updated: 2024/7/6 author: cmdragon excerpt: 本文详细介绍了Nuxt框架中的两个内置组件和的使用方法与功能。确保包裹的内容仅在客户端渲染,适用于处理浏览器特定功能或异步…

ubuntu 22 安装 lua 环境 编译lua cjson 模块

在 windows 下使用 cygwin 编译 lua 和 cjson 简直就是灾难,最后还是到 ubuntu 下完成了。 1、下载lua源码(我下载的 5.1 版本,后面还有一个小插曲), 直接解压编译,遇到一个 readline.h not found 的问题,需要安装 re…

MySQL篇三:数据类型

文章目录 前言1. 数值类型1.1 tinyint类型1.2 bit类型1.3 小数类型1.3.1 float1.3.2 decimal 2. 字符串类型2.1 char2.2 varchar2.3 char和varchar比较 3. 日期类型4. enum和set 前言 数据类型分类: 1. 数值类型 1.1 tinyint类型 在MySQL中,整型可以指…

论文略读:Learning and Forgetting Unsafe Examples in Large Language Models

随着发布给公众的大语言模型(LLMs)数量的增加,迫切需要了解这些模型从第三方定制的微调数据中学习的安全性影响。论文研究了在包含不安全内容的噪声定制数据上微调的LLMs的行为,这些数据集包含偏见、毒性和有害性 发现虽然对齐的L…

【Unity数据存储】Unity中使用SqLite数据库进行数据持久化

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 专栏交流🧧&…

Ubuntu 22.04远程自动登录桌面环境

如果需要远程自动登录桌面环境,首先需要将Ubuntu的自动登录打开,在【settings】-【user】下面 然后要设置【Sharing】进行桌面共享,Ubuntu有自带的桌面共享功能,不需要另外去安装xrdp或者vnc之类的工具了 点开【Remote Desktop】…