vue+iviewui实现表格合并(行列合并)

Posted wu2020

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue+iviewui实现表格合并(行列合并)相关的知识,希望对你有一定的参考价值。

效果图:

技术图片

 

 需求:

1.相同的项目要合并,相同的项目下相同塔楼要合并

2.日期动态生成(需判断跨年跨月)

3.列合并代表工作时长(颜色代表状态)

逻辑:

1.先处理表头,日期项自定义key值,如果跨年的话,添加一个子项(跨月一样),用三元表达式自定义class颜色

2.跟后端协商,项目,塔楼和日期都要返回一个总和值回来,然后根据这个值去指定合并(因为手动判断合并页面渲染会很慢,数据多时会死机)

代码:

1.初始化表头:

columns: [
        { title: 项目, key: taskItem, fixed: left, align: center, width: 200 },
        { title: 塔楼, key: taskArea, fixed: left, align: center, width: 120 }
      ],

 

2.当数据回来时,表头处理

日期是两层结构,所以不同年和同月要push一个对象,而具体的日期在.children里
日期格式:["7-6", "7-7", "7-8", "7-9", "7-10", "7-11", "7-13", "7-14", "7-15", "7-16", "7-17", "7-18", "7-20",
"7-21"]
columnsDate () {
      // let starttime = this.$route.query.schStartdate
      // let endtime = this.$route.query.schEnddate
      let starttime = this.schInfo.schStartdate
      let endtime = this.schInfo.schEnddate // ‘2020-06-29‘ // this.schInfo.schEnddate
      // 开始时间的年/月/日
      let startArr = starttime.split(-)
    // 结束时间 let endArr
= endtime.split(-) // 同年 if (startArr[0] === endArr[0]) { // 同月 if (startArr[1] === endArr[1]) { // console.log(‘同月‘) let columnsObj = { title: ‘‘, align: center, children: [] } columnsObj.title = `${startArr[0]}年${startArr[1]}月` for (var i = 0; i < this.dayData.length; i++) { // let columnStyle = isWeekend(startArr[0], startArr[1], i) ? ‘weekend-style‘ : ‘‘ let startMonth = this.dayData[i].split(-)[0] let day = this.dayData[i].split(-)[1] let objItem = { title: `${this.dayData[i].split(-)[1]}号`, key: `Y${startArr[0]}M${startMonth}D${day}`, // 根据key赋值 align: center, minWidth: 90, className: weekend-style, render: (h, params) => { return h(div, { // 1:未派发,2.已派发,3已完成) 自定义颜色 class: params.row.state === 3 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on2 : params.row.state === 2 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on : params.row.state === 1 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on1 : ‘‘, on: { click: () => { this.showDetail(params, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } }, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } columnsObj.children.push(objItem) } // this.BiweeklyPlanTable.columns.push(columnsObj) this.columns.push(columnsObj) } else { // console.log(‘不同月‘) for (var f = 0; f < endArr[1] - startArr[1] + 1; f++) { let columnsObj = { title: ‘‘, align: center, children: [] } var Month = parseInt(startArr[1]) + f Month = Month < 10 ? 0 + Month : Month columnsObj.title = `${startArr[0]}年${Month}月` for (var l = 0; l < this.dayData.length; l++) { // let columnStyle = isWeekend(startArr[0], startArr[1], i) ? ‘weekend-style‘ : ‘‘ if (this.dayData[l].split(-)[0] === parseInt(Month) + ‘‘) { let startMonth = this.dayData[l].split(-)[0] let day = this.dayData[l].split(-)[1] let objItem = { title: `${this.dayData[l].split(-)[1]}号`, key: `Y${startArr[0]}M${startMonth}D${day}`, align: center, minWidth: 90, className: weekend-style, render: (h, params) => { return h(div, { // 1:未派发,2.已派发,3已完成) class: params.row.state === 3 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on2 : params.row.state === 2 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on : params.row.state === 1 && params.row[`Y${startArr[0]}M${startMonth}D${day}`] !== - ? span-mouse-on1 : ‘‘, on: { click: () => { this.showDetail(params) } } }, params.row[`Y${startArr[0]}M${startMonth}D${day}`]) } } columnsObj.children.push(objItem) } } this.columns.push(columnsObj) } } } // console.log(this.dayData) // console.log(this.columns, ‘表头‘) // console.log(this.newData, ‘内容‘) },

 

3.初始化渲染表格数据

 // 拿到日期的数组循环遍历成表头key值那样赋值‘—’,再push进data里
getForData () {
      // console.log(this.columnsLength, length)this.schInfo.schStartdate
      let starttime = this.schInfo.schStartdate.split(-)[0]
      var obj = {}
      for (var i = 0; i < this.dayData.length; i++) {
        var day = Y + starttime + M + this.dayData[i].split(-)[0] + D + this.dayData[i].split(-)[1]
        obj[day] = -
      }
      return obj
    },

 

4.最终表格数据  // 数据处理

    getBiweeklyPlanDate () {
      this.newData = []
      let dataArr = this.data
      dataArr.forEach(arriItem => {
        let newObj = this.getForData()
        newObj.taskItem = arriItem.schTask.taskItem
        newObj.taskArea = arriItem.schTask.taskArea
        newObj.state = arriItem.schTask.state
        newObj.schTaskId = arriItem.schTask.id
        newObj.mergeCol = arriItem.itemsum ? arriItem.itemsum : 0
        newObj.areanum = arriItem.areanum ? arriItem.areanum : 0
        var dt = arriItem.schTask.dateRange.split(,)
        newObj.long = dt.length
        let startArr = arriItem.schTask.planStartDate.split(-) // 开始时间 planStartDate: "2020-07-06"
        // let startArr = dayLis.split(‘-‘)
        let startYear = startArr[0]
        let startMonth = startArr[1]
        startMonth = startMonth[0] === 0 ? startMonth.replace(0, ‘‘) : startMonth
        let startDay = startArr[2]
        startDay = startDay[0] === 0 ? startDay.replace(0, ‘‘) : startDay
        let startKey = `Y${startYear}M${startMonth}D${startDay}`
        newObj[startKey] = arriItem.schTask.state === 3 ? `${arriItem.schTask.taskFloor}(已完成)` : arriItem.schTask.taskFloor // 赋值
        this.dayData.forEach((day, index) => {
          if (day === `${startMonth}-${startDay}`) { // 记住是哪一列,合并列时要用到
            newObj.i = index + 2
          }
        })
this.newData.push(newObj)
      })
    },

 

5.合并(最重要代码)

// html
 <Table :columns="columns" :data="newData" border :span-method="handleSpan"></Table>
// js
// 表格的合并单元格处理
    handleSpan ({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        // 计算合并的行数列数
        let x = row.mergeCol === 0 ? 0 : row.mergeCol
        let y = row.mergeCol === 0 ? 0 : 1
        // console.log(x , y)
        return [x, y]
      }
      if (columnIndex === 1) {
        // 计算合并的行数列数
        let x = row.areanum === 0 ? 0 : row.areanum
        let y = row.areanum === 0 ? 0 : 1
        // console.log(x , y)
        return [x, y]
      }
      // 列合并
      if (columnIndex === row.i) {
        return [1, row.long]
      } else if (columnIndex > row.i && columnIndex < row.i + row.long) {
        return [0, 0]
      }
    },

 谦虚的小白望能得到大神的指导~

 

以上是关于vue+iviewui实现表格合并(行列合并)的主要内容,如果未能解决你的问题,请参考以下文章

高分求代码 用js或jquery实现表格行列转换,表格含合并的单元格

Antd 表格合并与赋值渲染

el-table动态获取数据合并行列

Vue2 带纵向合并的原生表格实现切割侧栏分页

利用Python合并指定行列excel文件

poi 导出word,导出表格(复杂表格合并行列)解决方法