DartやFlutterでPDFを扱うアプリケーションを開発していると、PDFファイルの内部構造をプログラムから読み取りたいケースがあります。
例えば、
- PDFファイルを解析する
- PDFのページ情報を取得する
- PDFのアウトラインを取得する
- PDFのコンテンツストリームを読み取る
- PDF内部のオブジェクトを扱う
- PDF解析ツールを作る
といった用途です。
今回紹介するdart_pdf_readerは、DartでPDFファイルを解析するためのPure Dartライブラリです。
PDFを画面に表示するためのビューアーではなく、PDFファイルからデータを読み取り、PDFの構造を扱うことを目的としています。
2026年8月時点の最新安定版は2.2.0で、Dart 3.0以上に対応しています。
この記事では、dart_pdf_readerの基本的な使い方から、PDFParser、PDFDocument、ページ、アウトライン、PDFオブジェクト、ストリームなどについて解説します。
- dart_pdf_readerとは?
- dart_pdf_readerの特徴
- インストール
- 基本的な使い方
- ByteStreamとは?
- PDFParserとは?
- PDFDocumentとは?
- PDFDocumentCatalogを取得する
- PDFのページを取得する
- PDFPageObjectNode
- ページサイズを取得する
- contentStreamsを取得する
- PDFのアウトラインを取得する
- PDF内部のオブジェクト
- PDFArray
- PDFNumber
- PDFStreamObject
- BufferedRandomAccessStream
- FileStreamを利用する
- ページツリーを辿る
- ページのリソースを取得する
- PDF解析時の例外
- Webにも対応
- PDFビューアーではない
- PDF解析ツールに利用する
- 画像やテキストの抽出について
- バージョン2.0.0での変更
- バージョン2.1.0での変更
- バージョン2.2.0での変更
- ライセンス
- メリット
- 注意点
- まとめ
dart_pdf_readerとは?
dart_pdf_readerは、PDFファイルを解析するためのPure Dartライブラリです。
パッケージ自体は「多くの解釈を行わないシンプルなPDFリーダー」という位置付けで、PDFファイルからデータを読み取るための仕組みを提供しています。
基本的な処理の流れは以下のようになります。
PDFファイル
↓
RandomAccessStream
↓
PDFParser
↓
PDFDocument
↓
Catalog
↓
Pages / Outlines
PDFを単純に表示するのではなく、PDFそのものを解析して内部の情報を扱いたい場合に向いています。
dart_pdf_readerの特徴
主な特徴は以下の通りです。
| 機能 | 対応 |
|---|---|
| PDF解析 | ○ |
| Pure Dart | ○ |
| バイト列からの読み込み | ○ |
| ファイルからの読み込み | ○ |
| RandomAccessStream | ○ |
| PDFParser | ○ |
| PDFDocument | ○ |
| ページ情報の取得 | ○ |
| アウトラインの取得 | ○ |
| コンテンツストリームの取得 | ○ |
| PDFオブジェクトの解析 | ○ |
| Web | ○ |
| Android | ○ |
| iOS | ○ |
| Linux | ○ |
| macOS | ○ |
| Windows | ○ |
インストール
pubspec.yamlに追加します。
YAML
dependencies:
dart_pdf_reader: ^2.2.0
追加したら、以下を実行します。
Bash
flutter pub get
コードから利用する場合はインポートします。
Dart
import 'package:dart_pdf_reader/dart_pdf_reader.dart';
基本的な使い方
dart_pdf_readerでPDFを解析する基本的な流れは非常にシンプルです。
RandomAccessStreamを作成するPDFParserを作成するparse()でPDFを解析する
例えば、PDFファイルをバイト列として読み込む場合は以下のようにします。
Dart
import 'dart:io';
import 'package:dart_pdf_reader/dart_pdf_reader.dart';
Future<void> main() async {
final inputFile = 'sample.pdf';
final stream = ByteStream(
File(inputFile).readAsBytesSync(),
);
final doc = await PDFParser(stream).parse();
print(doc);
}
parse()を実行すると、解析結果としてPDFDocumentを取得できます。
ByteStreamとは?
ByteStreamは、バイト列からPDFを読み込むためのRandomAccessStream実装です。
PDFファイルをFileから読み込み、その内容をバイト列として渡すことができます。
Dart
final bytes = File('sample.pdf').readAsBytesSync();
final stream = ByteStream(bytes);
作成したByteStreamをPDFParserに渡します。
Dart
final doc = await PDFParser(stream).parse();
PDFファイルをすでにUint8Listなどのバイトデータとして保持している場合にも利用できます。
PDFParserとは?
PDFParserは、RandomAccessStreamからPDFドキュメントを解析するためのクラスです。
Dart
final parser = PDFParser(stream);
作成したParserに対してparse()を実行します。
Dart
final doc = await parser.parse();
この結果として取得できるのがPDFDocumentです。
PDFDocumentとは?
PDFDocumentは、解析されたPDFドキュメントを保持するクラスです。
Dart
final doc = await PDFParser(stream).parse();
PDFDocumentからは、PDFのCatalogを取得できます。
Dart
final catalog = await doc.catalog;
Catalogを起点として、PDFのページやアウトラインなどを取得できます。
PDFDocumentCatalogを取得する
PDFのCatalogは、ドキュメント全体の構造を表すオブジェクトです。
Dart
final catalog = await doc.catalog;
Catalogからページ情報を取得できます。
Dart
final pages = await catalog.getPages();
アウトラインも取得できます。
Dart
final outlines = await catalog.getOutlines();
PDFのページを取得する
ページ情報はgetPages()から取得できます。
Dart
final pages = await catalog.getPages();
特定のページを取得する場合は、getPageAtIndex()を利用します。
Dart
final firstPage = pages.getPageAtIndex(0);
インデックスは0から始まるため、0を指定すると最初のページを取得できます。
PDFPageObjectNode
取得した個々のページはPDFPageObjectNodeとして扱われます。
Dart
final page = pages.getPageAtIndex(0);
PDFPageObjectNodeには、ページに関するさまざまな情報が用意されています。
例えば、
mediaBoxcropBoxbleedBoxtrimBoxartBoxrotateresourcescontentStreamsparent
などがあります。
ページサイズを取得する
mediaBoxからページのMedia Boxを取得できます。
Dart
final page = pages.getPageAtIndex(0);
final mediaBox = page.mediaBox;
print(mediaBox);
また、Crop Boxも取得できます。
Dart
final cropBox = page.cropBox;
print(cropBox);
PDFのページサイズや表示領域などを確認したい場合に利用できます。
contentStreamsを取得する
PDFページには、ページ上のコンテンツを表すストリームが含まれる場合があります。
contentStreamsから取得できます。
Dart
final page = pages.getPageAtIndex(0);
final streams = await page.contentStreams;
print(streams);
contentStreamsは複数のPDFStreamObjectを扱えるようになっています。
なお、以前のcontentStreamプロパティは非推奨となっており、現在はcontentStreamsの利用が推奨されています。
PDFのアウトラインを取得する
PDFのしおりや目次などのアウトラインを取得する場合は、CatalogのgetOutlines()を利用します。
Dart
final outlines = await catalog.getOutlines();
print(outlines);
アウトライン関連では、
PDFOutlineItemPDFOutlineActionPDFOutlineGoToActionPDFOutlineActionType
などのクラスが用意されています。
PDFに含まれるしおりやナビゲーション情報を扱いたい場合に利用できます。
PDF内部のオブジェクト
dart_pdf_readerでは、PDF内部のさまざまなオブジェクトをDartのクラスとして扱えます。
代表的なものには以下があります。
| クラス | 内容 |
|---|---|
| PDFArray | PDFの配列 |
| PDFBoolean | 真偽値 |
| PDFDictionary | PDFの辞書 |
| PDFHexString | 16進文字列 |
| PDFIndirectObject | 間接オブジェクト |
| PDFLiteralString | リテラル文字列 |
| PDFName | PDF Name |
| PDFNull | Nullオブジェクト |
| PDFNumber | 数値 |
| PDFObjectReference | オブジェクト参照 |
| PDFStreamObject | PDFストリーム |
このため、ページ情報だけではなく、PDFの内部構造をより細かく扱うことができます。
PDFArray
PDFArrayはPDFの配列を表すクラスです。
複数のPDFObjectを保持し、DartのIterableやListMixinとしても利用できます。
例えば、要素数を取得できます。
Dart
PDFArray array = ...;
print(array.length);
インデックスを指定して要素を取得することもできます。
Dart
final item = array[0];
print(item);
PDFNumber
PDFNumberはPDF内部の数値を表します。
Dart
final number = PDFNumber(100);
整数として取得する場合はtoInt()を利用できます。
Dart
final value = number.toInt();
print(value);
小数として扱う場合はtoDouble()を利用できます。
Dart
final value = number.toDouble();
print(value);
PDFStreamObject
PDFのストリームデータはPDFStreamObjectとして扱われます。
ストリームはデータを最初からすべて読み込むのではなく、必要になったタイミングでreadRaw()を利用して読み取る仕組みになっています。
Dart
final data = await stream.readRaw();
print(data);
大量のストリームデータを扱うPDFを解析する場合にも、この仕組みを理解しておくとよいでしょう。
BufferedRandomAccessStream
BufferedRandomAccessStreamは、別のRandomAccessStreamから読み込んだデータをバッファリングするための実装です。
APIドキュメントでは、遅いストリームから読み込む場合のパフォーマンス改善に利用できるとされています。
Dart
final stream = BufferedRandomAccessStream(
anotherStream,
);
ファイルから読み込む場合など、必要に応じて利用できます。
FileStreamを利用する
ファイルを直接読み込む場合はFileStreamを利用できます。
FileStreamはdart_pdf_reader_ioライブラリから提供されています。
Dart
import 'dart:io';
import 'package:dart_pdf_reader/dart_pdf_reader.dart';
import 'package:dart_pdf_reader/dart_pdf_reader_io.dart';
Future<void> main() async {
final file = await File('sample.pdf').open();
final stream = FileStream(file);
final doc = await PDFParser(stream).parse();
print(doc);
}
ただし、現在のFileStreamはスマートなバッファリングを行わず、遅くなる可能性があるとされています。
そのため、必要に応じてBufferedRandomAccessStreamと組み合わせます。
Dart
import 'dart:io';
import 'package:dart_pdf_reader/dart_pdf_reader.dart';
import 'package:dart_pdf_reader/dart_pdf_reader_io.dart';
Future<void> main() async {
final file = await File('sample.pdf').open();
final stream = BufferedRandomAccessStream(
FileStream(file),
);
final doc = await PDFParser(stream).parse();
print(doc);
}
ページツリーを辿る
PDFPageObjectNodeには親ページノードを表すparentがあります。
これを利用してページツリーを親方向へ辿ることができます。
Dart
PDFPageNode? node = firstPage;
while (node != null) {
print(await node.resources);
node = node.parent;
}
PDFのページ構造を詳しく調べたい場合に利用できます。
ページのリソースを取得する
ページには画像やフォントなど、ページから参照されるリソースが存在します。
resourcesからページのリソースを取得できます。
Dart
final resources = await page.resources;
print(resources);
PDFの内部構造を解析する場合に利用できます。
PDF解析時の例外
dart_pdf_readerにはPDF解析時に利用される例外も用意されています。
代表的なものとして、
EOFExceptionParseExceptionActionTypeNotSupported
があります。
例えば解析処理をtry-catchで囲むことができます。
Dart
try {
final doc = await PDFParser(stream).parse();
print(doc);
} on ParseException catch (e) {
print('PDFの解析に失敗しました: $e');
} on EOFException catch (e) {
print('PDFの読み込みが途中で終了しました: $e');
}
外部からPDFを受け取るアプリケーションでは、壊れたPDFや想定外のPDFが入力される可能性も考慮しておくとよいでしょう。
Webにも対応
dart_pdf_readerはWebにも対応しています。
現在の対応プラットフォームは、
- Android
- iOS
- Linux
- macOS
- Web
- Windows
です。
そのため、Flutterアプリだけでなく、Flutter WebなどでPDF解析を行う用途にも利用できます。
PDFビューアーではない
dart_pdf_readerを利用する際に注意したいのが、PDFを画面に表示するためのビューアーではないという点です。
例えば、
PDFファイル
↓
dart_pdf_reader
↓
PDFの構造を解析
という用途が中心です。
一方、
PDFファイル
↓
Flutter Widgetとして表示
という目的の場合は、PDF表示に対応した別のパッケージを利用する必要があります。
PDF解析ツールに利用する
dart_pdf_readerは、PDFファイルの構造を解析するツールなどに利用できます。
例えば、
- PDFの構造を調査するCLI
- PDFのページ情報を取得するツール
- PDFのアウトラインを解析するツール
- PDFの内部オブジェクトを解析するツール
- PDF処理のバックエンド
などです。
特にPDFを単純に表示するのではなく、PDFの構造そのものを扱いたい場合に適しています。
画像やテキストの抽出について
dart_pdf_readerはPDFの構造を読み取るためのライブラリですが、PDFから文章や画像を一般的な文書解析ライブラリのように簡単に抽出することを主目的とした高レベルAPIではありません。
パッケージ自体も、PDFデータについて多くの解釈を行わず、PDFからデータを読み取るための仕組みを提供するという位置付けです。
そのため、
- PDFの文章を抽出したい
- PDF内の画像を抽出したい
- PDFをHTMLに変換したい
といった処理では、dart_pdf_readerだけで完結するとは限りません。
用途に応じて追加の解析処理が必要になります。
バージョン2.0.0での変更
2.0.0では、いくつか大きな変更が行われています。
主な変更は以下の通りです。
- Webサポートの追加
- 19バイトしかない不正なxrefセクションを持つPDFへの対応
FileStreamをdart_pdf_reader_ioライブラリへ移動
特にFileStreamの移動は、古いバージョンからアップデートする場合に注意が必要です。
バージョン2.1.0での変更
2.1.0では、数値の比較にdeltaを使用する変更が行われました。
この変更はChangelog上でPotentially Breakingとされています。
古いバージョンからアップデートする場合は、既存コードへの影響を確認しておくとよいでしょう。
バージョン2.2.0での変更
現在の2.2.0では、依存パッケージの更新が行われています。
また、2.2.0の最小Dart SDKは3.0です。
ライセンス
dart_pdf_readerはApache License 2.0で公開されています。
利用する際は、プロジェクトのライセンス条件も確認しておきましょう。
メリット
Pure DartでPDFを解析できる
PDF解析処理をDartコードから扱えるため、PDFの構造を扱う処理をDartで実装できます。
PDFの内部構造を扱える
ページだけではなく、
- PDFオブジェクト
- ページツリー
- アウトライン
- コンテンツストリーム
- ページリソース
などを扱えます。
複数のプラットフォームに対応
Android、iOS、Linux、macOS、Web、Windowsに対応しています。
バイト列からPDFを読み込める
ByteStreamを利用することで、PDFファイルをバイト列として読み込んで解析できます。
Webに対応している
Webにも対応しているため、Flutter WebなどでPDF解析を行う用途にも利用できます。
注意点
PDFビューアーではない
PDFをFlutterの画面に表示することを目的としたパッケージではありません。
高レベルなPDF解析ライブラリではない
PDFの構造を読み取るための低レベル寄りのライブラリなので、「PDFから文章を抽出する」といった処理を簡単に実現するためのライブラリとは目的が異なります。
FileStreamのパフォーマンスに注意
FileStreamはスマートなバッファリングを行わず、遅くなる可能性があります。
必要に応じてBufferedRandomAccessStreamと組み合わせることを検討しましょう。
バージョンアップ時は変更点を確認する
2.0.0ではFileStreamの移動、2.1.0ではPotentially Breakingな変更が行われています。
古いバージョンからアップデートする場合は、変更内容を確認してから更新するのがおすすめです。
まとめ
dart_pdf_readerは、DartからPDFファイルの内部構造を読み取りたい場合に利用できるPure Dartライブラリです。
基本的な使い方は、
Dart
final stream = ByteStream(
File('sample.pdf').readAsBytesSync(),
);
final doc = await PDFParser(stream).parse();
final catalog = await doc.catalog;
final pages = await catalog.getPages();
final outlines = await catalog.getOutlines();
final firstPage = pages.getPageAtIndex(0);
という流れになります。
主な機能として、
- PDFファイルの解析
RandomAccessStreamByteStreamFileStreamBufferedRandomAccessStreamPDFParserPDFDocument- PDFページの取得
- PDFページのリソース取得
- アウトラインの取得
- コンテンツストリームの取得
- PDFオブジェクトの解析
- Web対応
- Android・iOS・Windows・macOS・Linux対応
などがあります。
特に、PDFを表示するのではなく、PDFそのものを解析・処理したい場合に適したパッケージです。
PDFのページ構造やオブジェクト、アウトライン、コンテンツストリームなどをDartから扱いたい場合は、dart_pdf_readerを候補として検討できます。

