比如:我们要实现下图这个表格
在这里插入图片描述
代码如下:

<template>
  <div>
    <el-table :data="tableData" :span-method="objectSpanMethod" border :header-cell-style="handerMethod">
      <el-table-column align="center" prop="id" label=""></el-table-column>
      <el-table-column align="center" prop="amount1" label="数据分类"></el-table-column>
      <el-table-column align="center" prop="amount2" label="缴存业务"></el-table-column>
      <el-table-column align="center" prop="amount3" label="提取业务"></el-table-column>
      <el-table-column align="center" prop="amount4" label="贷款业务"></el-table-column>
      <el-table-column align="center" label="业务办理合计">
        <el-table-column align="center" label="业务办理合计" prop="amount5"></el-table-column>
        <el-table-column align="center" label="" prop="amount6"></el-table-column>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
export default {
  data() {
    return {
      spanArr: [], // 用于存放每一行记录的合并数
      tableData: [
        {
          id: '业务办理类业务统计量',
          amount1: '线上服务量小计',
          amount2: '1',
          amount3: '2',
          amount4: '3',
          amount5: '4',
          amount6: '4'
        },
        {
          id: '业务办理类业务统计量',
          amount1: '线上业务小计',
          amount2: '1',
          amount3: '2',
          amount4: '3',
          amount5: '4',
          amount6: '4'
        },
        {
          id: '业务办理类业务统计量',
          amount1: '线下业务小计',
          amount2: '1',
          amount3: '2',
          amount4: '3',
          amount5: '4',
          amount6: '4'
        },
        {
          id: '业务办理类业务统计量',
          amount1: '线上+线下',
          amount2: '1',
          amount3: '2',
          amount4: '3',
          amount5: '4',
          amount6: '4'
        },
        {
          id: '业务办理类业务统计量',
          amount1: '线上占比',
          amount2: '1',
          amount3: '2',
          amount4: '3',
          amount5: '4',
          amount6: '4'
        },
        {
          id: '9大渠道服务总量统计',
          amount1: '9大渠道服务总量统计',
          amount2: '信息查询',
          amount3: '信息发布',
          amount4: '互动交流',
          amount5: '业务办理',
          amount6: '线上总计'
        },
        {
          id: '9大渠道服务总量统计',
          amount1: '9大渠道服务总量统计',
          amount2: '01',
          amount3: '02',
          amount4: '03',
          amount5: '04',
          amount6: '05'
        }
      ]
    }
  },
  mounted() {
  },
  methods: {
    // 隐藏表头
    handerMethod({ rowIndex }) {
      if (rowIndex === 1) {
        // 这里为了是将第二列的表头隐藏,就形成了合并表头的效果
        return { display: 'none' }
      }
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 对第六、七行 进行合并
      if (rowIndex === 5) {
        if (columnIndex === 0) {
          return [2, 2]
        } else if (columnIndex === 1) {
          return [0, 0]
        }
      }
      // 对第一列 第二列 进行合并
      if (columnIndex === 1 || columnIndex === 0) {
        // 当 当前行与上一行内容相同时 返回0 0 意味消除
        if (rowIndex > 0 && row[column.property] === this.tableData[rowIndex - 1][column.property]) {
          return {
            rowspan: 0,
            colspan: 0
          }
        } else {
          let rows = 1
          // 反之 查询相同的内容有多少行 进行合并
          for (let i = rowIndex; i < this.tableData.length - 1; i++) {
            if (row[column.property] === this.tableData[i + 1][column.property]) {
              rows++
            }
          }
          // 返回相同内容的行数
          return {
            rowspan: rows,
            colspan: 1
          }
        }
      }
      // 对第一、二、三、四、五行 进行合并
      if (rowIndex === 0 || rowIndex === 1 || rowIndex === 2 || rowIndex === 3 || rowIndex === 4) {
        // 处理合计,[1,2]表示合并1行2列,[0,0]表示改行不显示
        if (columnIndex === 5) {
          // 定位到5列的一、二、三、四、五行,告诉该单元格合并1行2列
          return [1, 2]
        } else if (columnIndex === 6) {
          // 定位到6列的一、二、三、四、五行,告诉该单元格不显示
          return [0, 0]
        }
      }
    }

  }
}
</script>

