AIで作ったPDF商品を販売前に検査する|4ページになった初稿を3ページへ戻した

AIで作ったPDF商品を販売前に検査する|4ページになった初稿を3ページへ戻した

PDF を開くと、表紙も記入欄も整っていました。ところがページ数は 3 ではなく 4 です。途中に「使い方」が 2 回入り、プレビュー用の複製ページが残っていました。

2026 年 9 月 28 日、AI で下書きした業務棚卸しシートを、販売用 PDF へ変換する手順を試しました。目視だけではなく、ページ数、見出しの重複、フォント埋め込みをコマンドで検査します。最初の PDF は終了コード1で止まり、修正後は0になりました。

個人でデジタル商品を作る時は、生成できたことと、購入者へ渡せることを分ける必要があります。PDF が開けるだけでは、完成とは判定しません。

前回完了時から変えたこと

前回は、プロンプト商品の 12 ケースを検査し、必須項目の欠落を止めました。今回は中身を PDF へ変換した後の検査へ進みます。

時点完了条件見落とす問題
前回完了時商品データが受け入れ条件を通りますPDF変換後の重複やフォント状態は見ません
今回完了後PDFのページ数、見出し、フォントを検査します内容の正確さと使いやすさは人が確認します

読み飛ばせる章: ChromeでHTMLをPDFへ変換できる場合は、「PDFの中身を3項目で検査する」から進めます。

なぜ、完成した見た目だけでは足りないのか

AI は、表紙、説明、記入欄を短時間で作れます。HTML へ流し込み、ブラウザで印刷すれば PDF もできます。しかし、生成途中で複製したページや、印刷時の改ページは画面上で見落としやすい部分です。

今回の初稿には、プレビュー用に複製した「使い方」が残っていました。各ページの色や余白は崩れていません。3 ページを想定していた人だけが、4 ページ目の存在を問題だと判断できます。

そこで、完成条件を PDF の外側に置きます。

[AIで本文とHTMLを作る]
          │
          ▼
[ChromeでPDFへ変換]
          │
          ▼
[販売前検査]
  ├── 3ページか
  ├── 必須見出しが各1回か
  └── 未埋め込みフォントが0か
          │
     ┌────┴────┐
     ▼         ▼
   PASS       FAIL
     │          └── HTMLを直して再変換
     ▼
[人が内容と操作性を確認]

検査コードは、PDF の価値を採点しません。機械で数えられる欠陥だけを、販売前に止めます。

用語をそろえる

用語この回での意味
ヘッドレスChrome画面を開かず、コマンドからWebページを処理するChromeです
pdfinfoPDFのページ数や用紙サイズなどを表示するPopplerの道具です
pdftotextPDFの文字をプレーンテキストへ変換する道具です
pdffontsPDFで使うフォントと埋め込み状態を一覧にする道具です
フォント埋め込み表示に必要な字体をPDF内へ含める処理です
終了コードコマンドの成功を0、失敗を0以外で示す値です

4ページの初稿を再現する

作業用ディレクトリで、次の HTML をoffer-before.htmlとして保存します。3 ページの商品を想定していますが、「使い方」の複製が 1 ページ残っています。

cat > offer-before.html <<'HTML'
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>AI業務棚卸しシート</title>
<style>
@page { size: A4; margin: 0; }
* { box-sizing: border-box; }
body { margin: 0; font-family: "Noto Sans CJK JP", sans-serif; }
.sheet { width: 210mm; height: 297mm; padding: 24mm 20mm; break-after: page; }
</style>
</head>
<body>
<section class="sheet"><h1>AI業務棚卸しシート</h1><p>事業の作業を整理します。</p></section>
<section class="sheet"><h2>使い方</h2><p>入力と完成条件を分けます。</p></section>
<section class="sheet"><h2>使い方</h2><p>複製ページが残っています。</p></section>
<section class="sheet"><h2>棚卸し欄</h2><p>作業名:</p><p>入力:</p><p>完成条件:</p></section>
</body>
</html>
HTML

この HTML を Chrome で PDF へ変換します。

google-chrome \
  --headless \
  --disable-gpu \
  --no-pdf-header-footer \
  --print-to-pdf=offer-before.pdf \
  file://$PWD/offer-before.html

Chrome の標準エラーには、作成したファイル容量が表示されます。今回の実行後、pdfinfoでページ数を読むと次の結果になりました。

pdfinfo offer-before.pdf | grep '^Pages:'
Pages:           4

ここで期待値の 3 ページと食い違います。見た目を確認する前でも、初稿を販売候補から外せます。

PDFの中身を3項目で検査する

次に、検査スクリプトをpreflight-pdf.shとして保存します。読み出した文字は一時ファイルへ置き、見出しの回数を数えます。

cat > preflight-pdf.sh <<'SH'
#!/usr/bin/env bash
set -euo pipefail
pdf=${1:?usage: preflight-pdf.sh FILE.pdf}
expected_pages=3
pages=$(pdfinfo "$pdf" | awk '/^Pages:/ {print $2}')
pdftotext "$pdf" - | tr -d '\f' > /tmp/offer-extracted.txt
use_count=$(grep -c '^使い方$' /tmp/offer-extracted.txt || true)
stock_count=$(grep -c '^棚卸し欄$' /tmp/offer-extracted.txt || true)
nonembedded=$(pdffonts "$pdf" | awk 'NR>2 && $4=="no" {n++} END {print n+0}')
printf 'pages=%s expected=%s\n' "$pages" "$expected_pages"
printf 'heading_use=%s heading_sheet=%s\n' "$use_count" "$stock_count"
printf 'nonembedded_fonts=%s\n' "$nonembedded"
test "$pages" -eq "$expected_pages"
test "$use_count" -eq 1
test "$stock_count" -eq 1
test "$nonembedded" -eq 0
printf 'result=PASS\n'
SH
chmod +x preflight-pdf.sh

