[PR] 記事内に広告が含まれています

WindowsでPDFを結合する方法|Acrobat不要でフォルダー内のPDFをファイル名順にバッチ処理

Acrobat/Reader

WindowsでPDFを結合する方法|Acrobat不要でフォルダー内のPDFをファイル名順にバッチ処理

複数の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」と入力しクリックします。

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

QPDFのインストールパスを確認

すると、インストールされているパスが表示されるので、メモしておきます。

 

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ファイルの組み合わせはかなり便利です。

タイトルとURLをコピーしました