PDF読込ユーティリティが業務で必要になる理由
PDFは「改ざんされにくい」「どの環境でも同じ見た目で表示できる」という特性から、請求書・契約書・レポート・帳票など、業務システムの“受け取る側”として非常に多く使われています。 そのため、Java で PDFを読み込んでテキスト抽出する・ページ数を調べる・画像を取り出す といった処理は、実務で必須になります。
しかし、初心者がやりがちな「PDFを文字列として扱う」「正規表現で解析する」といった実装は、PDFの構造を理解していないため必ず破綻します。 PDFは“描画命令の集まり”であり、内部構造はHTMLやテキストファイルとはまったく異なります。
そこで役に立つのが PDF読込ユーティリティ です。 Javaでは Apache PDFBox が事実上の標準ライブラリで、初心者でも扱いやすく、業務でも十分使える品質です。
PDF読込の基本発想
PDFは「ページ → 描画命令 → テキスト抽出」という構造で読む
PDFは次の階層構造でできています。
- PDDocument(PDFファイル)
- PDPage(ページ)
- PDFTextStripper(テキスト抽出器)
PDFは“テキストファイル”ではなく、“描画命令の集合体”です。 そのため、テキスト抽出には専用の抽出器(PDFTextStripper)を使う必要があります。
PDF読込の最小構成(初心者向け)
まずは「PDFからテキストを抽出する」だけのシンプルな例
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import java.nio.file.Files;
import java.nio.file.Path;
public class SimplePdfReader {
public static String readText(Path path) throws Exception {
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
PDFTextStripper stripper = new PDFTextStripper();
return stripper.getText(doc);
}
}
}
Java使い方の例です。
String text = SimplePdfReader.readText(Path.of("data/sample.pdf"));
System.out.println(text);
Javaここで重要なのは 「PDFをバイト列として読み込む」 という点です。 PDFはバイナリ形式なので、文字コードを意識する必要はありません。
PDFのページ数を取得する
PDDocument の getNumberOfPages を使う
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
int pages = doc.getNumberOfPages();
System.out.println("ページ数: " + pages);
}
Javaページ数は帳票処理やレポート解析でよく使います。
PDFの特定ページだけを読む
PDFTextStripper の範囲指定を使う
PDFTextStripper stripper = new PDFTextStripper();
stripper.setStartPage(2);
stripper.setEndPage(2);
String pageText = stripper.getText(doc);
Javaここで深掘りしたいポイントは 「PDFはページ単位で抽出できる」 ということです。 大量のPDFを扱う場合、必要なページだけ抽出することで処理が高速になります。
PDFから画像を抽出する
PDResources → XObject → PDImageXObject の流れ
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
public static void extractImages(Path path) throws Exception {
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
int pageIndex = 0;
for (PDPage page : doc.getPages()) {
var resources = page.getResources();
for (COSName name : resources.getXObjectNames()) {
PDXObject xobj = resources.getXObject(name);
if (xobj instanceof PDImageXObject) {
PDImageXObject img = (PDImageXObject) xobj;
Path out = Path.of("out/image_" + pageIndex + "_" + name.getName() + ".png");
ImageIO.write(img.getImage(), "png", out.toFile());
}
}
pageIndex++;
}
}
}
Javaここで深掘りしたいポイントは 「PDFの画像はXObjectとして埋め込まれている」 ということです。 PDFは画像を“描画命令”として持っているため、画像抽出は少し特殊な処理になります。
実務向け PDF読込ユーティリティ(テンプレート)
テキスト抽出・ページ数取得・画像抽出をまとめた形
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.cos.COSName;
import javax.imageio.ImageIO;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class PdfUtils {
public static String extractText(Path path) throws Exception {
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
PDFTextStripper stripper = new PDFTextStripper();
return stripper.getText(doc);
}
}
public static int getPageCount(Path path) throws Exception {
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
return doc.getNumberOfPages();
}
}
public static List<Path> extractImages(Path path, Path outDir) throws Exception {
List<Path> results = new ArrayList<>();
try (PDDocument doc = PDDocument.load(Files.readAllBytes(path))) {
int pageIndex = 0;
for (PDPage page : doc.getPages()) {
var resources = page.getResources();
for (COSName name : resources.getXObjectNames()) {
PDXObject xobj = resources.getXObject(name);
if (xobj instanceof PDImageXObject) {
PDImageXObject img = (PDImageXObject) xobj;
Path out = outDir.resolve("image_" + pageIndex + "_" + name.getName() + ".png");
ImageIO.write(img.getImage(), "png", out.toFile());
results.add(out);
}
}
pageIndex++;
}
}
return results;
}
}
Java使い方の例です。
String text = PdfUtils.extractText(Path.of("data/report.pdf"));
int pages = PdfUtils.getPageCount(Path.of("data/report.pdf"));
List<Path> images = PdfUtils.extractImages(Path.of("data/report.pdf"), Path.of("out"));
JavaPDF読込で必ず意識すべき重要ポイント
1. PDFは“テキストファイルではない”
内部は描画命令の集合体であり、テキスト抽出は専用の処理が必要です。
2. テキスト抽出は完全ではない
PDFの構造によっては、テキストが正しく抽出できない場合があります。 (画像として埋め込まれた文字など)
3. 画像抽出はページごとにXObjectを調べる
PDFは画像を“リソース”として持っているため、抽出処理は特殊です。
4. PDFはバイナリ形式なので文字コードを意識しなくてよい
ただし、抽出したテキストは UTF-8 で扱うのが一般的です。
PDF読込ユーティリティの実務的な使いどころ
外部ベンダーからのPDF帳票解析
請求書・契約書・レポートなどを自動解析できます。
管理画面でのPDFアップロード
アップロードされたPDFからテキストを抽出し、データベースに登録できます。
バッチ処理でのPDF解析
夜間バッチで大量のPDFを読み込み、テキスト抽出や画像抽出を行うことができます。
まとめ:PDF読込ユーティリティで身につけてほしい感覚
PDF読込ユーティリティは、業務データを“PDFという特殊な形式”から安全に取り出すための重要な仕組みです。 そこには次のようなポイントがあります。
- PDFは「ページ → 描画命令 → テキスト抽出」という構造で読む
- テキスト抽出は PDFTextStripper を使う
- ページ数取得は PDDocument の getNumberOfPages
- 画像抽出は XObject を調べる
- PDFはバイナリ形式なので文字コードを意識しなくてよい
