
複数のPDFファイルを1つにまとめたいとき、AdobeAcrobatを使えば簡単に結合できます。
ただ、PDFを結合するだけのためにAcrobatを契約するのは少し重いです。
特に、フォルダー内に大量のPDFがあり、それをファイル名順にまとめたいだけなら、無料のコマンドラインツールを使った方が早い場合があります。
今回は、WindowsでAcrobatを使わずに、フォルダー内のPDFをファイル名順で1つに結合する方法をまとめます。
最終的には、batファイルをダブルクリックするだけで、フォルダー内のPDFをまとめられるようにします。
今回やりたいこと
今回やりたいことは、次のような処理です。
- 指定フォルダー内にあるPDFファイルを取得する
- ファイル名順に並べる
- すべてのPDFを1つのPDFに結合する
- 毎回同じ処理をbatファイルで実行できるようにする
- AdobeAcrobatは使わない
たとえば、次のようなPDFがフォルダー内にあるとします。
05-06_06-01-59.pdf
05-06_06-02-10.pdf
05-06_06-03-20.pdf
これらをファイル名順に並べて、1つのPDFにまとめます。出力するPDFのファイル名は、今回は次のようにします。
_combined.pdf
使うソフトはqpdf
今回使うのは、qpdfというPDF処理用のコマンドラインツールです。
qpdfは、PDFの結合、分割、ページ操作などに使えるツールです。画面で操作するタイプのソフトではなく、PowerShellやbatファイルから実行するタイプのソフトです。
オンラインのPDF結合サービスもありますが、PDFを外部サイトへアップロードする必要があります。個人情報、仕事の資料、取引データ、医療系の書類などを扱う場合は、できるだけローカル環境だけで処理した方が安全です。
その点、qpdfを使えば、自分のPC内だけでPDF結合ができます。
qpdfをWindowsにインストールする
Windowsでは、wingetを使うとqpdfをインストールできます。まず、PowerShellで次のコマンドを実行して、qpdfの情報を確認します。
WindowsキーまたはWindowsボタンをクリック後「Power」と入力しクリックします。

PowerShellで、次の内容を入力します。
winget show --id QPDF.QPDF --source winget

ソフトの内容が表示されるので、確認して問題なければ、次のコマンドでインストールします。
winget install --id QPDF.QPDF -e --source winget
単に次のように実行することもできます。
winget install QPDF
ただし、この指定だと名前検索になります。似た名前のソフトが候補に出たり、MicrosoftStore側の確認が出たりすることがあります。
そのため、今回はIDを完全一致で指定し、wingetリポジトリだけを見るようにしています。その方が、狙ったqpdfをインストールしやすくなります。
QPDFのインストールパスを確認
PowerShellで、次の内容を入力します。
Get-ChildItem "C:\Program Files" -Recurse -Filter "qpdf.exe" -ErrorAction SilentlyContinue | Select-Object FullName

