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

如何通过独立按钮导出Material-UI DataGrid数据至Excel(不使用Toolbar)

实现Material-UI DataGrid独立导出按钮(不使用自带Toolbar)

核心方案

通过DataGrid的apiRef获取表格当前的有效数据(包括经过筛选、排序后的行),将数据转换为可下载的CSV格式,再配合自定义的Material-UI Button作为独立导出控件,完全不需要依赖DataGrid自带的Toolbar组件。

实现步骤

  1. 引入所需依赖:除了DataGrid,还需要引入Material-UI的Button,以及useGridApiRef来获取表格实例的引用。
  2. 创建apiRef实例:将其传递给DataGrid组件,用于后续获取表格数据。
  3. 编写导出逻辑:
    • 通过apiRef.current.getRenderedRows()获取当前页面渲染的所有行(需要全量数据可用getRows())
    • 提取列的headerName作为CSV表头,提取行数据对应字段的值
    • 将表头和行数据拼接成CSV格式的字符串
    • 创建临时下载链接,触发浏览器下载操作
  4. 渲染独立按钮:在DataGrid外部放置自定义按钮,绑定导出函数。

完整代码示例

import { DataGrid, useGridApiRef } from "@material-ui/data-grid";
import Button from "@material-ui/core/Button";

const columns = [
  { field: "id", headerName: "ID", flex: 1 },
  { field: "firstName", headerName: "First name", flex: 1 },
  { field: "lastName", headerName: "Last name", flex: 1 },
  {
    field: "age",
    headerName: "Age",
    type: "number",
    flex: 1
  },
  {
    field: "fullName",
    headerName: "Full name",
    description: "This column has a value getter and is not sortable.",
    sortable: false,
    flex: 1,
    valueGetter: (params) =>
      `${params.getValue(params.id, "firstName") || ""} ${params.getValue(params.id, "lastName") || ""}`
  }
];

const rows = [
  { id: 1, lastName: "Snow", firstName: "Jon", age: 35 },
  { id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 },
  { id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 },
  { id: 4, lastName: "Stark", firstName: "Arya", age: 16 },
  { id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null },
  { id: 6, lastName: "Melisandre", firstName: null, age: 150 },
  { id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 },
  { id: 8, lastName: "Frances", firstName: "Rossini", age: 36 },
  { id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 }
];

export default function App() {
  const apiRef = useGridApiRef();

  // 导出数据为CSV的函数
  const exportToCSV = () => {
    // 获取当前渲染的所有行(需要全量数据改用apiRef.current.getRows())
    const rows = apiRef.current.getRenderedRows();
    if (!rows.length) return;

    // 提取CSV表头:使用列的headerName
    const headers = columns.map(col => col.headerName);
    // 提取行数据:处理valueGetter生成的列(比如fullName)
    const rowsData = rows.map(row => {
      return columns.map(col => {
        // 如果列有valueGetter,调用它获取值
        if (col.valueGetter) {
          return col.valueGetter({
            getValue: (id, field) => row[field],
            id: row.id,
            row
          });
        }
        // 普通列直接取对应字段值,空值处理为空字符串
        return row[col.field] ?? "";
      });
    });

    // 拼接CSV内容,处理逗号和引号转义
    const csvContent = [
      headers.join(","),
      ...rowsData.map(row => row.map(cell => `"${cell.toString().replace(/"/g, '""')}"`).join(","))
    ].join("\n");

    // 创建下载链接并触发下载
    const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.setAttribute("download", "data-grid-export.csv");
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  return (
    <>
      <div style={{ width: "100%", marginBottom: "16px" }}>
        {/* 独立导出按钮 */}
        <Button variant="contained" color="primary" onClick={exportToCSV}>
          导出数据
        </Button>
      </div>
      <div style={{ height: 400, width: "100%" }}>
        <DataGrid 
          rows={rows} 
          columns={columns} 
          pageSize={5} 
          checkboxSelection 
          apiRef={apiRef}
        />
      </div>
    </>
  );
}

注意事项

  • 若需导出全部数据(而非当前页面),将getRenderedRows()替换为apiRef.current.getRows()即可。
  • 代码处理了valueGetter生成的列,确保导出数据与表格显示一致。
  • 对CSV内容做了转义处理,避免包含逗号或引号的内容破坏CSV格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:10:40