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

是否可以对MUI Material Table的默认PDF导出功能进行样式自定义?

MUI Material Table 自定义样式PDF导出实现方案

实现思路

Material Table 内置的默认PDF导出仅支持表格内容的基础导出,无法满足多模块自定义内容的需求,因此我们需要替换默认导出逻辑,结合jsPDF+jspdf-autotable库实现完全自定义的PDF内容排版。

前置依赖安装

npm install jspdf jspdf-autotable
# 若需要渲染页面元素为图片可额外安装html2canvas
npm install html2canvas

核心实现步骤

  1. 禁用默认导出,新增自定义导出按钮
    在Material Table的actions配置中添加自定义导出按钮,关闭默认的export功能:
import MaterialTable from '@material-table/core';
import { ExportToPdf } from '@mui/icons-material';

<MaterialTable
  // 其他基础配置
  options={{
    exportButton: false, // 关闭默认导出
  }}
  actions={[
    {
      icon: () => <ExportToPdf />,
      tooltip: '自定义导出PDF',
      onClick: (event, rowData) => handleExportPdf(rowData), // 行级导出,全量导出可放到toolbar
      isFreeAction: true, // 设为true则按钮放在顶部工具栏
    }
  ]}
/>
  1. 编写自定义导出逻辑
    以下是包含logo、多信息模块、表格的导出逻辑示例:
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';

// 提前把logo转成base64,避免跨域无法加载
const LOGO_BASE64 = '你的logo base64字符串';

const handleExportPdf = (data) => {
  const doc = new jsPDF('p', 'mm', 'a4'); // p=纵向,单位mm,A4尺寸
  const pageWidth = doc.internal.pageSize.getWidth();

  // 1. 渲染顶部logo
  doc.addImage(LOGO_BASE64, 'PNG', 14, 10, 30, 30);
  // 渲染右上角ID信息
  doc.setFontSize(12);
  doc.text(`订单ID:${data.orderId}`, pageWidth - 14, 15, { align: 'right' });
  doc.text(`导出时间:${new Date().toLocaleString()}`, pageWidth -14, 22, { align: 'right' });

  // 2. 渲染学生信息模块
  doc.setFontSize(14);
  doc.setFont('helvetica', 'bold');
  doc.text('学生信息', 14, 50);
  doc.setFont('helvetica', 'normal');
  doc.setFontSize(12);
  doc.text(`姓名:${data.student.name}`, 14, 58);
  doc.text(`年级:${data.student.grade}`, 14, 66);
  doc.text(`学号:${data.student.studentNo}`, 80, 58);
  doc.text(`联系电话:${data.student.phone}`, 80, 66);

  // 3. 渲染用户信息模块
  doc.setFontSize(14);
  doc.setFont('helvetica', 'bold');
  doc.text('用户信息', 14, 80);
  doc.setFont('helvetica', 'normal');
  doc.setFontSize(12);
  doc.text(`账号:${data.user.account}`, 14, 88);
  doc.text(`注册时间:${data.user.registerTime}`, 14, 96);
  doc.text(`所属机构:${data.user.org}`, 80, 88);

  // 4. 渲染订单表格
  autoTable(doc, {
    startY: 110, // 表格开始的Y轴位置
    head: [['订单商品', '单价', '数量', '实付金额', '购买时间']],
    body: data.orderList.map(item => [item.goodsName, item.price, item.count, item.payAmount, item.buyTime]),
    headStyles: {
      fillColor: '#1976d2', // 和MUI主题色保持一致
      textColor: '#fff',
    },
    styles: {
      fontSize: 10,
      cellPadding: 3,
    },
    margin: { left: 14, right: 14 },
    didDrawPage: (data) => {
      // 页脚内容,分页时自动添加
      doc.setFontSize(10);
      doc.text(`第 ${doc.internal.getNumberOfPages()} 页`, pageWidth / 2, doc.internal.pageSize.getHeight() - 10, { align: 'center' });
    }
  })

  // 保存PDF
  doc.save(`订单_${data.orderId}.pdf`);
}

常见问题处理

  • 中文乱码:需要给jsPDF引入支持中文的字体库,把ttf字体转成base64后通过doc.addFont()方法加载即可。
  • 分页适配:jspdf-autotable会自动处理表格内容的分页,可通过didDrawPage钩子统一添加页眉页脚。
  • 复杂样式渲染:如果有更复杂的排版需求,可以先用html写好模板,通过html2canvas转成图片后插入到PDF中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:36:04