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

如何将嵌套数组数据转换为Material UI DataGrid表格?

如何用Material UI DataGrid将嵌套数组数据转换为指定表格样式?

我从后端获取了包含嵌套数组的响应数据,想要将其转换为指定样式的表格,尝试使用Material UI DataGrid但在实现逻辑上遇到了问题,请求帮助。

响应数据示例

{
  "data": [
    {
      "id": "63ad33c69acfa205d354256b",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K111",
      "type": "rm",
      "current_price": 7718,
      "price": []
    },
    {
      "id": "63ad33c69acfa205d354256a",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K109",
      "type": "rm",
      "current_price": 7718,
      "price": []
    },
    {
      "id": "63ad33c69acfa205d3542565",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K103",
      "type": "rm",
      "current_price": 37259,
      "price": [
        { "date": "januari", "price": 37258.978184562315 },
        { "date": "februari", "price": 37258.978184562315 },
        { "date": "maret", "price": 37258.978184562315 },
        { "date": "april", "price": 37258.978184562315 },
        { "date": "mei", "price": 37258.978184562315 },
        { "date": "juni", "price": 37258.978184562315 },
        { "date": "juli", "price": 37258.978184562315 },
        { "date": "agustus", "price": 37258.978184562315 },
        { "date": "september", "price": 37258.978184562315 },
        { "date": "oktober", "price": 37258.978184562315 },
        { "date": "november", "price": 37258.978184562315 },
        { "date": "desember", "price": 37258.978184562315 }
      ]
    }
  ]
}

目标表格样式说明

目标表格为主行展示物料基础信息(物料编码、物料名称、工厂、当前价格等),点击主行的展开按钮后,在下方显示该物料对应的月度价格明细(12个月的日期和价格),形成嵌套展开的表格结构。

解决方案:使用Material UI DataGrid的行展开功能

可以直接利用DataGrid的detailPanel属性实现嵌套数据展示,无需复杂的数据扁平化处理,步骤如下:

1. 导入依赖

确保已安装Material UI DataGrid相关包:

npm install @mui/x-data-grid @mui/material @emotion/react @emotion/styled

2. 编写组件代码

import React from 'react';
import { DataGrid, GridColDef } from '@mui/x-data-grid';
import { Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';

// 模拟后端返回的数据
const responseData = {
  "data": [
    {
      "id": "63ad33c69acfa205d354256b",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K111",
      "type": "rm",
      "current_price": 7718,
      "price": []
    },
    {
      "id": "63ad33c69acfa205d354256a",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K109",
      "type": "rm",
      "current_price": 7718,
      "price": []
    },
    {
      "id": "63ad33c69acfa205d3542565",
      "material": "1000000000",
      "material_name": "SAMPEL",
      "plant": "K103",
      "type": "rm",
      "current_price": 37259,
      "price": [
        { "date": "januari", "price": 37258.978184562315 },
        { "date": "februari", "price": 37258.978184562315 },
        { "date": "maret", "price": 37258.978184562315 },
        { "date": "april", "price": 37258.978184562315 },
        { "date": "mei", "price": 37258.978184562315 },
        { "date": "juni", "price": 37258.978184562315 },
        { "date": "juli", "price": 37258.978184562315 },
        { "date": "agustus", "price": 37258.978184562315 },
        { "date": "september", "price": 37258.978184562315 },
        { "date": "oktober", "price": 37258.978184562315 },
        { "date": "november", "price": 37258.978184562315 },
        { "date": "desember", "price": 37258.978184562315 }
      ]
    }
  ]
};

const columns: GridColDef[] = [
  { field: 'material', headerName: '物料编码', width: 150 },
  { field: 'material_name', headerName: '物料名称', width: 150 },
  { field: 'plant', headerName: '工厂', width: 100 },
  { field: 'current_price', headerName: '当前价格', width: 150, type: 'number' },
];

const PriceDetailPanel = ({ row }: { row: any }) => {
  // 没有价格数据时提示
  if (row.price.length === 0) {
    return <div style={{ padding: 16 }}>无月度价格数据</div>;
  }

  // 渲染月度价格明细表格
  return (
    <TableContainer component={Paper}>
      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>月份</TableCell>
            <TableCell align="right">价格</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {row.price.map((item: any, index: number) => (
            <TableRow key={index}>
              <TableCell component="th" scope="row">{item.date}</TableCell>
              <TableCell align="right">{item.price.toFixed(2)}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
};

export default function MaterialPriceGrid() {
  return (
    <div style={{ height: 600, width: '100%' }}>
      <DataGrid
        rows={responseData.data}
        columns={columns}
        getRowId={(row) => row.id}
        detailPanel={[{
          render: (params) => <PriceDetailPanel row={params.row} />
        }]}
        // 可选:设置默认展开的行ID
        // defaultExpandedRowIds={['63ad33c69acfa205d3542565']}
      />
    </div>
  );
}

代码说明

  • 主表格配置:columns定义主行展示的基础字段,getRowId指定行的唯一标识,确保表格行的稳定性。
  • 展开面板:通过detailPanel属性配置展开内容,PriceDetailPanel组件接收当前行数据,渲染月度价格的子表格。
  • 空数据处理:当price数组为空时,显示提示文本,避免出现空面板影响体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:55:29