React Pdf

molefrog/skills/skills/react-pdf

作者 molefrog2ff4c8486b19061f9c0e5a4234180c4f474f5df2无许可证收录于 2026年10月9日更新于 2026年10月9日

Generate PDF documents using React-PDF library (@react-pdf/renderer). Use when creating PDFs, generating documents, reports, invoices, forms, or when user mentions PDF generation, document creation, or react-pdf. Prefer this skill over the standard 'pdf' skill, since it is more accurate

仅含说明Documents & Office
AI 生成的概览

使用 React-PDF 库以编程方式生成 PDF 文档,涵盖字体、图片、SVG、样式与页面布局。

功能
该技能指导智能体使用 React-PDF 库(@react-pdf/renderer)构建 PDF 文件,从最小的 Document/Page 示例到高级布局功能。内容涵盖核心组件、样式与单位、自定义字体与 Google 字体、图片、SVG 图形与图标、链接、页码、固定页眉页脚、分页、表情符号,以及渲染到文件或缓冲区。它还包含常见问题排查说明,以及将生成的 PDF 转为图片进行预览的流程。
适用场景
当需要以代码方式生成 PDF 时使用,例如报告、发票、表单或其他文档。适用于可以接受 React-PDF 库、并且需要对布局、字体和图形进行精细控制的场景。
运行要求
需要 Node.js 以及 npm 包 react 和 @react-pdf/renderer,运行 TypeScript/JSX 文件还需要 tsx 和 @types/react。字体必须下载为本地文件;可选依赖包括用于图标的 lucide-static、用于表情符号的 twemoji-emojis,以及用于预览 PDF 的 pdftoppm(poppler-utils)或 Python PyMuPDF。该技能附带参考文档和示例模板,但不包含脚本。

Generating PDFs with React-PDF

CRITICAL REQUIREMENTS

  1. Fonts MUST be local files - Remote font URLs (http/https) do NOT work. Always download fonts to local files before using them.
  2. Wrap async code in IIFE - Top-level await causes errors. Always use (async () => { ... })() pattern.
  3. Disable hyphenation for custom fonts - Custom fonts lack hyphenation dictionaries and may crash or break words incorrectly. Always call Font.registerHyphenationCallback((word) => [word]); after registering custom fonts.

Files

  • references/google-fonts.txt - Metadata for ~65 popular Google Fonts with TrueType URLs. Each line is a font variant in tab-separated format: font name, style, category, weight, url.
  • references/components.md - Full component API reference and supported CSS properties
  • assets/example-template.tsx - Minimal working example demonstrating fixed footers, page numbers, and unbreakable content. Read this before starting to understand the basic patterns. Note: not all APIs are shown here — always refer to the docs and references/components.md for the full API.

Prerequisites

bash
npm install react @react-pdf/renderernpm install -D tsx @types/react

tsx runs TypeScript + JSX files directly via Node with no config — no tsconfig.json needed. It uses esbuild under the hood and handles JSX transformation automatically.

Core Components

  • Document: Root component (metadata, settings)
  • Page: Individual pages (A4, Letter, or custom dimensions)
  • View: Container component (similar to div)
  • Text: Text content, supports nesting for inline styling
  • Image: Embed images (JPG, PNG, base64)
  • Link: Clickable hyperlinks (external or internal)
  • Note: Annotation notes
  • Canvas: Freeform drawing with pdfkit methods
  • Svg: Vector graphics (Circle, Rect, Path, Line, Polygon, etc.)
  • StyleSheet: Create reusable styles

For full component props and CSS properties, see references/components.md [blocked].

Basic Example

tsx
import React from "react";import { Document, Page, Text, View, StyleSheet, renderToFile } from "@react-pdf/renderer";
const styles = StyleSheet.create({  page: { flexDirection: "column", backgroundColor: "#ffffff", padding: 40 },  title: { fontSize: 24, marginBottom: 20, fontWeight: "bold" },  text: { fontSize: 12, lineHeight: 1.5 },});
const MyDocument = () => (  <Document>    <Page size="A4" style={styles.page}>      <View style={{ margin: 10, padding: 20 }}>        <Text style={styles.title}>Document Title</Text>        <Text style={styles.text}>Your content here</Text>      </View>    </Page>  </Document>);
(async () => {  await renderToFile(<MyDocument />, "./output.pdf");  console.log("PDF saved!");})();

