React-PDF 详解:API 要点与在线简历项目中的落地

适合:已经会一点 React,想在前端用代码生成 PDF(简历、小票、报告、证书等),还不熟悉 @react-pdf/renderer 的读者。

官方文档:https://react-pdf.org/

参考网站:https://beautyresume.com


一、它是什么?和「打印网页」有什么区别

  • @react-pdf/renderer:用 React 组件描述 PDF 的每一页、每一块文字和布局,在浏览器或 Node 里排版并输出 PDF 文件(常见是 Blob,再触发下载)。
  • 浏览器「打印 → 另存为 PDF」:那是把 HTML/CSS 交给打印引擎,版式受浏览器影响大,难做到像素级可控。
  • React-PDF:版式主要由 Flex(类似 React Native 的子集)控制,不是完整 Chrome CSS。学会「用 View 搭盒子、用 Text 写字」就能上手。

二、安装

在项目根目录执行(npm / yarn / pnpm 任选其一):

npm install @react-pdf/renderer

版本以官方当前稳定版为准;大版本升级时以 changelog 为准做回归。


三、第一个 PDF:Document → Page → Text

新建一个组件(名字随意),结构永远是:

  1. 最外层:<Document> ------ 表示「整份 PDF」。
  2. 里面至少一个:<Page> ------ 表示「一页纸」,常用 size="A4"
  3. 页里写内容:<Text><View> 等。
javascript 复制代码
import { Document, Page, Text, View, StyleSheet, PDFDownloadLink } from '@react-pdf/renderer';

const styles = StyleSheet.create({
  page: {
    padding: 40,
    fontSize: 12,
  },
  title: {
    fontSize: 20,
    marginBottom: 12,
  },
});

function MyFirstPdf() {
  return (
    <Document>
      <Page size="A4" style={styles.page}>
        <Text style={styles.title}>你好,PDF</Text>
        <Text>这是第一段正文。</Text>
      </Page>
    </Document>
  );
}

export function App() {
  return (
    <PDFDownloadLink document={<MyFirstPdf />} fileName="demo.pdf">
      {({ loading }) => (loading ? '生成中...' : '下载 PDF')}
    </PDFDownloadLink>
  );
}

运行后点击链接,浏览器会下载 demo.pdf

要点:

  • Document 下必须有 Page,否则不合法。
  • StyleSheet.create({...}) 里写样式,单位上 fontSize 一般按「点 pt」理解(和 Word 里字号习惯接近)。

四、布局核心:把 View 当成 div + Flex

React-PDF 里没有 div,块级容器用 View。排版主要靠 Flex(默认列方向可改):

javascript 复制代码
const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 8,
  },
  box: {
    width: '45%',
    padding: 8,
    borderWidth: 1,
    borderColor: '#ccc',
  },
});

// 在 <Page> 里:
<View style={styles.row}>
  <View style={styles.box}>
    <Text>左侧</Text>
  </View>
  <View style={styles.box}>
    <Text>右侧</Text>
  </View>
</View>

初学者记住三句话:

  1. View 分区,再在分区里放 Text
  2. width / height 能写数字就写数字;百分比在部分场景可用,复杂时优先明确尺寸。
  3. 多页 = 多个 <Page>,或内容太高时由库分页(与模板结构有关)。

五、样式常用属性(够用版)

用途 属性示例
内边距 padding: 24
外边距 marginBottom: 12
字号 fontSize: 11
字重 fontWeight: 'bold'
颜色 color: '#333333'
行高 lineHeight: 1.5
背景 backgroundColor: '#f5f5f5'
边框 borderWidth, borderColor

和网页 CSS 不一致的地方:很多选择器、浮动、Grid 等没有或行为不同;以 Flex 为主最省心。


六、中文与自定义字体(必看)

内置字体对 中文、日文 支持往往不够,会出现方框或乱码。要用 Font.register 注册自己的字体文件(.ttf / .otf),再在 StyleSheet 里写 fontFamily(与注册时的 family 一致)。

javascript 复制代码
import { Font, Document, Page, Text, StyleSheet } from '@react-pdf/renderer';

Font.register({
  family: 'MyCN',
  src: 'https://你的CDN或静态站/字体/NotoSansSC-Regular.ttf',
});

