let totalField = 'bank' // 开启合计的字段
let totalFieldObj = {bank:''}
let subtotalFields = ['bank','company','quater'] // 开启小计的字段
let subtotalFieldsObj = Object.fromEntries(subtotalFields.map(item=>[item,'']))
let featureFields = ['bank','company','quater'] // 特征字段
featureFieldsObj = Object.fromEntries(featureFields.map(item=>[item,'']))
featureFieldsValue = {
bank:['中国银行','广发银行','建设银行','平安银行'],
company:['广东公司','武汉公司','湖南公司'],
quater:['第一季度','第二季度','第三季度','第四季度']
}
// console.log(featureFieldsObj)
let quatoFields = ['money','fee'] // 指标字段
let tableData = [
{id:1,bank:'中国银行',company:'广东公司',quater:'第一季度',money:100,fee:200},
{id:2,bank:'中国银行',company:'广东公司',quater:'第二季度',money:200,fee:300},
{id:15,bank:'中国银行',company:'广东公司',quater:'第二季度',money:200,fee:300},
{id:3,bank:'中国银行',company:'湖南公司',quater:'第一季度',money:300,fee:400},
{id:4,bank:'中国银行',company:'湖南公司',quater:'第二季度',money:400,fee:500},
{id:5,bank:'广发银行',company:'武汉公司',quater:'第三季度',money:400,fee:500},
{id:6,bank:'广发银行',company:'广东公司',quater:'第一季度',money:100,fee:200},
{id:7,bank:'广发银行',company:'广东公司',quater:'第二季度',money:500,fee:600},
{id:8,bank:'广发银行',company:'湖南公司',quater:'第一季度',money:600,fee:700},
{id:9,bank:'广发银行',company:'湖南公司',quater:'第二季度',money:600,fee:700},
{id:10,bank:'建设银行',company:'广东公司',quater:'第一季度',money:100,fee:200},
{id:11,bank:'建设银行',company:'广东公司',quater:'第二季度',money:500,fee:600},
{id:12,bank:'建设银行',company:'湖南公司',quater:'第一季度',money:600,fee:700},
{id:13,bank:'建设银行',company:'湖南公司',quater:'第二季度',money:600,fee:700},
{id:14,bank:'建设银行',company:'湖南公司',quater:'第三季度',money:600,fee:700},
]
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)=>{
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 subtotalMap = attr(tableData,subtotalFields)
console.log(subtotalMap)
let subtotalFieldRowSpan = calcRowSpan(subtotalMap) // 小计字段值行合并长度
// 第一个小计字段的数据值
let totalFieldValue = {
中国银行:0,
广发银行:0,
建设银行:0,
// 平安银行:0,
}
// 生成数据
function handleMap(map){
let arr = []
for(let k in map){
if(Array.isArray(map[k].children)){
if(map[k].children.length){
map[k].children.forEach((item,index)=>{
const rawItem = {...item}
if(!totalFieldValue[item[totalField]]){
totalFieldValue[item[totalField]] = 1
}else{
item = Object.assign(item,totalFieldObj)
}
if(index!==0){
item = Object.assign(item,subtotalFieldsObj)
}
item.rawItem = rawItem
})
arr.push(...map[k].children)
arr.push(map[k].total)
}
}else{
let cArr = handleMap(map[k].children)
cArr.forEach((item,index)=>{
if(index!==0){
if(!['中国银行','广发银行','建设银行','平安银行'].includes(k)){
item = Object.assign(item,{company:''})
}
}
})
arr.push(...cArr)
if(!Array.isArray(map[k].total)){
arr.push(map[k].total)
}
}
}
return arr
}
let rowData = handleMap(subtotalMap)
// rowData.forEach(item=>{
// if(item.id&&needToClearArr.indexOf(item.id)>-1){
// item = Object.assign(item,subtotalFieldsObj)
// }
// })
console.log(rowData)
function calcRowSpan(subtotalMap){
let map = {}
for(let k in subtotalMap){
map[k] = map[k]||{}
map[k].rowSpan = map[k].rowSpan||0
if(Array.isArray(subtotalMap[k].children)){
map[k].rowSpan = subtotalMap[k].children.length
}else{
map[k].children = map[k].children||{}
map[k].children = calcRowSpan(subtotalMap[k].children)
for(let k1 in map[k].children){
map[k].rowSpan += map[k].children[k1].rowSpan
if(map[k].children[k1].rowSpan!==0){
map[k].rowSpan += 1
}
}
}
}
return map
}
console.log(subtotalFieldRowSpan)
let obj = {
"广东公司": {
"children": {
"中国银行": {
"children": [
{id:1,bank:'中国银行',company:'广东公司',quater:'第一季度',money:100,fee:200},
{id:2,bank:'中国银行',company:'广东公司',quater:'第二季度',money:200,fee:300},
],
"total":{bank:'中国银行合计',company:'',quater:'',money:300,fee:500}
},
"广发银行": {
"children": [
{id:5,bank:'广发银行',company:'广东公司',quater:'第一季度',money:100,fee:200},
{id:6,bank:'广发银行',company:'广东公司',quater:'第二季度',money:500,fee:600},
],
"total":{bank:'广发银行合计',company:'',quater:'',money:600,fee:800}
}
},
"total":{bank:'',company:'广东公司合计',quater:'',money:900,fee:1300}
},
"湖南公司": {
"children": {
"中国银行": {
"children": [
{id:3,bank:'中国银行',company:'湖南公司',quater:'第一季度',money:300,fee:400},
{id:4,bank:'中国银行',company:'湖南公司',quater:'第二季度',money:400,fee:500},
],
"total":{bank:'中国银行合计',company:'',quater:'',money:700,fee:900}
},
"广发银行": {
"children": [
{id:7,bank:'广发银行',company:'湖南公司',quater:'第一季度',money:600,fee:700},
{id:8,bank:'广发银行',company:'湖南公司',quater:'第二季度',money:600,fee:700},
],
"total":{bank:'广发银行合计',company:'',quater:'',money:1200,fee:1400}
}
},
"total":{bank:'',company:'湖南公司合计',quater:'',money:1900,fee:2300}
}
}
// console.log(obj)
let finalData = [
{id:1,company:'广东公司', bank:'中国银行', quater:'第一季度',money:100,fee:200},
{id:2,company:'', bank:'', quater:'第二季度',money:200,fee:300},
{ company:'', bank:'中国银行合计',quater:'', money:300,fee:500},
{id:5,company:'', bank:'广发银行', quater:'第一季度',money:100,fee:200},
{id:6,company:'', bank:'', quater:'第二季度',money:500,fee:600},
{ company:'', bank:'广发银行合计',quater:'', money:600,fee:800},
{ company:'广东公司合计',bank:'', quater:'', money:900,fee:1300},
{id:3,company:'湖南公司', bank:'中国银行', quater:'第一季度',money:300,fee:400},
{id:4,company:'', bank:'', quater:'第二季度',money:400,fee:500},
{ company:'', bank:'中国银行合计',quater:'', money:700,fee:900},
{id:7,company:'', bank:'广发银行', quater:'第一季度',money:600,fee:700},
{id:8,company:'', bank:'', quater:'第二季度',money:600,fee:700},
{ company:'', bank:'广发银行合计',quater:'', money:1200,fee:1400},
{ company:'湖南公司合计',bank:'', quater:'', money:1900,fee:2300}
]
console