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

MUI DataGrid导出Excel样式设置与层级下拉框实现问题

问题1:MUI DataGrid导出Excel定制样式解决方案

默认GridToolbarExport没有直接配置导出样式的API,需通过自定义导出逻辑,借助xlsx库实现样式定制:

步骤1:安装依赖

确保已安装xlsx(用于处理Excel文件):

npm install xlsx

步骤2:自定义导出函数

替换默认导出行为,实现三个样式需求:

import * as XLSX from 'xlsx';
import { utils, writeFile } from 'xlsx';
import { useGridApiRef } from '@mui/x-data-grid';

const customExport = (apiRef: GridApiRef) => {
  // 获取当前表格的可见列与数据
  const visibleColumns = apiRef.current.getVisibleColumns();
  const rowIds = apiRef.current.getSortedRowIds();
  const rows = rowIds.map(id => apiRef.current.getRow(id));

  // 转换为工作表数据结构:第一行是表头,后续是内容
  const worksheetData = [
    visibleColumns.map(col => col.headerName),
    ...rows.map(row => visibleColumns.map(col => row[col.field]))
  ];

  const worksheet = utils.aoa_to_sheet(worksheetData);
  const range = utils.decode_range(worksheet['!ref'] || 'A1:Z100');

  // 1. 表头样式:加粗字体、背景色、自动换行
  for (let col = range.s.c; col <= range.e.c; col++) {
    const cellAddr = utils.encode_cell({ r: 0, c: col });
    worksheet[cellAddr] = {
      ...worksheet[cellAddr],
      s: {
        font: { bold: true },
        fill: { fgColor: { rgb: 'F0F0F0' } }, // 浅灰色背景
        alignment: { wrapText: true }
      }
    };
  }

  // 2. 内容单元格样式:自动换行、白色背景
  for (let row = 1; row <= range.e.r; row++) {
    for (let col = range.s.c; col <= range.e.c; col++) {
      const cellAddr = utils.encode_cell({ r: row, c: col });
      worksheet[cellAddr] = {
        ...worksheet[cellAddr],
        s: {
          alignment: { wrapText: true },
          fill: { fgColor: { rgb: 'FFFFFF' } }
        }
      };
    }
  }

  // 生成工作簿并下载
  const workbook = utils.book_new();
  utils.book_append_sheet(workbook, worksheet, 'Treatments');
  writeFile(workbook, 'treatments_export.xlsx');
};

// 修改Toolbar组件,注入自定义导出逻辑
const TreatmentsToolbarForEvent = ({event, usersFromOpen, setUsersFromOpen}: IProps) => {
  const apiRef = useGridApiRef();
  return (
    <GridToolbarContainer>
      {/* @ts-ignore */}
      <GridToolbarColumnsButton sx={{ "& .MuiButton-startIcon": { marginLeft: "5px" } }} />
      {/* @ts-ignore */}
      <GridToolbarFilterButton sx={{ "& .MuiButton-startIcon": { marginLeft: "5px" } }} />
      <GridToolbarExport
        sx={{ "& .MuiButton-startIcon": { marginLeft: "5px" } }}
        apiRef={apiRef}
        exportfunc={() => customExport(apiRef)}
      />
      <AddFormDialog entity={"treatments"} eventId={event.id} />
      <FormDialogUsers event={event} open={usersFromOpen} setOpen={setUsersFromOpen} />
    </GridToolbarContainer>
  );
};

关键样式说明

  • 自动换行:通过alignment.wrapText: true开启单元格文本换行
  • 背景色:使用fill.fgColor.rgb设置,十六进制颜色需去掉#并转为大写
  • 标题加粗:给表头单元格添加font.bold: true属性

问题2:DataGrid可编辑列实现层级选择(树形下拉)

默认singleSelect不支持层级结构,需自定义编辑单元格组件,结合MUI TreeView实现:

步骤1:准备层级数据结构

确保departmentOptions是带嵌套层级的数组,示例结构:

const departmentOptions = [
  { id: 'dept-1', name: '技术部', children: [
    { id: 'dept-1-1', name: '前端开发组' },
    { id: 'dept-1-2', name: '后端开发组' }
  ]},
  { id: 'dept-2', name: '人力资源部', children: [
    { id: 'dept-2-1', name: '招聘组' }
  ]}
];

步骤2:自定义层级选择编辑组件

import { TreeView, TreeItem } from '@mui/x-tree-view';
import { GridRenderEditCellParams } from '@mui/x-data-grid';

// 递归渲染树形选项,通过padding实现层级缩进
const renderTreeNodes = (nodes: any[], level = 0) => {
  return nodes.map(node => (
    <TreeItem
      key={node.id}
      nodeId={node.id}
      label={<span style={{ paddingLeft: `${level * 18}px` }}>{node.name}</span>}
    >
      {node.children && renderTreeNodes(node.children, level + 1)}
    </TreeItem>
  ));
};

// 自定义编辑单元格组件
const HierarchySelectEditCell = (params: GridRenderEditCellParams) => {
  return (
    <TreeView
      selected={params.value}
      onNodeSelect={(event, nodeId) => {
        // 更新单元格值
        params.api.current.setEditCellValue({
          id: params.id,
          field: params.field,
          value: nodeId
        });
        // 选择完成后退出编辑模式
        params.api.current.stopCellEditMode({ id: params.id, field: params.field });
      }}
    >
      {renderTreeNodes(departmentSelectDropDown())}
    </TreeView>
  );
};

// 修改列配置,替换默认单选下拉为自定义组件
const columns: GridColDef[] = [
  { 
    field: 'department', 
    headerName: strings().department, 
    flex: 1, 
    editable: isInSpecificEvent,
    // 移除默认的singleSelect配置,使用自定义编辑组件
    renderEditCell: (params) => <HierarchySelectEditCell {...params} />,
    renderCell: (params) => {
      // 递归查找选中项的名称,用于单元格显示
      const findNodeName = (nodes: any[], targetId: string): string => {
        for (const node of nodes) {
          if (node.id === targetId) return node.name;
          if (node.children) {
            const childName = findNodeName(node.children, targetId);
            if (childName) return childName;
          }
        }
        return '';
      };
      return findNodeName(departmentSelectDropDown(), params.row.department);
    }
  },
  // 其他列配置...
];

核心逻辑说明

  • 用TreeView实现层级选择,通过paddingLeft模拟层级缩进效果
  • 自定义renderEditCell替换默认的单选下拉组件
  • 实现递归函数匹配选中项名称,确保单元格正常显示层级文本
  • 选择完成后调用setEditCellValue更新数据并关闭编辑模式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:02:52