[Insert subtotal row into table] el-table table, insert subtotal row calculation data based on a certain field in the array object

Preface

Function explanation: One of the requirements encountered is the tabledata array of the table. It contains department doctors and many consumption indicators and other data. Then I need to sort and put the departments together. Then add a row of data under each department, which is a subtotal row. Used to calculate the summary of all data for the same department above. Then there is another total row at the bottom, adding all the subtotals.

renderings

This is what the table looks like just after sorting. The data is simulated by me
Insert image description here
and then it looks like this after inserting the subtotal row.
Insert image description here

Implementation

Logical flow:
1. Request to get the data of the table tableData
2. Sort the array so that the departments are all together, then merge cells
3, loop the arrays, find the index of the corresponding department, save it in an array, and name it after the department.
4. Reverse the array and insert from the back to the front, because inserting from the front will cause the subtotal to change.
5. Calculate the subtotal row and insert it directly.

code

You can copy it directly to see the effect, and you can use it by changing the fields.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <!-- 公共css文件 -->
    <script src="./ceshi.js"></script>
    <link rel="stylesheet" href="/statics/css/common/common.css">
    <!-- 公共js文件 -->
    <script type="text/javascript" src="/statics/vue_element/common.js"></script>
    <!-- vue方面文件 -->
    <script src="/statics/vue_element/vue.js"></script>
    <script src="/statics/vue_element/element.js"></script>
    <link rel="stylesheet" href="/statics/vue_element/element.css">
    <script src="/statics/vue_element/axios.js"></script>
    <script src="/mixins/quanxian.js"></script>
    <title>测试页</title>
</head>

<body>
    <div id="app" style="padding:10px;">
        <el-table :data="tableDatas" border style="width: 100%" ref="configurationTable" :row-style="rowstyle"
            :span-method="objectSpanMethod">
            <el-table-column v-for="(arrd,index) in headers" :key="index" :label="arrd.name" align="center" width='100'
                show-overflow-tooltip>
                <!-- 有子级 -->
                <el-table-column v-for="(arrd2,index2) in arrd.child" align="center" :label="arrd2.name"
                    show-overflow-tooltip>
                    <template slot-scope="{row, $index}">
                        <span>{
    
    {
    
    row[arrd2.key]}}</span>
                    </template>
                </el-table-column>
                <!-- 无子级 -->
                <template slot-scope="{row, $index}">
                    <span>{
    
    {
    
    row[arrd.key]}}</span>
                </template>
            </el-table-column>
        </el-table>
    </div>
