📄

【Python初心者向け】たった約50行で作れるPDF結合ツール|pypdfで複数PDFを自在にまとめる方法

に公開

はじめに

「複数のPDFを1つにまとめたいけど、いい方法がない...」

こんな経験はありませんか?

  • 会議資料を1つのファイルにまとめたい
  • スキャンした書類を整理したい
  • レポートと参考資料を結合したい

オンラインのPDF結合サービスを使おうとすると、広告だらけだったり、ファイルサイズ制限があったり、「本当にデータは安全なの?」と不安になったり...。

有料のPDF編集ソフトを買うほどでもないし、かといって毎回手作業でコピー&ペーストするのは面倒。

そんな悩みを、Pythonならたった50行のコードで解決できます。

この記事では、Python初心者の方でも理解できるよう、PDF結合ツールの作り方を一から丁寧に解説します。

この記事で学べること

  • Pythonの基本的なファイル操作
  • 仮想環境(venv)の使い方
  • 外部ライブラリ(pypdf)のインストールと活用
  • コマンドラインツールの作り方

完成したコードはGitHubで公開しています。すぐに使いたい方はこちらからどうぞ。

https://github.com/yamato-snow/2025-12-03_pdf-merge-tool


このツールでできること

今回作るPDF結合ツールには、以下の機能があります。

主な機能

機能 説明
複数PDFの結合 指定したフォルダ内のPDFファイルを1つに結合
順番指定 結合する順番を自由に指定可能
ファイル名指定 出力ファイル名をカスタマイズ可能
一括結合 「all」コマンドで全ファイルを一括結合

なぜPythonで作るのか?

オンラインサービスや有料ソフトと比較した、Pythonで自作するメリットを整理します。

比較項目 オンラインサービス 有料ソフト Python自作
費用 無料(制限あり) 数千円〜 無料
セキュリティ サーバーにアップロード ローカル処理 ローカル処理
カスタマイズ 不可 限定的 自由自在
大量ファイル 制限あり 可能 可能
自動化 不可 限定的 容易

特にセキュリティ面カスタマイズ性がPython自作の大きな強みです。機密文書を外部サーバーにアップロードする必要がなく、業務に合わせた機能追加も自由にできます。


完成品を先に見てみよう

コードの解説に入る前に、完成品を見てみましょう。

GitHubリポジトリ

https://github.com/yamato-snow/2025-12-03_pdf-merge-tool

すぐに使いたい方は、上記リポジトリをクローンしてお使いください。

実際の動作デモ

ターミナルで実行すると、このように動作します。

$ python merge_pdf.py

PDFファイル一覧:
  1. chapter1.pdf
  2. chapter2.pdf
  3. appendix.pdf

結合順序を入力 (例: 2,1,3 または 2 1 3)
allで全て順番通り、qで終了
> 1,2,3

出力ファイル名 (空欄でmerged.pdf) > document.pdf

結合中...
  + chapter1.pdf
  + chapter2.pdf
  + appendix.pdf

完了: document.pdf

シンプルで直感的な操作ができるツールです。


環境構築

Python初心者の方向けに、環境構築から丁寧に解説します。

Python環境の準備

まず、Pythonがインストールされているか確認しましょう。

python --version

または

python3 --version

Python 3.x.x と表示されれば、Pythonはインストール済みです。

仮想環境とは何か?

Pythonでは「仮想環境」を使うことが推奨されています。

仮想環境とは?

プロジェクトごとに独立したPython環境を作る仕組みです。

なぜ必要?
├── プロジェクトA → ライブラリX バージョン1.0が必要
└── プロジェクトB → ライブラリX バージョン2.0が必要

仮想環境なし → バージョン競合でエラー!
仮想環境あり → それぞれ独立して管理できる

初心者の方は「プロジェクトごとにPythonの部屋を作る」とイメージすると分かりやすいかもしれません。

仮想環境の作成と有効化

プロジェクト用のフォルダを作成し、仮想環境をセットアップします。

