翼度科技»论坛 编程开发 JavaScript 查看内容

el-table表格动态合并相同数据单元格(可指定列+自定义合并)

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
1.固定合并


  • 官方挺提供的合并具体某行列的方法:el-table合并行或列
  • 通过给table传入span-method方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。
该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan,第二个元素代表colspan。 也可以返回一个键名为rowspan和colspan的对象。
  1. <template>
  2.   <div>
  3.     <el-table
  4.       :data="tableData"
  5.       :span-method="arraySpanMethod"
  6.       border
  7.       style="width: 100%">
  8.       <el-table-column
  9.         prop="id"
  10.         label="ID"
  11.         width="180">
  12.       </el-table-column>
  13.       <el-table-column
  14.         prop="name"
  15.         label="姓名">
  16.       </el-table-column>
  17.       <el-table-column
  18.         prop="amount1"
  19.         sortable
  20.         label="数值 1">
  21.       </el-table-column>
  22.       <el-table-column
  23.         prop="amount2"
  24.         sortable
  25.         label="数值 2">
  26.       </el-table-column>
  27.       <el-table-column
  28.         prop="amount3"
  29.         sortable
  30.         label="数值 3">
  31.       </el-table-column>
  32.     </el-table>
  33.     <el-table
  34.       :data="tableData"
  35.       :span-method="objectSpanMethod"
  36.       border
  37.       style="width: 100%; margin-top: 20px">
  38.       <el-table-column
  39.         prop="id"
  40.         label="ID"
  41.         width="180">
  42.       </el-table-column>
  43.       <el-table-column
  44.         prop="name"
  45.         label="姓名">
  46.       </el-table-column>
  47.       <el-table-column
  48.         prop="amount1"
  49.         label="数值 1(元)">
  50.       </el-table-column>
  51.       <el-table-column
  52.         prop="amount2"
  53.         label="数值 2(元)">
  54.       </el-table-column>
  55.       <el-table-column
  56.         prop="amount3"
  57.         label="数值 3(元)">
  58.       </el-table-column>
  59.     </el-table>
  60.   </div>
  61. </template>
  62. <script>
  63.   export default {
  64.     data() {
  65.       return {
  66.         tableData: [{
  67.           id: '12987122',
  68.           name: '王小虎',
  69.           amount1: '234',
  70.           amount2: '3.2',
  71.           amount3: 10
  72.         }, {
  73.           id: '12987123',
  74.           name: '王小虎',
  75.           amount1: '165',
  76.           amount2: '4.43',
  77.           amount3: 12
  78.         }, {
  79.           id: '12987124',
  80.           name: '王小虎',
  81.           amount1: '324',
  82.           amount2: '1.9',
  83.           amount3: 9
  84.         }, {
  85.           id: '12987125',
  86.           name: '王小虎',
  87.           amount1: '621',
  88.           amount2: '2.2',
  89.           amount3: 17
  90.         }, {
  91.           id: '12987126',
  92.           name: '王小虎',
  93.           amount1: '539',
  94.           amount2: '4.1',
  95.           amount3: 15
  96.         }]
  97.       };
  98.     },
  99.     methods: {
  100.       arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  101.         if (rowIndex % 2 === 0) {
  102.           if (columnIndex === 0) {
  103.             return [1, 2];
  104.           } else if (columnIndex === 1) {
  105.             return [0, 0];
  106.           }
  107.         }
  108.       },
  109.       objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  110.         if (columnIndex === 0) {
  111.           if (rowIndex % 2 === 0) {
  112.             return {
  113.               rowspan: 2,
  114.               colspan: 1
  115.             };
  116.           } else {
  117.             return {
  118.               rowspan: 0,
  119.               colspan: 0
  120.             };
  121.           }
  122.         }
  123.       }
  124.     }
  125.   };
  126. </script>
复制代码
运行效果:


缺点这种只适合写死的数据和固定的表格行列,无法动态判断单元格数据是否相等再合并;

