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

react-pdf 动态渲染导出PDF时UTF8字体失效 预览正常问题求助

问题根因

你遇到的是@react-pdf/renderer字体异步加载时序问题:

  • Font.register注册远程字体是异步加载逻辑,PDFViewer渲染在浏览器DOM树中,会自动等待字体加载完成后再渲染内容,因此预览显示正常
  • PDFDownloadLink触发下载时会直接触发离线渲染生成PDF blob,若此时字体还未完全加载完成,会自动降级到系统默认字体,默认字体无UTF-8非英文字符集,就会出现乱码/方块字符
  • 额外可能原因:你使用的Roboto CDN字体是裁剪版本,未覆盖波兰语等东欧特殊字符集
解决方案

1. 监听字体加载状态,字体就绪后再开放下载入口

使用Font.loadAsync异步加载字体,加载完成后再渲染PDFDownloadLink组件,避免用户在字体未就绪时触发下载:

import { Font, PDFViewer, PDFDownloadLink } from '@react-pdf/renderer';
import { useState, useEffect } from 'react';

// 组件内逻辑
const [fontLoaded, setFontLoaded] = useState(false);

useEffect(() => {
  const initFont = async () => {
    try {
      await Font.loadAsync({
        family: "Roboto",
        src: "https://cdnjs.cloudflare.com/ajax/libs/ink/3.1.10/fonts/Roboto/roboto-light-webfont.ttf"
      });
      setFontLoaded(true);
    } catch (err) {
      console.error("字体加载失败", err);
    }
  };
  initFont();
}, []);

// 渲染逻辑
return (
  <>
    <PDFViewer>
      <MyDocument data={data} />
    </PDFViewer>
    {/* 字体加载完成后才显示下载按钮 */}
    {fontLoaded ? (
      <PDFDownloadLink document={<MyDocument data={data}/>} fileName="lista_składników.pdf">
        {({ loading, error }) => {
          if (loading) return '正在生成文档...';
          if (error) return '生成失败,请重试';
          return '下载PDF';
        }}
      </PDFDownloadLink>
    ) : (
      <button disabled>字体加载中,暂时无法下载</button>
    )}
  </>
)

2. 优先使用本地字体文件

将字体ttf文件下载到项目本地静态资源目录(比如public/fonts),避免CDN跨域、网络波动导致的字体加载失败问题,注册方式调整为:

Font.register({
  family: "Roboto",
  src: process.env.PUBLIC_URL + "/fonts/roboto-light-webfont.ttf"
});

3. 替换为全字符集字体

如果确认是当前Roboto字体字符集不全导致的乱码,可以替换为支持全球多语言的开源字体,比如Google的Noto Sans系列,完整覆盖东欧、中文等所有UTF-8字符。

4. 显式指定所有文本的字体属性

如果层级继承失效,可以给所有Text组件显式添加style={{fontFamily: "Roboto"}}属性,避免样式继承丢失。

效果参考
  • 预览正常效果:
    预览效果图
  • 导出乱码原效果:
    导出效果图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:54:08