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

如何将MUI组件转换为PDF?遇useInsertionEffect错误求助

解决方案

错误原因分析

  1. React版本不兼容:useInsertionEffect是React 18新增的钩子,你的项目当前使用的React版本低于18,而@react-pdf/renderer或MUI的依赖版本要求React 18,导致报错。
  2. 组件混用错误:@react-pdf/renderer有自己独立的组件体系(如内置的排版组件),不能直接将MUI的<Typography>组件放入@react-pdf的<Document>/<Page>中渲染,两者的渲染环境不兼容。

方案一:升级React版本并使用@react-pdf原生组件

1. 升级React到18

执行以下命令升级依赖:

npm install react@^18 react-dom@^18

若使用Yarn:

yarn add react@^18 react-dom@^18

2. 替换MUI组件为@react-pdf原生组件

修改PDF组件代码,使用@react-pdf/renderer内置的<Text>组件复刻MUI样式:

import { Document, Page, View, Text, StyleSheet } from '@react-pdf/renderer';

const styles = StyleSheet.create({
  page: {
    padding: 30,
  },
  section: {
    marginBottom: 10,
  },
  heading: {
    fontSize: 24, // 匹配MUI h5字号
    fontWeight: 'bold',
  },
});

const MyPdf = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text style={styles.heading}>Hello World</Text>
      </View>
    </Page>
  </Document>
);

3. 保留原打开PDF的函数

你的openPdf函数可继续使用:

import { pdf } from '@react-pdf/renderer';

async function openPdf() {
  const pdfBlob = await pdf(<MyPdf />).toBlob();
  const pdfUrl = URL.createObjectURL(pdfBlob);
  const pdfWindow = window.open(pdfUrl, '_blank');
  if (pdfWindow) {
    pdfWindow.document.title = 'My PDF Document';
  }
}

方案二:不升级React,降级@react-pdf版本并调整组件

若无法升级React到18,可降级@react-pdf/renderer到不依赖useInsertionEffect的版本:

1. 降级@react-pdf/renderer

npm install @react-pdf/renderer@^2.2.0

2. 调整PDF组件代码

同样使用@react-pdf原生组件复刻MUI样式:

import { Document, Page, View, Text, StyleSheet } from '@react-pdf/renderer';

const styles = StyleSheet.create({
  page: { padding: 30 },
  section: { marginBottom: 10 },
  h5: {
    fontSize: 24,
    fontWeight: 600, // 匹配MUI h5字重
  },
});

const MyPdf = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={styles.section}>
        <Text style={styles.h5}>Hello World</Text>
      </View>
    </Page>
  </Document>
);

方案三:将MUI组件渲染为HTML后转PDF

若需完全保留MUI组件样式,可先渲染为HTML再转换:

1. 安装依赖

npm install html2canvas jspdf

2. 编写转换函数

import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';

async function openPdf() {
  // 获取MUI组件的DOM元素(需给组件添加id)
  const muiElement = document.getElementById('mui-typography');
  if (!muiElement) return;

  const canvas = await html2canvas(muiElement);
  const imgData = canvas.toDataURL('image/png');
  
  const pdf = new jsPDF('p', 'mm', 'A4');
  const imgWidth = 210; // A4宽度
  const pageHeight = 297;
  const imgHeight = (canvas.height * imgWidth) / canvas.width;
  let heightLeft = imgHeight;
  let position = 0;

  pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
  heightLeft -= pageHeight;

  while (heightLeft >= 0) {
    position = heightLeft - imgHeight;
    pdf.addPage();
    pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
    heightLeft -= pageHeight;
  }

  // 打开PDF
  pdf.output('blob').then(blob => {
    const pdfUrl = URL.createObjectURL(blob);
    const pdfWindow = window.open(pdfUrl, '_blank');
    if (pdfWindow) {
      pdfWindow.document.title = 'My PDF Document';
    }
  });
}

// 带id的MUI组件
const MuiComponent = () => (
  <div id="mui-typography">
    <Typography component="h6" variant="h5">Hello World</Typography>
  </div>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:12:42