You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JS和MUI X Data Grid将数据转为交叉表样式?

问题:MUI X Data Grid 交叉表样式调整

使用MUI X Data Grid展示数据时出现两个问题:日期列重复显示同一日期,Charge列未正确计算为该行其他单元格的总和。需要调整为交叉表样式:每个日期仅在日期列显示一次,其余数据横向排列,Charge为行内所有数据的总和。


现有DataGrid组件代码

<DataGrid
    rows={recon_rows} 
    columns={recon_columns} 
/>

当前数据处理代码

var recon_rows = [];
var recon_columns = [];
var setHeaders = new Set();
var setDate = new Set();

for(let i = 0; i < reportData.length; i++) {
  setHeaders.add(reportData[i].hdrname);
  setDate.add(reportData[i].recondate);
}

recon_columns = [
  { field: 'col1', headerName: 'Date', minWidth: 100 },
  { field: 'col2', headerName: 'Charge', minWidth: 100 },
];

for(var headers of setHeaders) {
  recon_columns.push({
    field: headers,
    headerName: headers,
    minWidth: 150
  });

  for(var dates of setDate) {
    var charge = 0;
    for(var i = 0; i < reportData.length; i++) {
      if(reportData[i].hdrname === headers && reportData[i].recondate === dates) {
        charge += reportData[i].entryqty;
        recon_rows.push({
          id: Math.random(dates),
          col1: dates,
          col2: charge,
          [headers]: charge
        });
      }
    }
  }
}

数据示例

[
{
    "recondate": "2022-07-19",
    "entryclass": 1,
    "entryid": 1,
    "entryqty": 16,
    "entrycharge": 160,
    "entryseq": 10001,
    "hdrname": "SERV-Major-2S"
},
{
    "recondate": "2022-07-21",
    "entryclass": 1,
    "entryid": 1,
    "entryqty": 5,
    "entrycharge": 50,
    "entryseq": 10001,
    "hdrname": "SERV-Major-2S"
}
// 其余数据格式一致
]

解决方案

问题根源是数据处理逻辑错误:嵌套循环导致同一日期被多次推入recon_rows,且Charge仅计算单个列的数值而非整行总和。以下是修正后的代码:

修正后的数据处理代码

var recon_rows = [];
var recon_columns = [];
var setHeaders = new Set();
var dateMap = new Map();

// 1. 收集表头并按日期分组数据
reportData.forEach(item => {
  setHeaders.add(item.hdrname);
  // 初始化日期分组
  if (!dateMap.has(item.recondate)) {
    dateMap.set(item.recondate, {
      date: item.recondate,
      charge: 0,
      columns: {}
    });
  }
  const dateEntry = dateMap.get(item.recondate);
  // 填充对应列的数值
  dateEntry.columns[item.hdrname] = item.entryqty;
  // 累加当前日期的Charge总和
  dateEntry.charge += item.entryqty;
});

// 2. 构建列配置
recon_columns = [
  { field: 'date', headerName: 'Date', minWidth: 100 },
  { field: 'charge', headerName: 'Charge', minWidth: 100 },
];
// 添加动态列
setHeaders.forEach(header => {
  recon_columns.push({
    field: header,
    headerName: header,
    minWidth: 150
  });
});

// 3. 转换为DataGrid所需的行格式
dateMap.forEach((entry, index) => {
  const row = {
    id: index + 1, // 用索引生成唯一ID,避免随机数重复
    date: entry.date,
    charge: entry.charge
  };
  // 合并列数据到行对象
  Object.assign(row, entry.columns);
  recon_rows.push(row);
});

修正说明

  1. 按日期分组:使用Map按recondate分组,确保每个日期仅生成一行数据
  2. 正确计算Charge:分组时直接累加当前日期下所有entryqty的总和
  3. 动态列填充:遍历分组后的列数据,将对应表头的数值填充到行对象
  4. 唯一ID生成:用索引替代Math.random,避免ID重复导致的渲染异常

内容的提问来源于stack exchange,提问作者Paw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:36:16