react-pdf
React-PDFライブラリ(@react-pdf/renderer)を使用してPDFドキュメントを生成します。PDF作成、レポート・請求書・フォームなどのドキュメント生成が必要な場合や、ユーザーがPDF生成・react-pdfについて言及した際に使用します。標準の「pdf」スキルより精度が高いため、こちらを優先して使用してください。
description の原文を見る
"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"
SKILL.md 本文
React-PDFでPDFを生成する
重要な要件
- フォントはローカルファイルである必要があります - リモートフォントURL(http/https)は動作しません。使用する前に必ずフォントをローカルファイルにダウンロードしてください。
- 非同期コードをIIFEでラップします - トップレベルのawaitはエラーを引き起こします。常に
(async () => { ... })()パターンを使用してください。 - カスタムフォントのハイフネーションを無効にします - カスタムフォントはハイフネーション辞書を持たず、クラッシュしたり単語を誤って分割したりする可能性があります。カスタムフォント登録後、常に
Font.registerHyphenationCallback((word) => [word]);を呼び出してください。
ファイル
references/google-fonts.txt- 約65個の一般的なGoogleフォントのメタデータ。各行はタブ区切り形式のフォントバリアント:フォント名、スタイル、カテゴリ、ウェイト、url。references/components.md- 完全なコンポーネントAPIリファレンスとサポートされるCSSプロパティassets/example-template.tsx- 固定フッター、ページ番号、改行不可コンテンツを示す最小限の動作例。開始前に読んで基本パターンを理解してください。注:すべてのAPIがここに示されているわけではありません。完全なAPIについては常にドキュメントとreferences/components.mdを参照してください。
前提条件
npm install react @react-pdf/renderer
npm install -D tsx @types/react
tsxは設定なしでNode経由でTypeScript + JSXファイルを直接実行します — tsconfig.jsonは不要です。内部ではesbuildを使用しており、JSX変換を自動的に処理します。
コアコンポーネント
- Document: ルートコンポーネント(メタデータ、設定)
- Page: 個別ページ(A4、Letter、またはカスタムサイズ)
- View: コンテナコンポーネント(divに類似)
- Text: テキストコンテンツ、インラインスタイル設定用のネスティング対応
- Image: 画像埋め込み(JPG、PNG、base64)
- Link: クリック可能なハイパーリンク(外部または内部)
- Note: 注釈ノート
- Canvas: pdfkitメソッドによる自由形式描画
- Svg: ベクターグラフィック(Circle、Rect、Path、Line、Polygonなど)
- StyleSheet: 再利用可能なスタイルの作成
完全なコンポーネントプロップとCSSプロパティについては、references/components.mdを参照してください。
基本的な例
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}>ドキュメントタイトル</Text>
<Text style={styles.text}>ここにコンテンツが入ります</Text>
</View>
</Page>
</Document>
);
(async () => {
await renderToFile(<MyDocument />, "./output.pdf");
console.log("PDFが保存されました!");
})();
スクリプト実行
PDF生成スクリプトはJSXを使用し、Nodeは直接実行できません。tsxを使用して実行してください:
npx tsx my-document.tsx
npx tsxはtsxをグローバルにインストールせずに動作します — 必要に応じてダウンロードされます。tsxが開発依存関係としてインストールされている場合(npm install -D tsx)、npxダウンロードステップなしに即座に実行されます。
常にレンダリングを非同期IIFEでラップしてください:
// 正しい
(async () => {
await renderToFile(<MyDocument />, "./output.pdf");
})();
// 間違い - トップレベルのawaitは失敗する可能性があります
await renderToFile(<MyDocument />, "./output.pdf");
PDFのプレビュー
生成されたPDFを視覚的に検査するには、ページを画像に変換します。まずpdftoppmを試し、利用できない場合はPythonのPyMuPDFにフォールバックしてください。
オプション1:pdftoppm (poppler-utils) — 推奨、多くの環境にインストール不要:
pdftoppm -png -r 200 document.pdf preview
# → preview-1.png, preview-2.png, ...
オプション2:PyMuPDF (Python) — pdftoppmが利用できない場合のフォールバック:
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")
レンダリングメソッド
import { renderToFile, renderToBuffer } from "@react-pdf/renderer";
// ファイルへ
(async () => {
await renderToFile(<MyDocument />, "./document.pdf");
})();
// バッファへ
(async () => {
const buffer = await renderToBuffer(<MyDocument />);
})();
スタイリング
3つの方法:StyleSheet.create()、インラインオブジェクト、または混合配列。
const styles = StyleSheet.create({ container: { padding: 20 } });
<View style={styles.container} />
<View style={{ padding: 20 }} />
<View style={[styles.container, { marginTop: 10 }]} />
サポートされる単位
pt(デフォルト、72 DPI)、in、mm、cm、%、vw、vh
一般的なスタイルプロパティ
{
// フレックスボックス
flexDirection: "row", justifyContent: "space-between", alignItems: "center",
flexWrap: "wrap", gap: 10,
// ボックスモデル
margin: 10, padding: 20, width: "100%", height: 200,
// ボーダー
borderWidth: 1, borderColor: "#333", borderRadius: 5, borderStyle: "solid",
// 色
backgroundColor: "#f0f0f0", color: "#000", opacity: 0.8,
// タイポグラフィ
fontSize: 12, fontWeight: "bold", fontFamily: "Helvetica", fontStyle: "italic",
lineHeight: 1.5, textAlign: "center", textDecoration: "underline",
textTransform: "uppercase", letterSpacing: 1,
// 位置
position: "absolute", top: 0, left: 0, right: 0, bottom: 0, zIndex: 10,
// トランスフォーム
transform: "rotate(45deg)", transformOrigin: "center",
}
画像
ローカルファイルが最も確実です。リモートURLはネットワーク/CORSの問題により失敗する可能性があります。
import { Image } from '@react-pdf/renderer';
<Image src="./images/photo.jpg" style={{ width: 200, height: 150 }} />
<Image src={{ data: buffer, format: 'png' }} />
SVGファイルはImage sourceとして使用できません。 SVG源を読み込んでreact-pdf Svgコンポーネントを使用して再作成してください。
SVGグラフィック
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>;
アイコンの使用
アイコンライブラリからSVG源を読み込んでreact-pdf Svgコンポーネントに変換します:
npm install lucide-static
import { Svg, Path, Rect } from "@react-pdf/renderer";
// 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>
);
リンクとナビゲーション
<Link src="https://example.com"><Text>ウェブサイトを訪問</Text></Link>
<View id="section-1"><Text>ターゲット</Text></View>
<Link src="#section-1"><Text>セクション1にジャンプ</Text></Link>
動的コンテンツとページ番号
<Text render={({ pageNumber, totalPages }) => `ページ ${pageNumber} / ${totalPages}`} />
固定ヘッダー/フッター
<Page size="A4">
<View fixed style={{ position: "absolute", top: 20, left: 30, right: 30 }}>
<Text>ヘッダー</Text>
</View>
<View style={{ marginTop: 60, marginBottom: 60 }}>
<Text>コンテンツ</Text>
</View>
<Text
fixed
style={{ position: "absolute", bottom: 20, left: 30, right: 30, textAlign: "center" }}
render={({ pageNumber, totalPages }) => `ページ ${pageNumber} / ${totalPages}`}
/>
</Page>
ページ区切りとラッピング
<View break /> // ページ区切りを強制
<View wrap={false}><Text>一緒に保つ</Text></View> // 内側の区切りを防止
<Text orphans={2} widows={2}>長いテキスト...</Text> // オーファン/ウィドウ制御
<View minPresenceAhead={100}><Text>コンテンツ</Text></View> // 区切り前の最小スペース
カスタムフォント
重要:すべてのフォントソースはローカルファイルパスである必要があります。 リモートURLは動作しません。
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" },
],
});
// カスタムフォント使用時は常にハイフネーションを無効にします
Font.registerHyphenationCallback((word) => [word]);
組み込みフォント:Courier、Helvetica、Times-Roman(各Bold、Italic/Obliqueバリアント付き)
フォントウェイト値:thin (100)、ultralight (200)、light (300)、normal (400)、medium (500)、semibold (600)、bold (700)、ultrabold (800)、heavy (900)
Googleフォント
references/google-fonts.txtを使用してフォントURLを見つけてから、ローカルにダウンロードしてください:
# フォントURLを検索
grep "^Roboto" skills/react-pdf/references/google-fonts.txt | grep "700" | grep "normal"
# ダウンロード
mkdir -p fonts
curl -sL "<grepからのurl>" -o fonts/Roboto-Bold.ttf
# 検証 - "TrueType Font data"を表示する必要があります
file fonts/Roboto-Bold.ttf
fileが"HTML document"または"ASCII text"を表示する場合、ダウンロードに失敗しています。別のURLを試すか、GitHubでTTFファイルを持つフォントの公式repoを検索してください。
絵文字
絵文字源を登録しない限り、絵文字はPDFでレンダリングされません。twemoji-emojisをインストールしてローカルTwemoji PNGアセットを取得してください — レンダリング時にインターネットは不要です。
npm install twemoji-emojis
import { Font } from "@react-pdf/renderer";
Font.registerEmojiSource({
format: "png",
url: "node_modules/twemoji-emojis/vendor/72x72/",
});
その後、テキストで直接絵文字を使用します:<Text>Hello 🚀🎉</Text>
その他の機能
// キャンバス描画
<Canvas style={{ width: 200, height: 200 }}
paint={(painter, w, h) => { painter.circle(w/2, h/2, 50).fill("#3498db"); }} />
// 注釈ノート
<Note style={{ color: "yellow" }}>注釈テキスト</Note>
// ハイフネーション
Font.registerHyphenationCallback((word) => [word]); // 無効
// デバッグモード - 境界を可視化
<View debug><Text debug>デバッグテキスト</Text></View>
// ドキュメントメタデータ
<Document title="My Doc" author="著者" subject="レポート" language="en-US" pdfVersion="1.5" />
ベストプラクティス
StyleSheet.create()を使用 — スタイルを一度定義して再利用- 埋め込み前に画像を圧縮、リモート画像に
cache={true}を使用 - ページ区切りをテスト — コンテンツは予期したものと異なるフローになる可能性があります
- 絶対位置指定よりフレックスボックスを優先
- 毎ページのヘッダー/フッターに
fixedプロップを使用 debug={true}を使用して要素の境界を可視化- レンダリングをtry-catchブロックでラップ
一般的な問題
テキスト溢れ:<Text style={{ width: 200, maxLines: 3, textOverflow: "ellipsis" }}>...</Text>
フォントの欠落:ローカルにダウンロードしてローカルファイルパスで登録してください。リモートURLは動作しません。
予期しないページ区切り:wrap={false}を使用してコンテンツを一緒に保つか、<View break />でブレークを強制してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- molefrog
- リポジトリ
- molefrog/skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/molefrog/skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。