el-table 行合并

方法一:(直接使用)

<el-table
                :data="tableData"
                border
                :span-method="objectSpanMethod"
                style="width: 100%">
                <el-table-column
                prop="order"
                label="序号"
                align="center"
                width="50">
                </el-table-column>
                <el-table-column
                prop="name"
                :label="'名称'"
                align="center"
                fixed="left"
                width="70">
                </el-table-column>
</el-table>



<script>
export default {
  name: 'StationsStaTable',
  data () {
    return {
        tableData: [],
    },
 methods: {
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 对第一列 第二列 进行合并
        if (columnIndex === 1 || columnIndex === 0) {
            // 当 当前行与上一行内容相同时 返回0 0 意味消除
            if(rowIndex > 0 && row[column.property] === this.tableData[rowIndex - 1][column.property]){
                return {
                    rowspan: 0,
                    colspan: 0
                };
            }else{
                let rows = 1;
                // 反之 查询相同的内容有多少行 进行合并
                for(let i = rowIndex; i < this.tableData.length - 1; i++){
                    if (row[column.property] === this.tableData[i + 1][column.property]) {
                        rows++;
                    }
                }
                // 返回相同内容的行数
                return {
                    rowspan: rows,
                    colspan: 1
                };
            }
        }
      }
 }

方法二:(封装函数)

1、使用

导入js文件,并设置需要合并的列

//导入js文件(文件脚本内容在下文)
import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'

//调用函数并导出需要的合并列函数 注意需要根据
//data为查询到的数据
//['prop1', 'prop2', 'prop3'] 需要合并的列
const spanMethod=getRowspanMethod(data,['prop1', 'prop2', 'prop3'])

在vue页面模板中使用

<!--使用spanMethod方法-->
<el-table :data="data" height="100%" :span-method="spanMethod">
...
</el-table>
2、封装合并的方法

这个文件(use-span-method.js)通过导出一个函数来提供给el-table的和并方法使用

/**
 * 合并相同数据,导出合并列所需的方法(只适合el-table)
 * @param {Object} data
 * @param {Object} rowspanArray
 */
export function getRowspanMethod(data, rowspanArray) {

	/**
	 * 要合并列的数据
	 */
	const rowspanNumObject = {};

	//初始化 rowspanNumObject
	rowspanArray.map(item => {
		rowspanNumObject[item] = new Array(data.length).fill(1, 0, 1).fill(0, 1);
		rowspanNumObject[`${item}-index`] = 0;
	});
	//计算相关的合并信息
	for (let i = 1; i < data.length; i++) {
		rowspanArray.map(key => {
			const index = rowspanNumObject[`${key}-index`];
			if (data[i][key] === data[i - 1][key]) {
				rowspanNumObject[key][index]++;
			} else {
				rowspanNumObject[`${key}-index`] = i;
				rowspanNumObject[key][i] = 1;
			}

		});
	}

	//提供合并的方法并导出
	const spanMethod = function({ row, column, rowIndex, columnIndex }) {
		if (rowspanArray.includes(column['property'])) {
			const rowspan = rowspanNumObject[column['property']][rowIndex];
			if (rowspan > 0) {
				return { rowspan: rowspan, colspan: 1 }
			}
			return { rowspan: 0, colspan: 0 }
		}
		return { rowspan: 1, colspan: 1 }
	};

	return spanMethod;
}
3、vue2/3具体使用
// vue2
import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'
	export default {
		data(){
			spanMethod:()=>{},
			list:[],
		},
		methods:{
			// 查询数据方法
			getData(){
				this.spanMethod=getRowspanMethod(this.list,['prop1', 'prop2', 'prop3'])
			}
		}
	}
 
// vue3 setup
import {ref ,computed} from 'vue';
	import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'
	
	// 获取数据存放变量
	let list=ref([]);
	//实际根据业务灵活调整
	const spanMethod=computed(()=>{
		return getRowspanMethod(list.value,['prop1', 'prop2', 'prop3'])
	})
	
	// 查询数据方法
	const getData=function(){
		//查询到数据赋值
		list.value=[];
	}

el-table 列合并

objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 处理合计,[1,2]表示合并2行2列,[0,0]表示改行不显示
      if (rowIndex === 5) {
        if (columnIndex === 0) {
          // 定位到0列,告诉该单元格合并1行2列
          return [1, 2]
        } else if (columnIndex === 1) {
           // 定位到1列,告诉该单元格不显示
          return [0, 0]
        }
      }
	}

