これらの 5 つのライブラリは、PDF 処理の異なる側面をカバーしています。@react-pdf/renderer と pdf-lib は PDF の生成・編集に特化しており、一方 react-pdf と pdfjs-dist は既存 PDF の閲覧・表示を目的としています。react-pdf-html は HTML コンテンツを PDF 構造に変換する橋渡し役として機能します。開発者は「作りたいのか」「見せたいのか」「編集したいのか」を明確に区別して選定する必要があります。
React プロジェクトで PDF を扱う際、最も多い混乱は「PDF を作りたいのか」「見せたいのか」の区別です。今回比較する 5 つのライブラリは、この目的によって明確に役割が分かれています。@react-pdf/renderer と pdf-lib は PDF を生成・編集するためのツールであり、react-pdf と pdfjs-dist は既存の PDF を表示するためのツールです。react-pdf-html はその中間で、HTML を PDF 生成用のデータに変換します。
実務では、これらを単独で使うこともあれば、組み合わせて使うこともあります。例えば、pdf-lib で既存フォームを読み込み、@react-pdf/renderer で新規ページを追加し、react-pdf で結果を確認するといった流れです。それぞれの強みと限界を理解し、適切な場面で使い分けることが重要です。
PDF を新しく作る場合、主に @react-pdf/renderer と pdf-lib のどちらかを選ぶことになります。前者は React の知識で書け、後者は PDF 構造を直接扱います。
@react-pdf/renderer は、React コンポーネントのように書いて PDF を生成します。
<Document> や <Page> といったコンポーネントを使います。// @react-pdf/renderer: React 風に PDF 生成
import { Document, Page, Text, StyleSheet } from '@react-pdf/renderer';
const styles = StyleSheet.create({ text: { fontSize: 12 } });
const MyDocument = () => (
<Document>
<Page size="A4">
<Text style={styles.text}>Hello World</Text>
</Page>
</Document>
);
pdf-lib は、既存の PDF を読み込んで編集したり、低レベルから作成したりします。
// pdf-lib: 既存 PDF の編集
import { PDFDocument } from 'pdf-lib';
const editPdf = async (existingPdfBytes) => {
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const pages = pdfDoc.getPages();
const firstPage = pages[0];
// 直接座標を指定して描画
firstPage.drawText('Edited with pdf-lib', { x: 50, y: 500, size: 15 });
return await pdfDoc.save();
};
既存の PDF ファイルをユーザーに見せる場合、react-pdf と pdfjs-dist が候補になります。実は react-pdf は pdfjs-dist を内部で使っているラッパーパッケージです。
react-pdf は、React アプリで PDF を表示するための標準的なラッパーです。
pdfjs-dist の複雑な設定を隠蔽しています。<Document> と <Page> コンポーネントで簡単に埋め込めます。// react-pdf: PDF 表示ラッパー
import { Document, Page } from 'react-pdf';
function PdfViewer({ file }) {
return (
<Document file={file}>
<Page pageNumber={1} width={600} />
</Document>
);
}
pdfjs-dist は、Mozilla が開発する PDF 描画エンジンの本体です。
// pdfjs-dist: 低レベルレンダリング
import * as pdfjsLib from 'pdfjs-dist';
const renderPdf = async (url) => {
const loadingTask = pdfjsLib.getDocument(url);
const pdf = await loadingTask.promise;
const page = await pdf.getPage(1);
// Canvas への描画を手动で管理
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
await page.render({ canvasContext: context, viewport: page.getViewport({ scale: 1.5 }) }).promise;
};
Web 上には HTML 形式のコンテンツが多く存在します。これを PDF にしたい場合、react-pdf-html が役立ちます。
react-pdf-html は、HTML 文字列を @react-pdf/renderer が理解できる要素に変換します。
@react-pdf/renderer を使用しているため、統合がスムーズです。// react-pdf-html: HTML を PDF 要素に変換
import { Html } from 'react-pdf-html';
import { Document, Page } from '@react-pdf/renderer';
const HtmlToPdf = ({ content }) => (
<Document>
<Page>
{/* HTML 文字列を PDF 互換要素にパース */}
<Html content={content} />
</Page>
</Document>
);
| 目的 | 推奨パッケージ | 理由 |
|---|---|---|
| React で PDF を新規作成 | @react-pdf/renderer | React コンポーネントで書けるため開発効率が高い |
| 既存 PDF の編集・結合 | pdf-lib | 既存バイナリを直接操作できる唯一の選択肢 |
| React で PDF を表示 | react-pdf | 実装が簡単で、必要な機能が揃っている |
| 独自の PDF ビューアー作成 | pdfjs-dist | 描画エンジンそのものなので自由度が高い |
| HTML コンテンツを PDF 化 | react-pdf-html | HTML 構造を PDF 要素へ変換する手間を省ける |
@react-pdf/renderer と react-pdf は名前が似ていますが、役割が真逆です。
@react-pdf/renderer → 作成 (Create)react-pdf → 閲覧 (View)インポート元を間違えると、コンポーネント名 (Document, Page) が被っており、動作しないか予期せぬエラーになります。必ずパッケージ名を確認してください。
// 間違いやすい例
import { Document } from 'react-pdf'; // 閲覧用
import { Document } from '@react-pdf/renderer'; // 生成用
これら 5 つのライブラリは、競合するものではなく、補完し合うものです。プロジェクトの要件に応じて以下のように選定します。
@react-pdf/renderer を中心に、必要に応じて react-pdf-html を併用。react-pdf で表示し、サーバー側で pdf-lib を使い事前処理。pdf-lib で編集機能を実装し、pdfjs-dist で詳細なプレビュー表示。最終的なアドバイス:まずは「作成」か「閲覧」かを明確にしましょう。その上で、React の知識を活かしたいなら @react-pdf/renderer と react-pdf の組み合わせが最も開発体験が良くなります。既存資産の編集が必要な場合のみ、pdf-lib の導入を検討してください。
React コンポーネントを使って PDF をゼロから生成したい場合に選択します。CSS に似たスタイル props でレイアウトを組めるため、React 開発者にとって学習コストが低く、動的なレポートや請求書生成に適しています。
既存の PDF ファイルを編集・加工(結合、分割、フォーム記入)したい場合に選択します。React に依存しない純粋な JavaScript ライブラリであり、サーバーサイドでのバッチ処理や既存書類の改ざん防止付き編集に向いています。
PDF 閲覧機能を最も低いレベルで制御したい場合に選択します。Mozilla が開発するレンダリングエンジンの本体であり、独自の UI を完全に自作する場合や、react-pdf では実現できない特殊な表示要件がある時に使用します。
React アプリケーション内で既存の PDF ファイルを閲覧・表示したい場合に選択します。pdfjs-dist をラップしており、ページネーションやズーム機能を実装する手間が省けるため、ドキュメントビューアー構築の標準的な選択肢です。
CMS などから取得したHTML 文字列を PDF に変換したい場合に選択します。@react-pdf/renderer の内部で動作し、HTML タグを PDF 要素に変換しますが、サポートされる CSS プロパティが限られるため、シンプルな文書変換に適しています。
React renderer for creating PDF files on the browser and server
yarn add @react-pdf/renderer
import React from 'react';
import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer';
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#E4E4E4',
},
section: {
margin: 10,
padding: 10,
flexGrow: 1,
},
});
// Create Document Component
const MyDocument = () => (
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.section}>
<Text>Section #1</Text>
</View>
<View style={styles.section}>
<Text>Section #2</Text>
</View>
</Page>
</Document>
);
Web. Render in DOMimport React from 'react';
import ReactDOM from 'react-dom';
import { PDFViewer } from '@react-pdf/renderer';
const App = () => (
<PDFViewer>
<MyDocument />
</PDFViewer>
);
ReactDOM.render(<App />, document.getElementById('root'));
Node. Save in a fileimport React from 'react';
import ReactPDF from '@react-pdf/renderer';
ReactPDF.render(<MyDocument />, `${__dirname}/example.pdf`);
This project exists thanks to all the people who contribute. Looking to contribute? Please check our [contribute] document for more details about how to setup a development environment and submitting code.
Thank you to all our sponsors! [Become a sponsors]
Thank you to all our backers! [Become a backer]
MIT © Diego Muracciole