# プロジェクトフォルダを作成
mkdir pdf-merge-tool
cd pdf-merge-tool

# 仮想環境を作成
python -m venv .venv

仮想環境を「有効化」すると、その環境内でPythonを実行できます。

Mac/Linuxの場合:

source .venv/bin/activate

Windowsの場合(コマンドプロンプト):

.venv\Scripts\activate.bat

Windowsの場合(PowerShell):

.venv\Scripts\Activate.ps1

有効化されると、ターミナルの先頭に (.venv) と表示されます。

(.venv) $

必要なライブラリのインストール

PDF操作には pypdf というライブラリを使います。

pip install pypdf

コード全体像

まずは完成したコードの全体を見てみましょう。

merge_pdf.py
"""PDF結合ツール"""
import sys
from pathlib import Path
from pypdf import PdfWriter

# スクリプトのあるフォルダのPDFを取得
script_dir = Path(__file__).parent
pdf_files = sorted(script_dir.glob("*.pdf"))

if not pdf_files:
    print("PDFファイルが見つかりません")
    sys.exit(1)

# 一覧表示
print("\nPDFファイル一覧:")
for i, f in enumerate(pdf_files, 1):
    print(f"  {i}. {f.name}")

# 順番入力
print("\n結合順序を入力 (例: 2,1,3 または 2 1 3)")
print("allで全て順番通り、qで終了")
user_input = input("> ").strip()

if user_input.lower() == "q":
    sys.exit(0)

if user_input.lower() == "all":
    selected = pdf_files
else:
    nums = user_input.replace(",", " ").split()
    selected = [pdf_files[int(n) - 1] for n in nums]

# 出力ファイル名
output_name = input("\n出力ファイル名 (空欄でmerged.pdf) > ").strip()
if not output_name:
    output_name = "merged.pdf"
if not output_name.endswith(".pdf"):
    output_name += ".pdf"

# 結合
print("\n結合中...")
writer = PdfWriter()
for pdf in selected:
    print(f"  + {pdf.name}")
    writer.append(pdf)

output_path = script_dir / output_name
writer.write(output_path)
writer.close()

print(f"\n完了: {output_name}")

たった約50行のコードで、実用的なPDF結合ツールが完成します。

処理の流れ

1. PDFファイルを検索・一覧表示

2. ユーザーから結合順序を入力

3. 出力ファイル名を入力

4. PDFを順番に結合

5. ファイルに保存

では、各ステップを詳しく見ていきましょう。


コード詳細解説

Step1: ライブラリのインポート

"""PDF結合ツール"""
import sys
from pathlib import Path
from pypdf import PdfWriter

3つのモジュール/ライブラリを使用しています。

ライブラリ 役割 種類
sys プログラムの終了処理 標準ライブラリ(最初から入っている)
pathlib ファイルパスの操作 標準ライブラリ
pypdf PDF操作 外部ライブラリ(pip install必要)

なぜ pathlib を使うのか?

従来の os.path より直感的にファイル操作ができます。

# os.path の場合
import os
path = os.path.join("folder", "file.pdf")

# pathlib の場合(よりシンプル)
from pathlib import Path
path = Path("folder") / "file.pdf"

Step2: PDFファイルの検索

# スクリプトのあるフォルダのPDFを取得
script_dir = Path(__file__).parent
pdf_files = sorted(script_dir.glob("*.pdf"))

Path(__file__).parent とは?

  • __file__ → このPythonファイル自身のパス
  • .parent → その親フォルダ(=スクリプトがあるフォルダ)

glob("*.pdf") とは?

「〜にマッチするファイルを全て取得」するメソッドです。

  • *.pdf → 「任意の文字列 + .pdf」にマッチ
  • 例:report.pdf, data.pdf, 123.pdf など全てマッチ

sorted() とは?

ファイル名順(アルファベット順)に並べ替えます。これにより、ファイル一覧が毎回同じ順序で表示されます。

