SOURCE

let tableData = [
    {
        "bank": "gfBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "900",
        "deposit": "1000",
        "id": "77"
    },
    {
        "bank": "gfBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "900",
        "deposit": "1000",
        "id": "76"
    },
    {
        "bank": "gfBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "900",
        "deposit": "1000",
        "id": "75"
    },
    {
        "bank": "gfBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "900",
        "deposit": "1000",
        "id": "74"
    },
    {
        "bank": "gfBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "800",
        "deposit": "900",
        "id": "73"
    },
    {
        "bank": "gfBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "800",
        "deposit": "900",
        "id": "72"
    },
    {
        "bank": "gfBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "800",
        "deposit": "900",
        "id": "71"
    },
    {
        "bank": "gfBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "800",
        "deposit": "900",
        "id": "70"
    },
    {
        "bank": "gfBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "700",
        "deposit": "800",
        "id": "69"
    },
    {
        "bank": "gfBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "700",
        "deposit": "800",
        "id": "68"
    },
    {
        "bank": "gfBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "700",
        "deposit": "800",
        "id": "67"
    },
    {
        "bank": "gfBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "700",
        "deposit": "800",
        "id": "66"
    },
    {
        "bank": "gfBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "600",
        "deposit": "700",
        "id": "65"
    },
    {
        "bank": "gfBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "600",
        "deposit": "700",
        "id": "64"
    },
    {
        "bank": "gfBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "600",
        "deposit": "700",
        "id": "63"
    },
    {
        "bank": "gfBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "600",
        "deposit": "700",
        "id": "62"
    },
    {
        "bank": "cnBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "500",
        "deposit": "600",
        "id": "61"
    },
    {
        "bank": "cnBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "500",
        "deposit": "600",
        "id": "60"
    },
    {
        "bank": "cnBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "500",
        "deposit": "600",
        "id": "59"
    },
    {
        "bank": "cnBank",
        "werks": "3031",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "500",
        "deposit": "600",
        "id": "58"
    },
    {
        "bank": "cnBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "400",
        "deposit": "500",
        "id": "57"
    },
    {
        "bank": "cnBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "400",
        "deposit": "500",
        "id": "56"
    },
    {
        "bank": "cnBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "400",
        "deposit": "500",
        "id": "55"
    },
    {
        "bank": "cnBank",
        "werks": "1011",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "400",
        "deposit": "500",
        "id": "54"
    },
    {
        "bank": "cnBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "300",
        "deposit": "400",
        "id": "53"
    },
    {
        "bank": "cnBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "300",
        "deposit": "400",
        "id": "52"
    },
    {
        "bank": "cnBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "300",
        "deposit": "400",
        "id": "51"
    },
    {
        "bank": "cnBank",
        "werks": "4031",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "300",
        "deposit": "400",
        "id": "50"
    },
    {
        "bank": "cnBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-12",
        "paper_money": "200",
        "deposit": "300",
        "id": "49"
    },
    {
        "bank": "cnBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-11",
        "paper_money": "200",
        "deposit": "300",
        "id": "48"
    },
    {
        "bank": "cnBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-10",
        "paper_money": "200",
        "deposit": "300",
        "id": "47"
    },
    {
        "bank": "cnBank",
        "werks": "5041",
        "zquarter": "quarter3",
        "edate": "2022-09",
        "paper_money": "200",
        "deposit": "300",
        "id": "46"
    }
]
let structureResVOs = [
    {
        "cellId": 94,
        "fieldType": "varchar",
        "fieldName": "银行",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 6,
        "total": 1,
        "subtotal": 1,
        "statistics": 0,
        "formula": "",
        "cellType": 1,
        "cellCode": "bank",
        "dataType": "varchar",
        "dataLength": 10,
        "dataPrecision": null,
        "dataValues": [
            {
                "dataValue": "cnBank",
                "dataTxt": "中国银行"
            },
            {
                "dataValue": "gfBank",
                "dataTxt": "广发银行"
            },
            {
                "dataValue": "jsBank",
                "dataTxt": "建设银行"
            },
            {
                "dataValue": "pinganBank",
                "dataTxt": "平安银行"
            }
        ]
    },
    {
        "cellId": 45,
        "fieldType": "varchar",
        "fieldName": "季度",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 5,
        "total": 0,
        "subtotal": 1,
        "statistics": 0,
        "formula": "",
        "cellType": 1,
        "cellCode": "zquarter",
        "dataType": "varchar",
        "dataLength": 10,
        "dataPrecision": null,
        "dataValues": [
            {
                "dataValue": "quarter1",
                "dataTxt": "第一季度"
            },
            {
                "dataValue": "quarter2",
                "dataTxt": "第二季度"
            },
            {
                "dataValue": "quarter3",
                "dataTxt": "第三季度"
            },
            {
                "dataValue": "quarter4",
                "dataTxt": "第四季度"
            }
        ]
    },
    {
        "cellId": 44,
        "fieldType": "char4",
        "fieldName": "工厂",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 8,
        "total": 0,
        "subtotal": 1,
        "statistics": 0,
        "formula": "",
        "cellType": 1,
        "cellCode": "werks",
        "dataType": "varchar",
        "dataLength": 4,
        "dataPrecision": null,
        "dataValues": [
            {
                "dataValue": "1011",
                "dataTxt": "广东科技"
            },
            {
                "dataValue": "3031",
                "dataTxt": "武汉联塑"
            },
            {
                "dataValue": "4031",
                "dataTxt": "贵阳联塑"
            },
            {
                "dataValue": "5041",
                "dataTxt": "四川联塑"
            }
        ]
    },
    {
        "cellId": 95,
        "fieldType": "curr",
        "fieldName": "票面金额",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 1,
        "total": 0,
        "subtotal": 0,
        "statistics": 0,
        "formula": "",
        "cellType": 2,
        "cellCode": "paper_money",
        "dataType": "decimal",
        "dataLength": 13,
        "dataPrecision": 2,
        "dataValues": null
    },
    {
        "cellId": 96,
        "fieldType": "curr",
        "fieldName": "保证金",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 2,
        "total": 0,
        "subtotal": 0,
        "statistics": 0,
        "formula": "",
        "cellType": 2,
        "cellCode": "deposit",
        "dataType": "decimal",
        "dataLength": 13,
        "dataPrecision": 2,
        "dataValues": null
    },
    {
        "cellId": 97,
        "fieldType": "varchar",
        "fieldName": "到期月份",
        "show": 1,
        "search": 0,
        "multiLabel": "",
        "sno": 3,
        "total": 0,
        "subtotal": 0,
        "statistics": 0,
        "formula": "",
        "cellType": 1,
        "cellCode": "edate",
        "dataType": "varchar",
        "dataLength": 10,
        "dataPrecision": null,
        "dataValues": [
            {
                "dataValue": "2022-09",
                "dataTxt": "2022年9月"
            },
            {
                "dataValue": "2022-10",
                "dataTxt": "2022年10月"
            },
            {
                "dataValue": "2022-11",
                "dataTxt": "2022年11月"
            },
            {
                "dataValue": "2022-12",
                "dataTxt": "2022年12月"
            }
        ]
    }
]
let uniqueTotalField = {index:1,cellCode:"bank",fieldName:"银行"}
// 开启小计的字段
let turnOnSubtotalFields = structureResVOs.filter(item=>item.subtotal).map(item=>item.cellCode)
// 特征字段
let featureFields = structureResVOs.filter(item=>item.cellType==1).map(item=>item.cellCode)
featureFieldsObj = Object.fromEntries(featureFields.map(item=>[item,'']))
// 指标字段
let quatoFields = structureResVOs.filter(item=>item.cellType==2).map(item=>item.cellCode)
// function handleTableHeader(structureResVOs) {
//       structureResVOs.sort((a, b) => {
//         return a.sno - b.sno
//       })
//       let headerMap = {}
//       for (let rec of structureResVOs) {
//         if (!rec.multiLabel) {
//           headerMap[rec.fieldName] = { field: rec.cellCode }
//         } else {
//           headerMap[rec.multiLabel] = headerMap[rec.multiLabel] || []
//           headerMap[rec.multiLabel].push({
//             headerName: rec.fieldName,
//             field: rec.cellCode
//           })
//         }
//       }
//       return headerMap
// }
// let headerMap = handleTableHeader(structureResVOs)
// console.log(headerMap)
console.log(turnOnSubtotalFields)
console.log(featureFields,featureFieldsObj)
console.log(quatoFields)
const attr = (data,arr,index=0,valueMap = {}) =>{
    let map = {}
    // 索引值等于数组长度,结束递归
    if(index===arr.length){
        return 
    }else{
        // 生成当前级对应索引值字段的值映射
        for(let rec of data){
            map[rec[arr[index]]] ={}
        }
        for(let k in map){
            // 如果索引值到最后一级
            if(index===arr.length-1){
                valueMap[arr[index]] = k
                // console.log(valueMap)
                map[k].children = data.filter((item,index)=>{
                    return arr.every(key=>item[key]==valueMap[key])
                })
                if(map[k].children.length){
                    let keyArr = arr.slice(0,index+1)
                    map[k].total = data.filter(item=>{
                        return keyArr.every(key=>item[key]==valueMap[key])
                    }).reduce((pre,next)=>{
                        quatoFields.forEach(field=>{
                            pre[field] = pre[field]||0
                            pre[field]+=Number(next[field])
                        })
                        return pre
                    },{...featureFieldsObj})
                    map[k].total[arr[index]] = `${k}小计`
                }  
            }else{ // 否则,继续递归子级
                valueMap[arr[index]] = k  // 当前级别的字段对应值映射
                // console.log(valueMap)       
                map[k].children = attr(data,arr,index+1,{...valueMap})
                let keyArr = arr.slice(0,index+1) // 筛选的小计字段依据
                // 筛选当前级别的数据
                map[k].total = data.filter(item=>{
                    return keyArr.every(key=>item[key]==valueMap[key])
                })
                // 计算总计
                if(map[k].total.length){
                    map[k].total =  map[k].total.reduce((pre,next)=>{
                        quatoFields.forEach(field=>{
                            pre[field] = pre[field]||0
                            pre[field]+=Number(next[field])
                        })
                        return pre
                    },{...featureFieldsObj})
                    map[k].total[arr[index]] = `${k}小计`
                }    
            }
        }
        return map
    }
}
let dataMap = attr(tableData,turnOnSubtotalFields)


console.log(dataMap)
console 命令行工具 X clear

                    
>
console