2. 动态合并相同数据单元格(所有列)


  • 可以对所有相同数据的列,进行动态合并
  • 此方法适合需要合并所有的相同数据的单元格
  1. <template>
  2.   <div>
  3.     <el-table
  4.       :data="tableData"
  5.       :span-method="objectSpanMethod"
  6.       border
  7.       :header-cell-style="{ textAlign: 'center', backgroundColor: '#F5F7FA' }"
  8.     >
  9.       <el-table-column prop="School" label="学校" align="center">
  10.       </el-table-column>
  11.       <el-table-column prop="Grade" label="年级" align="center" />
  12.       <el-table-column prop="Class" label="班级" align="center" />
  13.       <el-table-column prop="Name" label="姓名" align="center" />
  14.       <el-table-column prop="Chinese" label="语文" align="center" />
  15.       <el-table-column prop="Math" label="数学" align="center" />
  16.       <el-table-column prop="English" label="英语" align="center" />
  17.     </el-table>
  18.   </div>
  19. </template>
  20. <script>
  21. export default {
  22.   data() {
  23.     return {
  24.       // 存放所有的表头 一定要与tableData一致
  25.       colFields: [
  26.         "School",
  27.         "Grade",
  28.         "Class",
  29.         "Name",
  30.         "Chinese",
  31.         "Math",
  32.         "English",
  33.       ],
  34.       spanArr: [], //存储合并单元格的开始位置
  35.       // 表格数据
  36.       tableData: [
  37.         // 一年级
  38.         {
  39.           School: "第一小学",
  40.           Grade: "1年级",
  41.           Class: "1班",
  42.           Name: "张三",
  43.           Chinese: "90",
  44.           Math: "100",
  45.           English: "80",
  46.         },
  47.         {
  48.           School: "第一小学",
  49.           Grade: "1年级",
  50.           Class: "2班",
  51.           Name: "李四",
  52.           Chinese: "90",
  53.           Math: "85",
  54.           English: "80",
  55.         },
  56.         {
  57.           School: "第一小学",
  58.           Grade: "1年级",
  59.           Class: "3班",
  60.           Name: "王五",
  61.           Chinese: "79",
  62.           Math: "100",
  63.           English: "80",
  64.         },
  65.         // 二年级
  66.         {
  67.           School: "第一小学",
  68.           Grade: "2年级",
  69.           Class: "1班",
  70.           Name: "赵六",
  71.           Chinese: "95",
  72.           Math: "100",
  73.           English: "80",
  74.         },
  75.         {
  76.           School: "第一小学",
  77.           Grade: "2年级",
  78.           Class: "2班",
  79.           Name: "钱八",
  80.           Chinese: "98",
  81.           Math: "85",
  82.           English: "80",
  83.         },
  84.         {
  85.           School: "第一小学",
  86.           Grade: "2年级",
  87.           Class: "3班",
  88.           Name: "陈九",
  89.           Chinese: "79",
  90.           Math: "100",
  91.           English: "80",
  92.         },
  93.         // 三年级
  94.         {
  95.           School: "第一小学",
  96.           Grade: "3年级",
  97.           Class: "1班",
  98.           Name: "黄十",
  99.           Chinese: "91",
  100.           Math: "88",
  101.           English: "80",
  102.         },
  103.         {
  104.           School: "第一小学",
  105.           Grade: "3年级",
  106.           Class: "2班",
  107.           Name: "魏一",
  108.           Chinese: "90",
  109.           Math: "86",
  110.           English: "87",
  111.         },
  112.         {
  113.           School: "第一小学",
  114.           Grade: "3年级",
  115.           Class: "3班",
  116.           Name: "杨二",
  117.           Chinese: "79",
  118.           Math: "99",
  119.           English: "80",
  120.         },
  121.       ],
  122.     };
  123.   },
  124.   methods: {
  125.     /**
  126.      * 分析每一列,找出相同的
  127.      * @param data
  128.      */
  129.     getSpanArr() {
  130.       for (let i = 0; i < this.tableData.length; i++) {
  131.         let row = i;
  132.         // let col = i % this.colCount;
  133.         if (row === 0) {
  134.           // i 表示行 j表示列
  135.           for (let j = 0; j < this.colFields.length; j++) {
  136.             this.spanArr[i * this.colFields.length + j] = {
  137.               rowspan: 1,
  138.               colspan: 1,
  139.             };
  140.           }
  141.         } else {
  142.           for (let j = 0; j < this.colFields.length; j++) {
  143.             // 当前和上一次的一样
  144.             // 1. 合并所有列的相同数据单元格
  145.             if (
  146.               this.tableData[row][this.colFields[j]] ===
  147.               this.tableData[row - 1][this.colFields[j]]
  148.             ) {
  149.               let beforeItem =
  150.                 this.spanArr[(row - 1) * this.colFields.length + j];
  151.               this.spanArr[row * this.colFields.length + j] = {
  152.                 rowspan: 1 + beforeItem.rowspan, // 合并几行
  153.                 colspan: 1, // 合并几列,我这里只是跨行合并,不跨列合并,所以用的1
  154.               };
  155.               beforeItem.rowspan = 0;
  156.               beforeItem.colspan = 0;
  157.             } else {
  158.               // rowspan 和 colspan 都为1表格此单元格不合并
  159.               this.spanArr[row * this.colFields.length + j] = {
  160.                 rowspan: 1,
  161.                 colspan: 1,
  162.               };
  163.             }
  164.           }
  165.         }
  166.       }
  167.       // 对数据进行倒序
  168.       let stack = [];
  169.       for (let i = 0; i < this.colFields.length; i++) {
  170.         for (let j = 0; j < this.tableData.length; j++) {
  171.           // console.log("i=" + i + " j=" + j);
  172.           // i 表示列 j表示行
  173.           if (j === 0) {
  174.             if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
  175.               stack.push(this.spanArr[j * this.colFields.length + i]);
  176.             }
  177.           } else {
  178.             if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
  179.               stack.push(this.spanArr[j * this.colFields.length + i]);
  180.             } else {
  181.               stack.push(this.spanArr[j * this.colFields.length + i]);
  182.               while (stack.length > 0) {
  183.                 let pop = stack.pop();
  184.                 let len = stack.length;
  185.                 this.spanArr[(j - len) * this.colFields.length + i] = pop;
  186.               }
  187.             }
  188.           }
  189.         }
  190.       }
  191.       // console.log(this.spanArr);
  192.     },
  193.     objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  194.       // console.log(this.spanArr[rowIndex * this.colFields.length + columnIndex]);
  195.       return this.spanArr[rowIndex * this.colFields.length + columnIndex];
  196.     },
  197.   },
  198.   mounted() {
  199.     this.getSpanArr();
  200.   },
  201. };
  202. </script>
  203. <style lang="scss" scoped></style>