Step3: ファイル一覧の表示

if not pdf_files:
    print("PDFファイルが見つかりません")
    sys.exit(1)

# 一覧表示
print("\nPDFファイル一覧:")
for i, f in enumerate(pdf_files, 1):
    print(f"  {i}. {f.name}")

enumerate() とは?

リストの要素と、その番号(インデックス)を同時に取得できる便利な関数です。

fruits = ["apple", "banana", "cherry"]

# enumerate なし
for fruit in fruits:
    print(fruit)
# apple, banana, cherry

# enumerate あり(1から開始)
for i, fruit in enumerate(fruits, 1):
    print(f"{i}. {fruit}")
# 1. apple
# 2. banana
# 3. cherry

f-string(フォーマット文字列)とは?

f"..." の中で {変数} と書くと、変数の値が埋め込まれます。

name = "田中"
age = 25
print(f"{name}さんは{age}歳です")
# → 田中さんは25歳です

Step4: ユーザー入力の処理

# 順番入力
print("\n結合順序を入力 (例: 2,1,3 または 2 1 3)")
print("allで全て順番通り、qで終了")
user_input = input("> ").strip()

if user_input.lower() == "q":
    sys.exit(0)

if user_input.lower() == "all":
    selected = pdf_files
else:
    nums = user_input.replace(",", " ").split()
    selected = [pdf_files[int(n) - 1] for n in nums]

input() とは?

ユーザーからの入力を受け取る関数です。入力が完了するまでプログラムは待機します。

.strip() とは?

文字列の前後の空白や改行を削除します。

text = "  hello  "
print(text.strip())  # → "hello"

.lower() とは?

文字列を小文字に変換します。これにより「Q」でも「q」でも同じ処理ができます。

replace()split() の組み合わせ

ユーザーが「2,1,3」でも「2 1 3」でも対応できるようにしています。

user_input = "2,1,3"

# replace()は新しい文字列を返す(元の文字列は変わらない)
# そのため、メソッドチェーンで繋げて使う
nums = user_input.replace(",", " ").split()
# → ["2", "1", "3"]

リスト内包表記

selected = [pdf_files[int(n) - 1] for n in nums]

これは以下と同じ意味です:

selected = []
for n in nums:
    index = int(n) - 1  # 1始まりを0始まりに変換
    selected.append(pdf_files[index])

Step5: PDFの結合処理

# 結合
print("\n結合中...")
writer = PdfWriter()
for pdf in selected:
    print(f"  + {pdf.name}")
    writer.append(pdf)

output_path = script_dir / output_name
writer.write(output_path)
writer.close()

print(f"\n完了: {output_name}")

PdfWriter クラス

pypdfライブラリの中心的なクラスです。PDFを作成・編集するための機能を提供します。

メソッド 役割
append(pdf) 既存のPDFを末尾に追加
write(path) ファイルとして保存
close() リソースを解放

パスの結合

output_path = script_dir / output_name

pathlibでは / 演算子でパスを結合できます。直感的で分かりやすいですね。


実際に使ってみよう

準備:PDFファイルを配置

  1. merge_pdf.py があるフォルダに、結合したいPDFファイルを置きます
  2. ターミナルでそのフォルダに移動します
pdf-merge-tool/
├── merge_pdf.py
├── chapter1.pdf  ← 結合したいファイル
├── chapter2.pdf  ← 結合したいファイル
└── appendix.pdf  ← 結合したいファイル

実行:コマンドの入力

# 仮想環境を有効化(まだの場合)
source .venv/bin/activate  # Mac/Linux
# または
.venv\Scripts\activate.bat  # Windows

# 実行
python merge_pdf.py

結果:結合されたPDFの確認

指定した出力ファイル名(デフォルトは merged.pdf)が同じフォルダに作成されます。

よくあるエラーと対処法


カスタマイズしてみよう

基本的な使い方をマスターしたら、自分好みにカスタマイズしてみましょう。

日付を自動でファイル名に入れる