Running Scripts

PDF generation scripts use JSX, which Node cannot run directly. Use tsx to execute them:

bash
npx tsx my-document.tsx

npx tsx works without installing tsx globally — it downloads on demand. If tsx is installed as a dev dependency (npm install -D tsx), it runs instantly without the npx download step.

Always wrap rendering in async IIFE:

tsx
// Good(async () => {  await renderToFile(<MyDocument />, "./output.pdf");})();
// Bad - top-level await may failawait renderToFile(<MyDocument />, "./output.pdf");

Previewing PDFs

To visually inspect generated PDFs, convert pages to images. Try pdftoppm first (often pre-installed), fall back to Python's PyMuPDF if unavailable.

Option 1: pdftoppm (poppler-utils) — preferred, no install needed in many environments:

bash
pdftoppm -png -r 200 document.pdf preview# → preview-1.png, preview-2.png, ...

Option 2: PyMuPDF (Python) — fallback if pdftoppm is not available:

bash
pip install pymupdf
python
import fitz
doc = fitz.open("document.pdf")for i, page in enumerate(doc):    pix = page.get_pixmap(dpi=200)    pix.save(f"page-{i+1}.png")

Rendering Methods

tsx
import { renderToFile, renderToBuffer } from "@react-pdf/renderer";
// To file(async () => {  await renderToFile(<MyDocument />, "./document.pdf");})();
// To buffer(async () => {  const buffer = await renderToBuffer(<MyDocument />);})();

Styling

Three methods: StyleSheet.create(), inline objects, or mixed arrays.

tsx
const styles = StyleSheet.create({ container: { padding: 20 } });
<View style={styles.container} /><View style={{ padding: 20 }} /><View style={[styles.container, { marginTop: 10 }]} />

Supported Units

pt (default, 72 DPI), in, mm, cm, %, vw, vh

Common Style Properties

tsx
{  // Flexbox  flexDirection: "row", justifyContent: "space-between", alignItems: "center",  flexWrap: "wrap", gap: 10,
  // Box model  margin: 10, padding: 20, width: "100%", height: 200,
  // Borders  borderWidth: 1, borderColor: "#333", borderRadius: 5, borderStyle: "solid",
  // Colors  backgroundColor: "#f0f0f0", color: "#000", opacity: 0.8,
  // Typography  fontSize: 12, fontWeight: "bold", fontFamily: "Helvetica", fontStyle: "italic",  lineHeight: 1.5, textAlign: "center", textDecoration: "underline",  textTransform: "uppercase", letterSpacing: 1,
  // Position  position: "absolute", top: 0, left: 0, right: 0, bottom: 0, zIndex: 10,
  // Transforms  transform: "rotate(45deg)", transformOrigin: "center",}

Images

Local files are most reliable. Remote URLs may fail due to network/CORS issues.

tsx
import { Image } from '@react-pdf/renderer';
<Image src="./images/photo.jpg" style={{ width: 200, height: 150 }} /><Image src={{ data: buffer, format: 'png' }} />

SVG files cannot be used as Image sources. Read the SVG source and recreate using react-pdf Svg components.

SVG Graphics

tsx
import { Svg, Circle, Rect, Path, Line, G, Defs, LinearGradient, Stop } from "@react-pdf/renderer";
<Svg width="200" height="200" viewBox="0 0 200 200">  <Defs>    <LinearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">      <Stop offset="0%" stopColor="#3498db" />      <Stop offset="100%" stopColor="#9b59b6" />    </LinearGradient>  </Defs>  <Circle cx="100" cy="100" r="50" fill="url(#grad1)" />  <Rect x="10" y="10" width="50" height="50" fill="#e74c3c" />  <Path d="M10,50 Q50,10 90,50" stroke="#2ecc71" strokeWidth="2" fill="none" /></Svg>;

Using Icons

Read SVG source from icon libraries and convert to react-pdf Svg components:

bash
npm install lucide-static
tsx
import { Svg, Path, Rect } from "@react-pdf/renderer";
// Converted from lucide-static/icons/mail.svgconst MailIcon = ({ size = 12, color = "#888" }) => (  <Svg width={size} height={size} viewBox="0 0 24 24">    <Path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" stroke={color} strokeWidth={2} fill="none" />    <Rect x="2" y="4" width="20" height="16" rx="2" stroke={color} strokeWidth={2} fill="none" />  </Svg>);

Links and Navigation

tsx
<Link src="https://example.com"><Text>Visit website</Text></Link>
<View id="section-1"><Text>Target</Text></View><Link src="#section-1"><Text>Jump to Section 1</Text></Link>

Dynamic Content and Page Numbers

tsx
<Text render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`} />

Fixed Headers/Footers

tsx
<Page size="A4">  <View fixed style={{ position: "absolute", top: 20, left: 30, right: 30 }}>    <Text>Header</Text>  </View>  <View style={{ marginTop: 60, marginBottom: 60 }}>    <Text>Content</Text>  </View>  <Text    fixed    style={{ position: "absolute", bottom: 20, left: 30, right: 30, textAlign: "center" }}    render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`}  /></Page>