复制代码
效果:

我们可以看到,所有列,只要数据相同的单元格都被合并了,包括我不想合并的单元格,这时候就要指定合并的列


3. 动态合并相同数据单元格(指定列)

只需要加个if判断即可指定要合并哪些列
  1. // 这里只放了部分代码,除了加了个if,其他代码和上面的一样
  2. getSpanArr() {
  3.       for (let i = 0; i < this.tableData.length; i++) {
  4.         let row = i;
  5.         // let col = i % this.colCount;
  6.         if (row === 0) {
  7.           // i 表示行 j表示列
  8.           for (let j = 0; j < this.colFields.length; j++) {
  9.             this.spanArr[i * this.colFields.length + j] = {
  10.               rowspan: 1,
  11.               colspan: 1,
  12.             };
  13.           }
  14.         } else {
  15.           for (let j = 0; j < this.colFields.length; j++) {
  16.             // 当前和上一次的一样
  17.             //  合并所有列的相同数据单元格
  18.             if (
  19.               this.colFields[j] == "School" ||
  20.               this.colFields[j] == "Grade" ||
  21.               this.colFields[j] == "Class"
  22.             ) { // 指定合并哪些列
  23.               if (
  24.                 this.tableData[row][this.colFields[j]] ===
  25.                 this.tableData[row - 1][this.colFields[j]]
  26.               ) {
  27.                 let beforeItem =
  28.                   this.spanArr[(row - 1) * this.colFields.length + j];
  29.                 this.spanArr[row * this.colFields.length + j] = {
  30.                   rowspan: 1 + beforeItem.rowspan,
  31.                   colspan: 1,
  32.                 };
  33.                 beforeItem.rowspan = 0;
  34.                 beforeItem.colspan = 0;
  35.               } else {
  36.                 // rowspan 和 colspan 都为1表格此单元格不合并
  37.                 this.spanArr[row * this.colFields.length + j] = {
  38.                   rowspan: 1,
  39.                   colspan: 1,
  40.                 };
  41.               }
  42.             }
  43.           }
  44.         }
  45.       }
复制代码
效果:这样就只合并了我们指定的那几列了


4. 动态合并相同数据单元格(指定列+合并条件)

有时候我们会遇到不想合并的单元格,比如下面这种情况:

按常理来说,不同小学的数据应该是不做合并才对,正确是这种:

这时候就需要加上一些自定义的合并条件了:
  1. getSpanArr() {
  2.       for (let i = 0; i < this.tableData.length; i++) {
  3.         let row = i;
  4.         // let col = i % this.colCount;
  5.         if (row === 0) {
  6.           // i 表示行 j表示列
  7.           for (let j = 0; j < this.colFields.length; j++) {
  8.             this.spanArr[i * this.colFields.length + j] = {
  9.               rowspan: 1,
  10.               colspan: 1,
  11.             };
  12.           }
  13.         } else {
  14.           for (let j = 0; j < this.colFields.length; j++) {
  15.             // 当前和上一次的一样
  16.             //  合并所有列的相同数据单元格
  17.             if (
  18.               this.colFields[j] == "School" ||
  19.               this.colFields[j] == "Grade" ||
  20.               this.colFields[j] == "Class"
  21.             ) { // 指定合并哪些列
  22.               if (
  23.                 this.tableData[row]["School"] !==
  24.                   this.tableData[row - 1]["School"]
  25.               ) { // 哪些不合并:School不一样的,不合并
  26.                 this.spanArr[row * this.colFields.length + j] = {
  27.                   rowspan: 1,
  28.                   colspan: 1,
  29.                 };
  30.               } else if (
  31.                 this.tableData[row][this.colFields[j]] ===
  32.                 this.tableData[row - 1][this.colFields[j]]
  33.               ) {
  34.                 let beforeItem =
  35.                   this.spanArr[(row - 1) * this.colFields.length + j];
  36.                 this.spanArr[row * this.colFields.length + j] = {
  37.                   rowspan: 1 + beforeItem.rowspan,// 合并几列
  38.                   colspan: 1,// 合并几行
  39.                 };
  40.                 beforeItem.rowspan = 0;
  41.                 beforeItem.colspan = 0;
  42.               } else {
  43.                 // rowspan 和 colspan 都为1表格此单元格不合并
  44.                 this.spanArr[row * this.colFields.length + j] = {
  45.                   rowspan: 1,
  46.                   colspan: 1,
  47.                 };
  48.               }
  49.             }
  50.           }
  51.         }
  52.       }
  53.       // console.log(this.spanArr);
  54.     },
复制代码
这时候再看,就是我们想要的效果了


完整代码

最后附完整代码:
  1. <template>
  2.   <div>
  3.     <el-table
  4.       :data="tableData"
  5.       :span-method="objectSpanMethod"
  6.       border
  7.       :header-cell-style="{ textAlign: 'center', backgroundColor: '#F5F7FA' }"
  8.     >
  9.       <el-table-column prop="School" label="学校" align="center">
  10.       </el-table-column>
  11.       <el-table-column prop="Grade" label="年级" align="center" />
  12.       <el-table-column prop="Class" label="班级" align="center" />
  13.       <el-table-column prop="Name" label="姓名" align="center" />
  14.       <el-table-column prop="Chinese" label="语文" align="center" />
  15.       <el-table-column prop="Math" label="数学" align="center" />
  16.       <el-table-column prop="English" label="英语" align="center" />
  17.     </el-table>
  18.   </div>
  19. </template>
  20. <script>
  21. export default {
  22.   data() {
  23.     return {
  24.       // 存放所有的表头 一定要与tableData一致
  25.       colFields: [
  26.         "School",
  27.         "Grade",
  28.         "Class",
  29.         "Name",
  30.         "Chinese",
  31.         "Math",
  32.         "English",
  33.       ],
  34.       spanArr: [], //存储合并单元格的开始位置
  35.       // 表格数据
  36.       tableData: [
  37.         // 一年级
  38.         {
  39.           School: "第一小学",
  40.           Grade: "1年级",
  41.           Class: "1班",
  42.           Name: "张三",
  43.           Chinese: "90",
  44.           Math: "100",
  45.           English: "80",
  46.         },
  47.         {
  48.           School: "第一小学",
  49.           Grade: "1年级",
  50.           Class: "1班",
  51.           Name: "张伟",
  52.           Chinese: "90",
  53.           Math: "99",
  54.           English: "89",
  55.         },
  56.         {
  57.           School: "第一小学",
  58.           Grade: "1年级",
  59.           Class: "2班",
  60.           Name: "李四",
  61.           Chinese: "90",
  62.           Math: "85",
  63.           English: "80",
  64.         },
  65.         {
  66.           School: "第一小学",
  67.           Grade: "1年级",
  68.           Class: "3班",
  69.           Name: "王五",
  70.           Chinese: "79",
  71.           Math: "100",
  72.           English: "80",
  73.         },
  74.         // 二年级
  75.         {
  76.           School: "第一小学",
  77.           Grade: "2年级",
  78.           Class: "1班",
  79.           Name: "赵六",
  80.           Chinese: "95",
  81.           Math: "100",
  82.           English: "80",
  83.         },
  84.         {
  85.           School: "第一小学",
  86.           Grade: "2年级",
  87.           Class: "2班",
  88.           Name: "钱八",
  89.           Chinese: "98",
  90.           Math: "85",
  91.           English: "80",
  92.         },
  93.         {
  94.           School: "第一小学",
  95.           Grade: "2年级",
  96.           Class: "3班",
  97.           Name: "陈九",
  98.           Chinese: "79",
  99.           Math: "100",
  100.           English: "100",
  101.         },
  102.         // 三年级
  103.         {
  104.           School: "第一小学",
  105.           Grade: "3年级",
  106.           Class: "1班",
  107.           Name: "黄十",
  108.           Chinese: "91",
  109.           Math: "88",
  110.           English: "80",
  111.         },
  112.         {
  113.           School: "第一小学",
  114.           Grade: "3年级",
  115.           Class: "2班",
  116.           Name: "魏一",
  117.           Chinese: "90",
  118.           Math: "86",
  119.           English: "87",
  120.         },
  121.         {
  122.           School: "第一小学",
  123.           Grade: "3年级",
  124.           Class: "3班",
  125.           Name: "杨二",
  126.           Chinese: "79",
  127.           Math: "99",
  128.           English: "80",
  129.         },
  130.         // 第二小学
  131.         {
  132.           School: "第二小学",
  133.           Grade: "3年级",
  134.           Class: "3班",
  135.           Name: "袁零",
  136.           Chinese: "79",
  137.           Math: "99",
  138.           English: "80",
  139.         },
  140.       ],
  141.     };
  142.   },
  143.   methods: {
  144.     /**
  145.      * 分析每一列,找出相同的
  146.      * @param data
  147.      */
  148.     getSpanArr() {
  149.       for (let i = 0; i < this.tableData.length; i++) {
  150.         let row = i;
  151.         // let col = i % this.colCount;
  152.         if (row === 0) {
  153.           // i 表示行 j表示列
  154.           for (let j = 0; j < this.colFields.length; j++) {
  155.             this.spanArr[i * this.colFields.length + j] = {
  156.               rowspan: 1,
  157.               colspan: 1,
  158.             };
  159.           }
  160.         } else {
  161.           for (let j = 0; j < this.colFields.length; j++) {
  162.             // 当前和上一次的一样
  163.             //  合并所有列的相同数据单元格
  164.             if (
  165.               this.colFields[j] == "School" ||
  166.               this.colFields[j] == "Grade" ||
  167.               this.colFields[j] == "Class"
  168.             ) { // 指定合并哪些列
  169.               if (
  170.                 this.tableData[row]["School"] !==
  171.                   this.tableData[row - 1]["School"]
  172.               ) { // 哪些不合并:School不一样的,不合并
  173.                 this.spanArr[row * this.colFields.length + j] = {
  174.                   rowspan: 1,
  175.                   colspan: 1,
  176.                 };
  177.               } else if (
  178.                 this.tableData[row][this.colFields[j]] ===
  179.                 this.tableData[row - 1][this.colFields[j]]
  180.               ) {
  181.                 let beforeItem =
  182.                   this.spanArr[(row - 1) * this.colFields.length + j];
  183.                 this.spanArr[row * this.colFields.length + j] = {
  184.                   rowspan: 1 + beforeItem.rowspan,// 合并几列
  185.                   colspan: 1,// 合并几行
  186.                 };
  187.                 beforeItem.rowspan = 0;
  188.                 beforeItem.colspan = 0;
  189.               } else {
  190.                 // rowspan 和 colspan 都为1表格此单元格不合并
  191.                 this.spanArr[row * this.colFields.length + j] = {
  192.                   rowspan: 1,
  193.                   colspan: 1,
  194.                 };
  195.               }
  196.             }
  197.           }
  198.         }
  199.       }
  200.       // 对数据进行倒序
  201.       let stack = [];
  202.       for (let i = 0; i < this.colFields.length; i++) {
  203.         for (let j = 0; j < this.tableData.length; j++) {
  204.           // console.log("i=" + i + " j=" + j);
  205.           // i 表示列 j表示行
  206.           if (j === 0) {
  207.             if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
  208.               stack.push(this.spanArr[j * this.colFields.length + i]);
  209.             }
  210.           } else {
  211.             if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
  212.               stack.push(this.spanArr[j * this.colFields.length + i]);
  213.             } else {
  214.               stack.push(this.spanArr[j * this.colFields.length + i]);
  215.               while (stack.length > 0) {
  216.                 let pop = stack.pop();
  217.                 let len = stack.length;
  218.                 this.spanArr[(j - len) * this.colFields.length + i] = pop;
  219.               }
  220.             }
  221.           }
  222.         }
  223.       }
  224.       // console.log(this.spanArr);
  225.     },
  226.     objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  227.       // console.log(this.spanArr[rowIndex * this.colFields.length + columnIndex]);
  228.       return this.spanArr[rowIndex * this.colFields.length + columnIndex];
  229.     },
  230.   },
  231.   mounted() {
  232.     this.getSpanArr();
  233.   },
  234. };
  235. </script>
  236. <style lang="scss" scoped></style>
复制代码
参考:https://blog.csdn.net/u010735120/article/details/122184493
到此这篇关于el-table表格动态合并相同数据单元格(可指定列+自定义合并)的文章就介绍到这了,更多相关el-table 动态合并单元格内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源:https://www.jb51.net/javascript/292180wz4.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具