初稿を検査します。

./preflight-pdf.sh offer-before.pdf
printf 'exit=%s\n' "$?"

実測結果は次の通りです。set -eを呼び出し側で有効にしている場合、printfへ進まず終了します。

pages=4 expected=3
heading_use=2 heading_sheet=1
nonembedded_fonts=0
exit=1

ページ数だけでなく、「使い方」が 2 回あることも分かりました。未埋め込みフォントは 0 です。今回の失敗原因を、フォントではなく重複ページへ絞れます。

重複を消し、同じ物差しで測り直す

初稿を複製し、プレビュー用のページだけを削除します。最後のページには、不要な改ページを付けません。

python - <<'PY'
from pathlib import Path
src = Path("offer-before.html").read_text()
src = src.replace(
    '.sheet { width: 210mm; height: 297mm; padding: 24mm 20mm; break-after: page; }',
    '.sheet { width: 210mm; height: 297mm; padding: 24mm 20mm; break-after: page; }\n'
    '.sheet:last-child { break-after: auto; }',
)
src = src.replace(
    '<section class="sheet"><h2>使い方</h2><p>複製ページが残っています。</p></section>\n',
    '',
)
Path("offer-after.html").write_text(src)
PY

google-chrome \
  --headless \
  --disable-gpu \
  --no-pdf-header-footer \
  --print-to-pdf=offer-after.pdf \
  file://$PWD/offer-after.html

同じ検査スクリプトを使います。修正に合わせて期待値を変えると、改善したのか、判定を緩めたのか分からなくなります。

./preflight-pdf.sh offer-after.pdf
printf 'exit=%s\n' "$?"

修正後の実測結果です。

pages=3 expected=3
heading_use=1 heading_sheet=1
nonembedded_fonts=0
result=PASS
exit=0

3 ページになり、2 つの必須見出しは各 1 回です。フォント状態も初稿から悪化していません。

テキスト抽出は購入後の使いやすさにも関わる

pdftotextで文字を取り出せるかは、重複検査だけの問題ではありません。購入者が PDF 内を検索し、必要な箇所をコピーできるかにも関わります。

ただし、文字を抽出できればアクセシブルな PDF になるわけではありません。文書の言語、見出し構造、画像の代替情報、読み上げ順などは別に確認します。Adobe のアクセシビリティ検査も、機械検査だけでは確認できない項目があると案内しています。

フォントについても役割を分けます。pdffontsのemb列は、フォントが PDF へ埋め込まれているかを示します。埋め込みがyesでも、文字順や見出し構造の正しさまでは保証しません。

検査分かること分からないこと
pdfinfoページ数や用紙サイズですページ内容の正しさです
pdftotext文字を抽出できるか、見出しが何回あるかです見た目と読み上げ順の品質です
pdffontsフォントの種類と埋め込み状態です文章の正確さと商品価値です
人の確認記入しやすさ、内容、販売条件です再実行時の機械的な回帰です

よくあるエラー

症状原因対応
想定より1ページ多いです複製ページか末尾の改ページが残っていますpdfinfoで件数を止め、HTMLのsection数を確認します
見出し件数が0です文字が画像化され、テキストとして残っていません画像ではなくHTMLの文字として配置し直します
日本語が文字化けします使用フォントか文字コードに問題がありますUTF-8と日本語フォントを指定し、再抽出します
nonembedded_fontsが1以上です端末側のフォントへ依存していますライセンスを確認したフォントを埋め込みます
手元では通るのに別環境で崩れますChromeやフォントの版が違います変換環境を固定し、PDF自体を検査対象にします
検査は通るのに使いにくいです件数検査を人の確認の代わりにしています印刷、検索、コピー、記入を実際に試します

PASSは販売開始の合図ではない

今回の検査で確認できたのは、3 ページ、必須見出し各 1 回、未埋め込みフォント 0 の 3 点です。文章の正確さや、購入者が記入しやすいかは別に残ります。

AI でデジタル商品を作ると、初稿が早く出るため、完成判定も早めたくなります。しかし、見た目が整った 4 ページをそのまま渡すと、購入者が重複の意味を考えることになります。作り手の確認不足を、購入者へ移してはいけません。

私は、AI へ作成を任せる範囲が広いほど、最後の判定を単純なコマンドへ戻します。PDF を開いた感想ではなく、期待するページ数と見出し数を先に固定します。失敗時は商品を消さず、終了コード1と原因を残して直します。

次は、同じ PDF を画面、印刷、スマートフォンで確認し、記入欄の大きさを測ります。機械検査で欠落を止めた後に、人が使う場面へ進みます。

一次情報

資料確認した内容
Chrome for Developers: Headless command-line reference--print-to-pdfと--no-pdf-header-footerの使い方
Debian Manpages: pdfinfoPDFのメタデータとページ情報を表示する仕様
Debian Manpages: pdftotextPDFをテキストへ変換する機能と終了コード
Debian Manpages: pdffontsemb、sub、uni列が示す情報
Adobe Acrobat: Create and verify PDF accessibilityPDFのアクセシビリティ検査と、人が確認する項目
W3C: PDF16PDF文書のデフォルト言語を/Langで指定する方法
この記事をシェア