Font.register({
  family: 'MyCN',
  src: 'https://你的CDN或静态站/字体/NotoSansSC-Bold.ttf',
  fontWeight: 'bold',
});

const styles = StyleSheet.create({
  page: {
    padding: 40,
    fontFamily: 'MyCN',
    fontSize: 11,
  },
});

注意:

  • Regular 和 Bold 一般要分别注册(fontWeight 不同)。
  • 字体 URL 必须浏览器能访问;若字体在你自己服务器上,注意 CORS。
  • 字体文件可能很大,生产环境常用 子集字体 减小体积(字体工具另学即可)。

七、不用「下载链接」:用 pdf() 自己拿 Blob

按钮点击后生成再下载,更适合和表单状态绑在一起:

javascript 复制代码
import { pdf, Document, Page, Text } from '@react-pdf/renderer';

async function handleDownload() {
  const blob = await pdf(
    <Document>
      <Page size="A4">
        <Text>动态内容:{new Date().toLocaleString()}</Text>
      </Page>
    </Document>
  ).toBlob();

  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'report.pdf';
  a.click();
  URL.revokeObjectURL(url);
}

pdf(...) 还支持 .toBuffer()(Node)等,见官方 API。


八、在页面里「预览」PDF(进阶一小步)

下载前先预览,常见两种思路:

  1. PDFViewer(若当前版本仍提供):直接把 <Document> 嵌进去,适合快速原型。
  2. usePDF hook:生成 blob URL,再配合 react-pdf(pdf.js)在 <canvas> 里画出来,自定义程度高。

react-pdf 时务必配置 worker,否则容易白屏或报错:

import { pdfjs } from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.min.mjs'; // 从 node_modules 拷贝到 public

具体路径以官方 react-pdf 文档为准。


九、初学者最常踩的坑

  1. 忘包 Document / Page → 直接报错或空白。
  2. 中文没注册字体 → 方块字。
  3. 把网页 CSS 照搬进来 → 大量无效;改学 Flex + 官方支持的属性列表。
  4. Text 里嵌套复杂结构 → 尽量扁平:多段就用多个 Text 或多个 View 包一层。
  5. 图片不显示 → 检查 URL、HTTPS、CORS;本地 file:// 常有限制。
  6. 升级大版本 → 先看 breaking changes,PDF 类项目建议锁小版本并做好样张回归。

十、建议你练手的顺序

  1. 单页 A4:Text + View flex 排一版简单简历壳子。
  2. 接上 Font.register,把中文跑通。
  3. pdf().toBlob() 做下载按钮。
  4. 把「姓名、电话」等改成 props,体会数据驱动。
  5. 再学 Image、多 Page、或官方示例里的表格模式。

官方示例仓库:https://github.com/diegomura/react-pdf/tree/master/packages/renderer/examples


小结

  • DocumentPageView / Text 搭结构。
  • StyleSheet.create + Flex 控制版式。
  • 中文必须 Font.register
  • 下载用 PDFDownloadLinkpdf().toBlob() 均可。

把以上几步跑通,你就具备了在真实项目里接「动态数据生成 PDF」的基础;之后再学分页、页眉页脚、复杂表格即可。

相关推荐
Bigger2 小时前
第九章:我是如何剖析 Claude Code 的 CLI 里的安全沙盒与指令拦截机制的
前端·claude·源码阅读
得想办法娶到那个女人2 小时前
Vue3 组合式API 标准写法(通俗易懂,可直接复制)
前端·javascript·vue.js
_深海凉_2 小时前
LeetCode热题100-最长公共子序列
java·开发语言·前端
ONLYOFFICE2 小时前
11款Linux PDF编辑工具横评|开源、免费为主
linux·pdf·onlyoffice
蓝天客2 小时前
接入支付 FM 接口实战经验
前端
liyi_hz20082 小时前
O2OA V10 升级说明(二)内容管理:更安全、更融合、更适配移动办公
java·前端·数据库
a1117762 小时前
PascalEditor( 3D建筑编辑器 开源)
前端·开源·html
爱上好庆祝2 小时前
移动端适配
前端·css·学习·html·css3
overmind2 小时前
oeasy Python 123 元组_运算_封包解包_欢乐颂_大写数字
java·前端·python