PythonでPDFを自由自在に操る!PyPDF2で結合・分割のテクニック
PDF(Portable Document Format)は、ビジネスから個人利用まで、あらゆる場面で使われる普遍的なドキュメント形式です。しかし、複数のPDFを一つにまとめたり、逆に大きなPDFから必要なページだけを抜き出したりといった作業は、手動で行うと非常に手間がかかります。
そこで役立つのがPythonの強力なライブラリ**PyPDF2
です。PyPDF2
を使えば、PDFファイルをプログラムから簡単に結合したり、特定のページや範囲で分割**したりすることができます。この記事では、PyPDF2
を用いたPDFの結合・分割の基本的な手順を、短いサンプルコードとともに分かりやすく解説します。PDFの効率的な管理と自動化を目指す方にとって、必見の内容です。
なぜPDFを結合・分割する必要があるのか?
PDFの結合や分割は、様々な業務プロセスを効率化するために不可欠な操作です。
結合 (Merge)
レポートの統合: 複数の部署から提出されたPDF形式の週報や月報を、一つのマスターレポートにまとめる。
資料の整理: 関連する複数のPDF資料(例:提案書、補足資料、契約書)を一つに統合し、管理を容易にする。
電子書籍の作成: バラバラの章ファイルや記事を結合して、一つのPDF電子書籍を作成する。
分割 (Split)
特定ページの抽出: 大量のページを持つPDFから、必要な数ページだけを抜き出して共有する。
ファイルサイズの最適化: 大きすぎるPDFファイルを章やセクションごとに分割し、メール添付やWebアップロードに適したサイズにする。
個人情報の分離: 共有する部分と非公開の部分が混在するPDFから、公開可能なページだけを分離する。
PyPDF2
とは?
PyPDF2
は、PythonでPDFファイルを操作するための包括的なライブラリです。PDFの結合、分割、ページの抽出、透かしの追加、情報の取得・設定など、多岐にわたる機能を提供します。PythonでPDFの自動処理を行う際のデファクトスタンダードと言えるでしょう。
インストール方法
使用する前に、pipコマンドでインストールが必要です。
pip install PyPDF2
PDFファイルを結合する
複数のPDFファイルを一つに結合するには、PyPDF2.PdfWriter
オブジェクトを使用し、append_pages_from_reader()
またはadd_page()
メソッドでページを追加していきます。
基本的な結合の手順
PdfWriter
オブジェクトを作成する: 新しい結合済みPDFを作成するためのオブジェクトです。結合したいPDFファイルを順に読み込む:
PdfReader
で各PDFファイルを開きます。各PDFのページを
PdfWriter
に追加する:PdfWriter.append_pages_from_reader()
メソッドを使って、PDFリーダーから全てのページを一括で追加します。特定のページだけ追加したい場合はPdfWriter.add_page()
を使います。新しいPDFファイルとして保存する: 結合されたPDFファイルを書き出します。
from PyPDF2 import PdfWriter, PdfReader
import os
# --- テスト用のPDFファイルを仮作成 (結合用) ---
# pdf1.pdf
writer1 = PdfWriter()
writer1.add_blank_page(width=500, height=700).add_label("1-A")
writer1.add_blank_page(width=500, height=700).add_label("1-B")
with open("pdf1.pdf", "wb") as f:
writer1.write(f)
# pdf2.pdf
writer2 = PdfWriter()
writer2.add_blank_page(width=500, height=700).add_label("2-C")
writer2.add_blank_page(width=500, height=700).add_label("2-D")
with open("pdf2.pdf", "wb") as f:
writer2.write(f)
print("テスト用に 'pdf1.pdf' と 'pdf2.pdf' を作成しました。\n")
# ----------------------------------------------------
# 結合したいPDFファイル名
pdf_files_to_merge = ["pdf1.pdf", "pdf2.pdf"]
output_merged_pdf = "merged_document.pdf"
# PdfWriterオブジェクトを作成
pdf_merger = PdfWriter()
try:
# 各PDFファイルを読み込み、ページを追加
for pdf_file in pdf_files_to_merge:
# 既存のPDFを読み込む
reader = PdfReader(pdf_file)
# 読み込んだPDFの全ページをマージ対象に追加
pdf_merger.append_pages_from_reader(reader) # 全ページを追加
# 特定のページのみ追加する場合の例:
# for page_num in range(len(reader.pages)):
# pdf_merger.add_page(reader.pages[page_num])
# 結合されたPDFを保存
with open(output_merged_pdf, "wb") as f:
pdf_merger.write(f)
print(f"'{pdf_files_to_merge}' を結合し、'{output_merged_pdf}' として保存しました。")
except FileNotFoundError as e:
print(f"エラー: ファイルが見つかりません - {e.filename}")
except Exception as e:
print(f"結合中にエラーが発生しました: {e}")
# 出力例:
# テスト用に 'pdf1.pdf' と 'pdf2.pdf' を作成しました。
# ['pdf1.pdf', 'pdf2.pdf'] を結合し、'merged_document.pdf' として保存しました。
PDFファイルを分割する
一つのPDFファイルから、必要なページを抽出して新しいPDFファイルとして保存します。ファイル全体を複数のPDFに分割したり、特定のページ範囲だけを抜き出したりできます。
1. 全ページを個別のPDFファイルに分割する
各ページをそれぞれ独立したPDFファイルとして保存します。
from PyPDF2 import PdfWriter, PdfReader
import os
# 分割元のPDFファイル名 (上記で作成した merged_document.pdf を使用)
input_pdf_for_split = "merged_document.pdf"
output_folder = "split_pages"
# 出力フォルダが存在しない場合は作成
if not os.path.exists(output_folder):
os.makedirs(output_folder)
try:
# 分割元のPDFを読み込む
reader = PdfReader(input_pdf_for_split)
# 各ページを個別のファイルに保存
for i, page in enumerate(reader.pages):
writer = PdfWriter() # 各ページごとに新しいWriterを作成
writer.add_page(page) # ページを追加
output_filepath = os.path.join(output_folder, f"page_{i+1}.pdf")
with open(output_filepath, "wb") as f:
writer.write(f)
print(f"ページ {i+1} を '{output_filepath}' として保存しました。")
except FileNotFoundError:
print(f"エラー: '{input_pdf_for_split}' が見つかりません。結合ステップを実行してください。")
except Exception as e:
print(f"分割中にエラーが発生しました: {e}")
# 出力例:
# ページ 1 を 'split_pages/page_1.pdf' として保存しました。
# ページ 2 を 'split_pages/page_2.pdf' として保存しました。
# ページ 3 を 'split_pages/page_3.pdf' として保存しました。
# ページ 4 を 'split_pages/page_4.pdf' として保存しました。
2. 特定のページ範囲を抽出して新しいPDFファイルを作成する
特定の開始ページから終了ページまでの範囲を抽出して、新しいPDFファイルを作成します。
from PyPDF2 import PdfWriter, PdfReader
import os
# 分割元のPDFファイル名 (上記で作成した merged_document.pdf を使用)
input_pdf_for_range_split = "merged_document.pdf"
output_ranged_pdf = "extracted_pages.pdf"
# 抽出したいページ範囲(例:2ページ目から3ページ目まで)
# PyPDF2のページインデックスは0から始まる
start_page_index = 1 # 2ページ目 (インデックスは1)
end_page_index = 3 # 4ページ目 (インデックスは3, ここは含まれない)
try:
reader = PdfReader(input_pdf_for_range_split)
writer = PdfWriter()
# 指定されたページ範囲を追加
# reader.pagesはリストのように扱える
for i in range(start_page_index, end_page_index):
if i < len(reader.pages): # 範囲がPDFの総ページ数を超えないようにチェック
writer.add_page(reader.pages[i])
else:
print(f"警告: ページインデックス {i} はPDFの範囲外です。")
break
# 抽出されたページを含むPDFを保存
with open(output_ranged_pdf, "wb") as f:
writer.write(f)
print(f"'{input_pdf_for_range_split}' からページ {start_page_index+1} から {end_page_index} を抽出し、'{output_ranged_pdf}' として保存しました。")
except FileNotFoundError:
print(f"エラー: '{input_pdf_for_range_split}' が見つかりません。結合ステップを実行してください。")
except Exception as e:
print(f"範囲抽出中にエラーが発生しました: {e}")
# 出力例:
# 'merged_document.pdf' からページ 2 から 3 を抽出し、'extracted_pages.pdf' として保存しました。
reader.pages
は、PDFの各ページオブジェクトにアクセスするためのリストのようなオブジェクトです。ページインデックスは0から始まるため、例えば2ページ目を指す場合はインデックス
1
を指定します。range(start, end)
ではend
の値は含まれないため、抽出したい最後のページのインデックス+1
を指定する必要があります。
まとめと活用例
PyPDF2
ライブラリは、PythonでPDFファイルの結合と分割を行うための非常に効率的で柔軟なツールです。
自動レポート生成と配布: 複数のデータソースから生成されたPDFを結合し、月次レポートとして自動生成・配布する。
ドキュメントの整理とアーカイブ: 大量のPDF文書を、日付や内容に応じて適切な単位で分割・結合し、整理された状態でアーカイブする。
機密情報のマスキングと共有: 大規模なPDFから公開可能な部分だけを抽出し、それ以外の機密情報を含まない新しいPDFを作成して共有する。
電子書籍のカスタマイズ: 個別のPDF章ファイルを結合して、自分だけのカスタム電子書籍を作成する。
PyPDF2
を使いこなすことで、PDFファイルの管理と処理を自動化し、日々の業務を大幅に効率化できるでしょう。ぜひ、あなたのPythonプロジェクトにPyPDF2
を取り入れてみてください。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座