react-pdf

安装量: 246
排名: #3549

安装

npx skills add https://github.com/molefrog/skills --skill react-pdf
Generating PDFs with React-PDF
CRITICAL REQUIREMENTS
Fonts MUST be local files
- Remote font URLs (http/https) do NOT work. Always download fonts
to local files before using them.
Wrap async code in IIFE
- Top-level await causes errors. Always use
(async () => { ... })()
pattern.
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
npm
install
react @react-pdf/renderer
npm
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 . Basic Example 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: 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: // Good ( async ( ) => { await renderToFile ( < MyDocument /> , "./output.pdf" ) ; } ) ( ) ; // Bad - top-level await may fail await 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: pdftoppm -png -r 200 document.pdf preview

→ preview-1.png, preview-2.png, ...

Option 2: PyMuPDF (Python) — fallback if pdftoppm is not available: pip install pymupdf 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 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. 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 { // 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. 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 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: npm install lucide-static import { Svg , Path , Rect } from "@react-pdf/renderer" ; // Converted from lucide-static/icons/mail.svg const 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 < Link src = " https://example.com "

Visit website </ Text

</ Link

< View id = " section-1 "

Target </ Text

</ View

< Link src = "

section-1

"
>
Jump to Section 1
</
Text
>
</
Link
>
Dynamic Content and Page Numbers
<
Text
render
=
{
(
{
pageNumber
,
totalPages
}
)
=>
`
Page
${
pageNumber
}
of
${
totalPages
}
`
}
/>
Fixed Headers/Footers
<
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
<
View
break
/>
// Force page break
<
View
wrap
=
{
false
}
>
Keep together
</
Text
>
</
View
>
// Prevent breaking inside
<
Text
orphans
=
{
2
}
widows
=
{
2
}
>
Long text...
</
Text
>
// Orphan/widow control
<
View
minPresenceAhead
=
{
100
}
>
Content
</
Text
>
</
View
>
// Min space before break
Custom Fonts
CRITICAL: All font sources MUST be local file paths.
Remote URLs do not work.
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 fonts
Font
.
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:

Find the font URL

grep "^Roboto" skills/react-pdf/references/google-fonts.txt | grep "700" | grep "normal"

Download

mkdir -p fonts curl -sL "" -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.
npm
install
twemoji-emojis
import
{
Font
}
from
"@react-pdf/renderer"
;
Font
.
registerEmojiSource
(
{
format
:
"png"
,
url
:
"node_modules/twemoji-emojis/vendor/72x72/"
,
}
)
;
Then use emoji directly in Text:
Hello 🚀🎉
Other Features
// 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
>
// Hyphenation
Font
.
registerHyphenationCallback
(
(
word
)
=>
[
word
]
)
;
// disable
// Debug mode - visualize boundaries
<
View
debug
>
Debug text
</
Text
>
</
View
>
// Document metadata
<
Document
title
=
"
My Doc
"
author
=
"
Author
"
subject
=
"
Report
"
language
=
"
en-US
"
pdfVersion
=
"
1.5
"
/>
Best Practices
Use
StyleSheet.create()
— define styles once and reuse
Compress images before embedding, use
cache={true}
for remote images
Test page breaks — content may flow differently than expected
Prefer flexbox over absolute positioning
Use
fixed
prop for headers/footers on every page
Use
debug={true}
to visualize element boundaries
Wrap rendering in try-catch blocks
Common Issues
Text overflow
:
...
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 to force breaks.
返回排行榜