すると、インストールされているパスが表示されるので、メモしておきます。
PowerShellでPDFを結合する
今回は、次のフォルダーに結合したい複数のPDFファイルが入っているものとして説明します。
C:\pdf
PowerShellで次のコード貼り付けて実行すると、このフォルダー内のPDFをファイル名順に結合できます。
$folder = "C:\pdf"
$out = Join-Path $folder "_combined.pdf"
$qpdf = "C:\Program Files\qpdf 12.3.2\bin\qpdf.exe"
$argFile = Join-Path $env:TEMP "qpdf-merge-args.txt"
if (Test-Path $out) {
Remove-Item $out -Force
}
$files = Get-ChildItem -LiteralPath $folder -Filter "*.pdf" -File |
Where-Object { $_.Name -ne "_combined.pdf" } |
Sort-Object Name
Write-Host "PDF件数: $($files.Count)"
if ($files.Count -eq 0) {
Write-Host "PDFファイルが見つかりません。"
exit
}
$lines = New-Object System.Collections.Generic.List[string]
$lines.Add("--empty")
$lines.Add("--pages")
foreach ($file in $files) {
$lines.Add($file.FullName)
}
$lines.Add("--")
$lines.Add($out)
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllLines($argFile, $lines, $utf8NoBom)
& $qpdf "@$argFile"
if ($LASTEXITCODE -eq 0) {
Write-Host "結合完了: $out"
} else {
Write-Host "qpdfでエラーが発生しました。"
}
成功すると、次のPDFが作成されます。
C:\pdf\_combined.pdf
今回工夫した点
今回のポイントは、単純にqpdfへPDFファイルを全部並べて渡すのではなく、引数ファイルを使っていることです。
PDFファイルが数個だけなら、コマンドにPDFファイル名を直接並べても問題ありません。
しかし、今回はフォルダー内に約700個のPDFファイルがありました。
このようにファイル数が多い場合、コマンドにすべてのファイル名を直接並べると、コマンドが長くなりすぎたり、うまく渡せなかったりする可能性があります。
そこで今回は、qpdfに渡す内容を一度テキストファイルに書き出し、そのテキストファイルをqpdfに読み込ませる形にしました。
この部分です。
$argFile = Join-Path $env:TEMP "qpdf-merge-args.txt"
そして、qpdf実行時に次のように渡しています。
& $qpdf "@$argFile"
この方法にすると、大量のPDFファイルでも処理しやすくなります。これにより、700個程度のPDFでも安定して結合できます。
ファイル名順で結合する
今回のコードでは、PDFを次の部分でファイル名順に並べています。
Sort-Object Name
そのため、次のようなファイル名であれば、時刻順に並びます。
05-06_06-01-59.pdf
05-06_06-02-10.pdf
05-06_06-03-20.pdf
注意点として、次のようなファイル名の場合は、思った順番にならないことがあります。
1.pdf
2.pdf
10.pdf
文字列として並べると、次のような順番になる場合があります。
1.pdf
10.pdf
2.pdf
そのため、順番を確実にしたい場合は、次のようにゼロ埋めしておくのがおすすめです。
001.pdf
002.pdf
010.pdf
PDF結合では、ファイル名がそのままページ順になります。ここは地味ですが、かなり重要です。
batファイルにしてダブルクリックで実行する
毎回PowerShellにコードを貼り付けるのは面倒なので、batファイルにしておきます。
次の内容で、merge-pdf.batというファイルを作成します。
@echo off
setlocal
set "MERGE_PDF_FOLDER=%~dp0"
set "MERGE_QPDF=C:\Program Files\qpdf 12.3.2\bin\qpdf.exe"
powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference='Stop'; $folder=$env:MERGE_PDF_FOLDER; $out=Join-Path $folder '_combined.pdf'; $qpdf=$env:MERGE_QPDF; $argFile=Join-Path $env:TEMP ('qpdf-merge-args-' + [guid]::NewGuid().ToString() + '.txt'); if (Test-Path $out) { Remove-Item $out -Force }; $files=@(Get-ChildItem -LiteralPath $folder -Filter '*.pdf' -File | Where-Object { $_.Name -ne '_combined.pdf' } | Sort-Object Name); Write-Host ('PDF count: ' + $files.Count); if ($files.Count -eq 0) { Write-Host 'No PDF files found.'; exit 1 }; $lines=New-Object System.Collections.Generic.List[string]; $lines.Add('--empty'); $lines.Add('--pages'); foreach ($file in $files) { $lines.Add($file.FullName) }; $lines.Add('--'); $lines.Add($out); $utf8NoBom=New-Object System.Text.UTF8Encoding($false); [System.IO.File]::WriteAllLines($argFile, $lines, $utf8NoBom); & $qpdf ('@' + $argFile); $code=$LASTEXITCODE; Remove-Item $argFile -Force -ErrorAction SilentlyContinue; if ($code -eq 0) { Write-Host ('Done: ' + $out) } else { Write-Host ('qpdf error. ExitCode=' + $code); exit $code }"
echo.
pause
endlocal
このbatファイルを、PDFが入っているフォルダーに置きます。
たとえば今回なら、次の場所です。
C:\pdf\merge-pdf.bat
あとは、このbatファイルをダブルクリックするだけです。
同じフォルダー内にあるPDFをファイル名順に結合し、次のファイルを作成します。
_combined.pdf
batファイルの仕組み
このbatファイルでは、次の部分で「batファイル自身が置かれているフォルダー」を対象にしています。
set "MERGE_PDF_FOLDER=%~dp0"
つまり、PDFが入っているフォルダーにbatファイルを置けば、そのフォルダー内のPDFを結合できます。
フォルダー名を毎回コード内に書く必要がないため、別のフォルダーでも使い回しやすくなります。
qpdf本体の場所は、次の部分で指定しています。
set "MERGE_QPDF=C:\Program Files\qpdf 12.3.2\bin\qpdf.exe"
qpdfのバージョンや環境によってqpdfのインストール場所が違う場合は、この部分を自分の環境に合わせて変更します。
既存の結合済みPDFは除外する
結合結果として作成するPDFは、次の名前にしています。
_combined.pdf
このファイルが既に存在する場合、先に削除してから作り直します。
if (Test-Path $out) { Remove-Item $out -Force }
また、PDF一覧を作るときに、_combined.pdf自体は除外しています。
Where-Object { $_.Name -ne '_combined.pdf' }
これをしないと、過去に作った結合済みPDFまで再び結合対象に入ってしまいます。
PDF結合でありがちな事故なので、ここは必ず入れておいた方がいいです。
よくあるエラー
作業中に出やすいエラーもまとめておきます。
qpdfが認識されない
次のようなエラーが出る場合があります。
qpdf : 用語 'qpdf' は、コマンドレット、関数、スクリプトファイル、または操作可能なプログラムの名前として認識されません。
これは、qpdf.exeの場所にPATHが通っていない状態です。
その場合は、次のようにqpdf.exeをフルパスで指定します。
& "C:\Program Files\qpdf 12.3.2\bin\qpdf.exe" --version
batファイル内でも、qpdfの場所をフルパスで指定しているため、PATHが通っていなくても動きます。
qpdf:aninputfilenameisrequiredと出る
次のようなエラーが出ることがあります。
qpdf: an input file name is required
これは、qpdfへ入力PDFファイルが渡っていないときに出るエラーです。
原因としては、次のようなものがあります。
- 指定フォルダーにPDFがない
- PDFがサブフォルダー内にある
- ファイル取得条件が間違っている
- qpdfへ渡す引数がうまく作れていない
今回のようにファイル数が多い場合は、引数ファイル方式にすると安定しやすくなります。
まとめ
WindowsでPDFを結合するだけなら、AdobeAcrobatを使わなくても対応できます。
qpdfを使えば、フォルダー内のPDFをファイル名順に並べて、1つのPDFにまとめられます。
さらにbatファイルにしておけば、次回からはダブルクリックだけで処理できます。
今回のポイントは、PDFファイルが約700個あったため、qpdfへファイル名を直接大量に渡すのではなく、引数ファイル方式にしたことです。
この方法なら、大量のPDFをまとめる場合でも扱いやすくなります。
Acrobatを使わず、ローカル環境だけでPDFを結合したい場合には、qpdfとbatファイルの組み合わせはかなり便利です。