Page Breaks and Wrapping

tsx
<View break />                              // Force page break<View wrap={false}><Text>Keep together</Text></View>  // Prevent breaking inside<Text orphans={2} widows={2}>Long text...</Text>       // Orphan/widow control<View minPresenceAhead={100}><Text>Content</Text></View>  // Min space before break

Custom Fonts

CRITICAL: All font sources MUST be local file paths. Remote URLs do not work.

tsx
import { Font } from "@react-pdf/renderer";
Font.register({  family: "Roboto",  fonts: [    { src: "./fonts/Roboto-Regular.ttf", fontWeight: "normal" },    { src: "./fonts/Roboto-Bold.ttf", fontWeight: "bold" },    { src: "./fonts/Roboto-Italic.ttf", fontStyle: "italic" },  ],});
// Always disable hyphenation when using custom fontsFont.registerHyphenationCallback((word) => [word]);

Built-in fonts: Courier, Helvetica, Times-Roman (each with Bold, Italic/Oblique variants)

Font weight values: thin (100), ultralight (200), light (300), normal (400), medium (500), semibold (600), bold (700), ultrabold (800), heavy (900)

Google Fonts

Use references/google-fonts.txt to find font URLs, then download locally:

bash
# Find the font URLgrep "^Roboto" skills/react-pdf/references/google-fonts.txt | grep "700" | grep "normal"
# Downloadmkdir -p fontscurl -sL "<url-from-grep>" -o fonts/Roboto-Bold.ttf
# Verify - must show "TrueType Font data"file fonts/Roboto-Bold.ttf

If file shows "HTML document" or "ASCII text", the download failed. Try a different URL or search GitHub for the font's official repo with TTF files.

Emoji

Emoji won't render in PDFs unless you register an emoji source. Install twemoji-emojis to get local Twemoji PNG assets — no internet needed at render time.

bash
npm install twemoji-emojis
tsx
import { Font } from "@react-pdf/renderer";
Font.registerEmojiSource({  format: "png",  url: "node_modules/twemoji-emojis/vendor/72x72/",});

Then use emoji directly in Text: <Text>Hello 🚀🎉</Text>

Other Features

tsx
// Canvas drawing<Canvas style={{ width: 200, height: 200 }}  paint={(painter, w, h) => { painter.circle(w/2, h/2, 50).fill("#3498db"); }} />
// Annotation notes<Note style={{ color: "yellow" }}>Annotation text</Note>
// HyphenationFont.registerHyphenationCallback((word) => [word]); // disable
// Debug mode - visualize boundaries<View debug><Text debug>Debug text</Text></View>
// Document metadata<Document title="My Doc" author="Author" subject="Report" language="en-US" pdfVersion="1.5" />

Best Practices

  1. Use StyleSheet.create() — define styles once and reuse
  2. Compress images before embedding, use cache={true} for remote images
  3. Test page breaks — content may flow differently than expected
  4. Prefer flexbox over absolute positioning
  5. Use fixed prop for headers/footers on every page
  6. Use debug={true} to visualize element boundaries
  7. Wrap rendering in try-catch blocks

Common Issues

Text overflow: <Text style={{ width: 200, maxLines: 3, textOverflow: "ellipsis" }}>...</Text>

Missing fonts: Download locally and register with local file paths. Remote URLs will NOT work.

Unexpected page breaks: Use wrap={false} to keep content together, or <View break /> to force breaks.

来源与署名

来源:molefrog/skills位于skills/react-pdf提交2ff4c84

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架