SOURCE

let tableData = [
  {id:1,bank:'中国银行',company:'广东公司',quater:'第一季度',werks:'广东科技',money:100,fee:200},
  {id:2,bank:'中国银行',company:'广东公司',quater:'第二季度',werks:'贵阳联塑',money:200,fee:300},
  {id:9,bank:'建设银行',company:'湖南公司',quater:'第二季度',werks:'广东科技',money:600,fee:700},
  {id:3,bank:'中国银行',company:'湖南公司',quater:'第一季度',werks:'广东科技',money:300,fee:400},
  {id:4,bank:'中国银行',company:'湖南公司',quater:'第二季度',werks:'武汉联塑',money:400,fee:500},
  {id:5,bank:'广发银行',company:'广东公司',quater:'第一季度',werks:'广东科技',fee:200},
  {id:6,bank:'广发银行',company:'广东公司',quater:'第二季度',werks:'贵阳联塑',money:500,fee:600},
  {id:7,bank:'广发银行',company:'湖南公司',quater:'第一季度',werks:'广东科技',money:600,fee:700},
  {id:8,bank:'广发银行',company:'湖南公司',quater:'第二季度',werks:'武汉联塑',money:600,fee:700},
  {id:10,bank:'广发银行',company:'湖南公司',quater:'第三季度',werks:'广东科技',money:600,fee:700},
  {id:11,bank:'广发银行',company:'湖南公司',quater:'第三季度',werks:'武汉联塑',money:1600,fee:700},

]
const subtotalFields = ["bank", "company"];
const quatoFields = ["money", "fee"];
function subtotal({ data, subtotalFields, quatoFields }) {
  const res = [];
//   const subtotalFieldsObj = Object.fromEntries(subtotalFields.map((item) => [item, ""]));
  const total = (function dfs(items, i) {
    const total = Object.fromEntries(quatoFields.map((k) => [k, 0]));
    if (i == subtotalFields.length) {
      items.forEach((item) => {
        quatoFields.forEach((k) =>{
            if(!item[k]){
                item[k]=0
            }
            total[k] += +item[k]
            });
      });
      res.push(...items);
    } else {
      const k = subtotalFields[i++];
      items
        .reduce((map, item) => {
          const feature = item[k];
          if (map.has(feature)) {
            item[k] = item[k];
          } else {
            map.set(feature, []);
          }
          map.get(feature).push(item);
          return map;
        }, new Map())
        .forEach((items, feature) => {
          const sub = dfs(items, i);
          console.log(items)
          console.log(i)
          const obj =  Object.fromEntries(subtotalFields.filter(item=>item!==subtotalFields[i-1])
          .map(item=>i==1?[item,'']:[item,items[0][item]]))
          console.log(obj)
          console.log('=======')
          if(i!==1&& i !== subtotalFields.length){
              for(let index = i;index<subtotalFields.length;index++){
                obj[subtotalFields[index]] = ''
              }
          }
        res.push({...obj,[k]: feature + "小计", ...sub });

          quatoFields.forEach((k) => (total[k] += sub[k]));
        });
    }
    return total;
  })(data.map((item) => ({ ...item })), 0);
  return [res, total];
}

const [res, total] = subtotal({
  data: tableData,
  subtotalFields: ["bank",'company','quater','werks'],
  quatoFields: ["money", "fee"],
});

console.log(res);
console.log("总计", total);
console 命令行工具 X clear

                    
>
console