el-table合并行,列

文章描述了一个使用Vue.js开发的应用,展示了如何使用ElementUI组件构建一个包含区域选择、日期范围筛选、数据获取和导出功能的动态配置表单,并展示了一张用于展示查询结果的表格。
摘要由CSDN通过智能技术生成
<!-- eslint-disable default-case -->
<template>
  <div class="mod-config">
    <el-form
      :inline="true"
      size="small"
      :model="dataForm"
      @keyup.enter.native="getDataList()"
    >
      <!-- <el-form-item label="项目名称">
        <el-input v-model="dataForm.xmmc" placeholder="" clearable />
      </el-form-item>
      <el-form-item label="项目编号">
        <el-input v-model="dataForm.xmbh" placeholder="" clearable />
      </el-form-item> -->
      <el-form-item label="区域">
        <el-cascader
          v-model="dataForm.zzjg"
          filterable
          style="width: 100%"
          placeholder=""
          :options="orgList"
          :props="{ checkStrictly: true, value: 'code', label: 'fullName' }"
          clearable
        />
      </el-form-item>
      <el-form-item label="日期">
        <el-date-picker
          v-model="dataForm.sjrq"
          type="monthrange"
          value-format="yyyy-MM-dd"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          style="width: 100%;"
        />
      </el-form-item>
      <el-form-item>
        <el-button class="selectButton" size="small" @click="getDataList()">
          查询
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button size="small" @click="resetForm">
          重置
        </el-button>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" @click="exportReport()">
          导出
        </el-button>
      </el-form-item>
    </el-form>
    <!-- <el-table
      v-loading="dataListLoading"
      :data="tableData"
      :span-method="handleSpanMethod"
      border
      stripe
      :row-style="{height: '0'}"
      style="width: 100%;border: 0.5px solid black;border-color: black"
      :cell-style="tableRowClassName"
      :header-cell-style="{borderColor:'#000000',border:'1px solid',background:'#23ffff'}"
      size="small"
    > -->
    <el-table
      v-loading="dataListLoading"
      :header-cell-style="{background:'#FAFAFA'}"
      :data="tableData"
      :span-method="handleSpanMethod"
      stripe
      :row-style="{height: '0'}"
      :cell-style="tableRowClassName"
      size="small"
    >
      >
      <el-table-column
        prop="orgName"
        label="区域"
        width="200"
      />
      <el-table-column
        prop="khName"
        label="客户名称"
        show-overflow-tooltip
        width="150"
      />
      <el-table-column
        prop="xmmc"
        label="项目名称"
        width="200"
        show-overflow-tooltip
      />
      <!-- <el-table-column
        prop="xmbh"
        label="项目编号"
      /> -->

      />
      <el-table-column
        prop="bhd"
        label="饱和度"
        width="90"
      />
      <el-table-column
        prop="fhl"
        label="负荷率"
        width="100"
      />
      <el-table-column
        prop="bhjbbjl"
        label="报价率(不含加班)"
        width="120"
      />
      <el-table-column
        prop="hjbbjl"
        label="报价率(含加班)"
        width="110"
      />
      <el-table-column
        prop="ygcz"
        label="预估产值"
      >
        <template slot-scope="scope">
          {{ utils.handleScopeFormat(scope.row.ygcz) }}
        </template>
      </el-table-column>
      <el-table-column
        prop="qrcz"
        label="确认产值"
      >
        <template slot-scope="scope">
          {{ utils.handleScopeFormat(scope.row.qrcz) }}
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dataListLoading: false,
      dataForm: {
        zzjg: ['0001'],
        xmmc: '',
        xmbh: '',
        sjrq: []
      },
      tableData: [],
      orgList: []
    }
  },
  activated() {
    this.getDataList()
  },
  mounted() {
  },
  methods: {
    /**
     * 日报分析列表
     */
    getDataList() {
      this.dataListLoading = true
      this.dataList = []
      this.$http({
        url: this.$http.adornUrl('/reportprojoutput/list'),
        method: 'get',
        params: this.$http.adornParams({
          xmmc: this.dataForm.xmmc,
          xmbh: this.dataForm.xmbh,
          sjrq1: this.dataForm.sjrq && this.dataForm.sjrq.length > 0 ? this.dataForm.sjrq[0] : '',
          sjrq2: this.dataForm.sjrq && this.dataForm.sjrq.length > 0 ? this.dataForm.sjrq[1] : '',
          zzjg: this.dataForm.zzjg.length > 0 ? this.dataForm.zzjg[this.dataForm.zzjg.length - 1] : ''

        })
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.orgList = this.$store.state.common.zzjgList
          this.tableData = data.reportProjOutputEntities
          // this.getSpanArr(this.tableData)
        } else {
          this.dataList = []
          this.totalPage = 0
        }
        this.dataListLoading = false
      })
    },
    /**
     * 导出
     */
    exportReport() {
      this.$http({
        url: this.$http.adornUrl('/reportprojoutput/exportStaticReport'),
        method: 'get',
        responseType: 'blob',
        params: this.$http.adornParams({
          sjrq1: this.dataForm.sjrq && this.dataForm.sjrq.length > 0 ? this.dataForm.sjrq[0] : '',
          sjrq2: this.dataForm.sjrq && this.dataForm.sjrq.length > 0 ? this.dataForm.sjrq[1] : '',
          zzjg: this.dataForm.zzjg.length > 0 ? this.dataForm.zzjg[this.dataForm.zzjg.length - 1] : ''
        })
      }).then(res => {
        const blob = new Blob([res.data])
        const fileName = res.headers['content-disposition']
          .split(';')[1]
          .split('filename=')[1]
        const elink = document.createElement('a')
        elink.download = decodeURI(`${fileName}.xlsx`)
        elink.style.display = 'none'
        elink.href = URL.createObjectURL(blob)
        document.body.appendChild(elink)
        elink.click()
        URL.revokeObjectURL(elink.href)
        document.body.removeChild(elink)
      })
    },
    // 得到行、列的合并值
    handleSpanMethod({
      row, column, rowIndex, columnIndex
    }) {
	     // 页面列表上 表格合并行 -> 第几列(从0开始)
	    // 需要合并多个单元格时 依次增加判断条件即可
      if (columnIndex === 1 && row.xmmc !== '小计' && row.xmmc !== '总计') {
        const rowspanArr = this.formatRowspanAndColspan(this.tableData, 'khName')
        return {
          rowspan: rowspanArr[rowIndex],
          colspan: 1
        }
      }
      if (columnIndex === 0 && row.orgName !== '总计' && row.orgName !== '小计') {
        const rowspanArr = this.formatRowspanAndColspan(this.tableData, 'orgName')
        return {
          rowspan: rowspanArr[rowIndex],
          colspan: 1
        }
      }
      // 客户小计
      if (columnIndex === 1 && row.xmmc === '小计' && row.khName !== '小计') {
        return [0, 0]
      }
      // 区域小计
      if (columnIndex === 1 && row.xmmc === '小计' && row.khName === '小计') {
        return [1, 2]
      }
      if (columnIndex === 2 && row.xmmc === '小计' && row.khName === '小计') {
        return [0, 0]
      }
      // 如果为最后一行
      if (columnIndex === 0 && row.orgName === '总计') {
        return [1, 3]
      }
      if (columnIndex === 1 && row.xmmc === '总计') {
        return [0, 0]
      }
      if (columnIndex === 2 && row.xmmc === '总计') {
        return [0, 0]
      }
    },

    tableRowClassName({ row }) {
      // return row.khName === '小计'
      //   ? 'background-color: #FAFAFA;'
      //   : 'background-color: white;'
      let backgroundColor = 'background-color: white;'
      switch (row.xmmc) {
        case '小计':
          backgroundColor = 'background-color: #FAFAFA'
          break
        case '总计':
          backgroundColor = 'background-color: #EDF1FF'
          break
        default:
          backgroundColor = 'background-color: white'
      }
      return backgroundColor
    },
    /**
     * 合并单元格辅助
     */
    formatRowspanAndColspan(tableList, keyName) {
      const keyNameList = []
      tableList.forEach(
        t => { keyNameList.push(t[keyName]) }
      )
      // console.log('keyNameList =>', keyNameList)

      let prev // 上一个键名的索引
      let contin = 0 // 连续相同键名个数
      const computedList = [] // 计算后的键名列表
      for (let i = 0; i < keyNameList.length; i++) {
        if (computedList.length === 0) {
          computedList.push({ key: keyNameList[i], val: 1 })
        } else if (keyNameList[prev] === keyNameList[i]) {
          contin++
          computedList.push({ key: keyNameList[i], val: 0 })
        } else {
          if (contin > 0) {
            const index = computedList.length - 1 - contin
            const { key } = computedList[index]
            const { val } = computedList[index]
            const obj = { key, val: val + contin }
            computedList.splice(index, 1, obj)
          }
          computedList.push({ key: keyNameList[i], val: 1 })
          contin = 0
        }

        prev = i // 将 i 赋值给 prev,以便当下一次循环时获取上一个键值的索引
      }
      if (contin > 0) {
        const index = computedList.length - 1 - contin
        const { key } = computedList[index]
        const { val } = computedList[index]
        const obj = { key, val: val + contin }
        computedList.splice(index, 1, obj)
      }
      // console.log('computedList =>', computedList)

      const finalList = []
      computedList.forEach(
        t => { finalList.push(t.val) }
      )
      // console.log('finalList =>', finalList)

      return finalList
    },
    /**
     * 重置查询条件
     */
    resetForm() {
      this.dataForm.zzjg = ['0001']
      this.dataForm.sjrq = []
    }

  }
}
</script>
<style>
/* 或者使用/deep/方式 */
/deep/ .el-table .el-table__header-wrapper tr {
  border-bottom: 2px solid #000;
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值