</body>
<script type="text/javascript">
    let v = new Vue({
    
    
        el: '#app',
        data() {
    
    
            return {
    
    
                tableDatas: [],//表体
                headers: [],//表头
                spanArr: []//合并单元格
            }
        },
        mounted() {
    
    
            this.searchList()
        },
        methods: {
    
    
            // 模拟发送请求,拿到表格数据
            searchList() {
    
    
                let that = this
                that.tableShow = false
                // 模拟数据
                that.headers = [{
    
    
                            child: [],
                            key: "ks",
                            name: "科室"
                        },
                        {
    
    
                            child: [],
                            key: "doctor",
                            name: "医生"
                        },
                        {
    
    
                            child: [],
                            key: "ghl",
                            name: "挂号"
                        },
                        {
    
    
                            child: [],
                            key: "jzl",
                            name: "就诊"
                        },
                        {
    
    
                            child: [],
                            key: "jz",
                            name: "体检"
                        }
                    ],
                    that.tableDatas = [{
    
    
                        ks: "中医科",
                        doctor: '中医科医生1',
                        ghl: 6,
                        jzl: 5,
                        jz: 2,
                    }, {
    
    
                        ks: "中医科",
                        doctor: '中医科医生2',
                        ghl: 9,
                        jzl: 4,
                        jz: 3,
                    }, {
    
    
                        ks: "外科",
                        doctor: '外科医生2',
                        ghl: 7,
                        jzl: 3,
                        jz: 4,
                    }, {
    
    
                        ks: "外科",
                        doctor: '外科医生1',
                        ghl: 5,
                        jzl: 1,
                        jz: 5,
                    }, {
    
    
                        ks: "内科",
                        doctor: '内科医生3',
                        ghl: 2,
                        jzl: 1,
                        jz: 6,
                    }, {
    
    
                        ks: "内科",
                        doctor: '内科医生1',
                        ghl: 2,
                        jzl: 12,
                        jz: 7,
                    }]
                this.tableDatas.sort(this.mysort);
                this.groupHandle(that.tableDatas)
                let hj = this.hj(that.tableDatas)
                this.tableDatas.push(hj)
                this.setdates()
            },
            // 根据科室排序
            mysort(a, b) {
    
    
                if (a.ks !== b.ks) {
    
    
                    if (a.ks !== null && a.ks !== undefined) {
    
    
                        return a.ks < b.ks ? -1 : 1;
                    } else {
    
    
                        return -1;
                    }
                }
            },
            // 计算小计行插入位置
            groupHandle(Human) {
    
    
                let doctorMap = {
    
    };
                for (let i = 0; i < Human.length; i++) {
    
    
                    //找出相同名称的行数
                    let doctorName = Human[i].ks
                    if (doctorMap[doctorName] !== undefined) {
    
    
                        doctorMap[doctorName].push(i);
                    } else {
    
    
                        doctorMap[doctorName] = [i];
                    }
                }
                let keyArr = [];
                for (let k in doctorMap) {
    
    
                    //取出key并倒序,防止正序插入会影响行下标
                    keyArr.unshift(k);
                }
                keyArr.forEach((ele, index) => {
    
    
                    let lastIndex = doctorMap[ele][doctorMap[ele].length - 1]; //找出相同名称最后一行插入合计数据
                    let obj = this.xj(Human, ele) //计算出小计行数据
                    Human.splice(lastIndex + 1, 0, obj) //插入
                })
            },
            // 小计行计算
            xj(data, name) {
    
    
                let obj = {
    
    
                    ks: name, //科室名字,用于合并单元格
                    doctor: '小计',
                    ghl: 0,
                    jzl: 0,
                    jz: 0,
                }
                data.forEach(item => {
    
    
                    // 科室相同的加起来
                    if (item.ks == name) {
    
    
                        obj.ghl += (item.ghl ? parseFloat(item.ghl) : 0)
                        obj.jzl += (item.jzl ? parseFloat(item.jzl) : 0)
                        obj.jz += (item.jz ? parseFloat(item.jz) : 0)
                    }
                })
                return obj
            },
            // 合计行计算
            hj(data) {
    
    
                let hj = {
    
    
                    ks: '合计',
                    doctor: '-',
                    ghl: 0,
                    jzl: 0,
                    jz: 0,
                }
                data.forEach(item => {
    
    
                    // 小计行加起来就是合计
                    if (item.doctor == '小计') {
    
    
                        hj.ghl += (item.ghl ? parseFloat(item.ghl) : 0)
                        hj.jzl += (item.jzl ? parseFloat(item.jzl) : 0)
                        hj.jz += (item.jz ? parseFloat(item.jz) : 0)
                    }
                })
                return hj
            },
            // 行底纹
            rowstyle({
     
     
                row,
                rowindex,
            }) {
    
    
                if (row.ks == '合计') {
    
    
                    return "background:#afdfe4;color:#34738f"
                }
                if (row.doctor == '小计') {
    
    

                    return "background:	#D9EDF7;color:#34738f;border-bottom:1px solid #409eff !important;"
                }
            },
            // 合并单元格
            objectSpanMethod({
     
     
                row,
                column,
                rowIndex,
                columnIndex
            }) {
    
    
                if (columnIndex === 0) {
    
    
                    const _row = this.spanArr[rowIndex];
                    const _col = _row > 0 ? 1 : 0;
                    return {
    
    
                        rowspan: _row,
                        colspan: _col
                    };
                }
            },
            // 计算要合并的单元格
            setdates() {
    
    
                let contactDot = 0;
                this.spanArr = []
                this.tableDatas.forEach((item, index) => {
    
    
                    item.index = index;
                    if (index === 0) {
    
    
                        this.spanArr.push(1);
                    } else {
    
    
                        // 根据相同科室来合并
                        if (item.ks === this.tableDatas[index - 1].ks) {
    
    
                            this.spanArr[contactDot] += 1;
                            this.spanArr.push(0);
                        } else {
    
    
                            contactDot = index;
                            this.spanArr.push(1);
                        }
                    }
                });
            },
        }
    })
</script>
<style scoped>

</style>

</html>

Guess you like

Origin blog.csdn.net/seeeeeeeeeee/article/details/133122424