el-table表头列合并

<el-table :data="tableData" :header-cell-style="handerMethod">
    <el-table-column align="center" label="业务办理合计">
            <el-table-column label="业务办理合计" prop="amount5"></el-table-column>
            <el-table-column label="" prop="amount6"></el-table-column>
          </el-table-column>
</el-table>

	//隐藏表头
    handerMethod({rowIndex}){
      if (rowIndex === 1) {
       //这里为了是将第二列的表头隐藏,就形成了合并表头的效果
        return {display: 'none'}
      }
    },
       <el-table-column label="业务办理合计" prop="amount5"></el-table-column>
        <el-table-column label="" prop="amount6"></el-table-column>
      </el-table-column>

```js
	//隐藏表头
    handerMethod({rowIndex}){
      if (rowIndex === 1) {
       //这里为了是将第二列的表头隐藏,就形成了合并表头的效果
        return {display: 'none'}
      }
    },

el-table自定义合计

效果图如下:在这里插入图片描述代码实现:

<template>
  <div style='height: 800px;width: 100%;background: #fff;'>
    <el-table  ref="table" border :data="tableData" :span-method="objectSpanMethod" stripe class="table-class" show-summary :summary-method="getNodeSummaries" highlight-current-row>
      <el-table-column type="index" label="序号" width="50"></el-table-column>
      <el-table-column prop="name" label="名字" align="center" />
      <el-table-column prop="sex" label="性别" width="120" align="center" />
      <el-table-column prop="tiZh" label="体重" width="120" align="center" />
      <el-table-column prop="num1" label="爬山次数" width="120" align="center" />
      <el-table-column prop="num2" label="游泳次数" width="120" align="center" />
      <el-table-column prop="num3" label="健身次数" width="120" align="center" />
    </el-table>
  </div>
</template>

<script>
// import { ref } from 'vue'
export default {
  name: 'aaaa',
  components: {},
  props: {},
  data() {
    return {
      tableData: [
        {       
          name: '张三',
          sex: '男',
          tiZh: 120,
          num1: 1000,
          num2: 2000,
          num3: 3000
        },{       
          name: '张四',
          sex: '女',
          tiZh: 120,
          num1: 1000,
          num2: 2000,
          num3: 3000
        },
      ],
    }
  },
  computed: {},
  mounted() {},
  methods: {
    objectSpanMethod() {
      this.$nextTick(x => {
      if (this.$refs.table.$el) {
          var current = this.$refs.table.$el
            .querySelector(".el-table__footer-wrapper")
            .querySelector(".el-table__footer");
          var cell = current.rows[0].cells;
          cell[0].style.display = "none";
          cell[1].style.display = "none";
          cell[2].style.display = "none";
          cell[3].classList.remove('is-left')
          cell[3].colSpan = "4";
        }
      })
    },
    getNodeSummaries(param) {
      const { columns, data } = param;
      const sums = [];
      let arr = [ 'num1', 'num2', 'num3']
      columns.forEach((column, index) => {
        if (index === 3) {
          sums[index] = "合计";
          return;
        }
        if (arr.some(x => column.property === x)) {
          sums[index] = 0;
          data.map((item) => {
            console.log(item)
            let num = item[column.property];
            // num = num ? parseFloat(num.replace(/,/gi, "")) : 0;
            sums[index] = this.accAdd(sums[index], num);
          });
        } else {
          sums[index] = "";
        }
      });
      return sums;
    },
    accAdd(arg1, arg2) {
      let r1, r2, m;
      try {
        r1 = arg1.toString().split(".")[1].length;
      } catch (e) {
        r1 = 0;
      }
      try {
        r2 = arg2.toString().split(".")[1].length;
      } catch (e) {
        r2 = 0;
      }
      m = Math.pow(10, Math.max(r1, r2));
      return ((arg1 * m + arg2 * m) / m).toFixed(2);
    },
  }
}
</script>

<style lang='scss' scoped>
  .table-class{
    width: 50%;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
</style>
Logo

前往低代码交流专区

更多推荐