出力ファイルに今日の日付を自動で入れたい場合:

from datetime import datetime

# 出力ファイル名を日付付きに
today = datetime.now().strftime("%Y%m%d")
default_name = f"merged_{today}.pdf"

output_name = input(f"\n出力ファイル名 (空欄で{default_name}) > ").strip()
if not output_name:
    output_name = default_name

結果:merged_20251207.pdf のようなファイル名になります。

特定のフォルダのPDFを対象にする

引数でフォルダを指定できるようにする場合:

import sys
from pathlib import Path

# 引数があればそのフォルダ、なければカレントディレクトリ
if len(sys.argv) > 1:
    target_dir = Path(sys.argv[1])
else:
    target_dir = Path(__file__).parent

pdf_files = sorted(target_dir.glob("*.pdf"))

使い方:

python merge_pdf.py /path/to/pdf/folder

ページ範囲を指定して結合

特定のページだけ結合したい場合は、append() にページ範囲を指定できます:

# 1〜5ページだけ追加
writer.append(pdf, pages=(0, 5))

# 最初の3ページだけ追加
writer.append(pdf, pages=(0, 3))

活用シーン

このツールは様々な場面で活用できます。

ビジネスでの活用

シーン 具体例
レポート作成 月次報告書 + グラフ資料 + 参考データを1つに
請求書管理 月ごとの請求書をまとめてPDF化
プレゼン準備 スライド + 補足資料 + Q&A集を結合

個人での活用

シーン 具体例
書類整理 スキャンした書類を1ファイルにまとめる
学習資料 教材PDFを章ごとに並べ替えて結合
申請書類 複数の証明書を1ファイルにまとめて提出

バッチ処理への応用

このスクリプトをベースに、定期的な処理を自動化することもできます。

# 例:特定フォルダのPDFを毎日自動で結合
# (cronやタスクスケジューラと組み合わせて使用)

よくある質問(FAQ)

Q: Windowsでも動きますか?

A: はい、動きます。ただし、仮想環境の有効化コマンドが異なります。

  • Windows(コマンドプロンプト): .venv\Scripts\activate.bat
  • Windows(PowerShell): .venv\Scripts\Activate.ps1

Q: 大量のPDFでも大丈夫?

A: はい、対応しています。pypdfはメモリ効率が良く設計されているため、数百ファイルでも問題なく結合できます。ただし、結合後のファイルサイズが大きくなる点には注意してください。

Q: パスワード付きPDFは結合できますか?

A: パスワードで保護されたPDFを結合する場合は、追加の処理が必要です。

from pypdf import PdfReader, PdfWriter

reader = PdfReader("protected.pdf")
reader.decrypt("password")  # パスワードを指定

writer = PdfWriter()
for page in reader.pages:
    writer.add_page(page)

Q: 結合後のPDFにパスワードをかけられますか?

A: はい、可能です。

writer.encrypt("password")
writer.write(output_path)

まとめ

この記事では、Python初心者の方向けに、たった50行で作れるPDF結合ツールを解説しました。

学んだこと

  • pathlib でのファイル操作
  • 仮想環境(venv) の作成と管理
  • pypdf ライブラリの基本的な使い方
  • ユーザー入力 の処理方法
  • リスト内包表記 などのPythonらしい書き方

次のステップ

このツールを使いこなしたら、次のようなカスタマイズに挑戦してみてください。

  • GUIを付けてより使いやすく(tkinterやPyQt)
  • Webアプリ化してブラウザから操作(Flask, Streamlit)
  • PDF分割機能の追加

ソースコード

完成したコードはGitHubで公開しています。

https://github.com/yamato-snow/2025-12-03_pdf-merge-tool

スターやフォークをいただけると励みになります。

バグ報告や機能リクエストは、Issueでお気軽にどうぞ。


最後までお読みいただき、ありがとうございました。

この記事が「役に立った」と思っていただけたら、いいねやストックをお願いします。

Discussion