PDFを結合したい場合にどのような方法で行っていますか?Acrobat Readerを使っていて結合ができそうな感じのあるアイコンをクリックしたら試用版7日と表示されがっかりしたことはないですか?

PDFの結合に関してはAdobe AcrobatやいきなりPDFなど有料のソフトを利用している人、無料ソフトをインストールして使用している人、SmallPDFやiLovePDFなどオンラインで行っている人などさまざまだと思います。

複数枚のPDFを1枚ずつ印刷して、まとめて複合機でスキャンして1つのPDFファイルにするという人をみたこともあります。

有料ソフトを買う余裕もない、無料ソフトやクラウドどのオンラインサイトでのPDF結合ではセキュリティに不安だと思っている人にぜひ試してもらいたいのがPythonのPDF結合です。一度プログラムを作成すると簡単にPDFの結合を行うことができます。

Pythonを使って業務を効率的にする第一歩としてPDFの結合方法を理解することはハードルが低い非常にいい題材だと思います。特にPythonでの自動化に興味がある人におすすめです。

本文書の公開時にはPyPDF2のバージョン2を利用しておりましたがバージョン3になり、それ以降はpfpdfで開発が継続されることになっています。本文書ではpfpdfを利用した方法を後半に記述しています。どちらを利用してもPDFの結合は動作はしますが今後のことを考えてpfpdfを利用しましょう。

PyPDF2パッケージのインストール

Windows10を動作確認を行っています。

PythonでPDFの結合を行うためには、Pythonの標準ライブラリには含まれていないPyPDF2パッケージをインストールする必要があります。インストールはパッケージ管理のpipを利用して行います。


>pip install pypdf2
Collecting pypdf2
  Downloading pypdf2-3.0.1-py3-none-any.whl (232 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 232.6/232.6 kB 1.6 MB/s eta 0:00:00
Installing collected packages: pypdf2
Successfully installed pypdf2-3.0.1

pip listコマンドを利用するとインストールが完了しているパッケージの一覧が表示されるのでインストールが正常に行われているか確認することができます。


>pip iist
Package Version
------- -------
pip     23.3.1
PyPDF2  3.0.1

PDFの結合

最もシンプルな結合方法

PDFファイルを事前に用意して、pythonプログラムを使って結合を行います。

まずtest.pyファイルを作成し、下記のコードを書き込みます。pyファイルが存在するフォルダの中に事前に準備している1.pdf, 2.pdfという名前の2つのPDFファイルを保存します。


from PyPDF2 import PdfFileMerger

pdf_file_merger = PdfFileMerger()

pdf_file_merger.append('./1.pdf')

pdf_file_merger.append('./2.pdf')

pdf_file_merger.write('merge.pdf')

pdf_file_merger.close()
PyPDF2のバージョンがアップしたために関数が変更になっています。”PyPDF2.errors.DeprecationError: PdfFileMerger is deprecated and was removed in PyPDF2 3.0.0. Use PdfMerger instead.”のメッセージが表示された場合はPdfFileMergerではなくPdfMergerを利用してください。
fukidashi

上から順番に1行1行コードの説明を行っていきます。

  • PyPDF2パッケージからPdfFileMergerをimportします。
  • PdfFileMergerを実行してその戻り値をpdf_file_merger変数に保存します。
  • pdf_file_mergerのappendメソッドでファイルと追加します。
  • pdf_file_mergerのwriteメソッドでファイルを作成します。

上記を実行すると同じフォルダにmerge.pdfという名前のPDFファイルが作成されます。

これだけの処理でPDFの結合を行うことができます。

appendメソッドとwriteメソッドで指定するファイル名は各自の環境に合わせて変更を行ってください。
fukidashi

append、writeメソッドでファイルパスを設定していますが、パスではなくファイルオブジェクトを利用することも可能です。

ファイルオブジェクトを利用して結合

先ほどはパスを利用してファイルの結合を行っていましたが、下記のようにファイルオブジェクトを使っても結合を行うことができます。openメソッドでファイルを開いて、開いたファイルをappendメソッドで追加しています。


from PyPDF2 import PdfFileMerger

pdf_file_merger = PdfFileMerger()

with open('./1.pdf','rb') as f1:

	pdf_file_merger.append(f1)

with open('./2.pdf','rb') as f2:

	pdf_file_merger.append(f2)

with open('./merge2.pdf','wb') as f3:

	pdf_file_merger.write(f3)
open時のrbはread+binaryモードを表しています。
fukidashi

実践的なPDFファイルの結合

PDFのファイルの結合を行うことができましたが、説明した方法では、実行する前にファイルの名前を確認してPythonファイルに記述する必要があります。2個、3個のファイル名の場合はファイル名の修正を毎回行うことができるかもしれませんが自動化からほど遠く10個、20個のファイルになると非効率なため業務では利用できません。

より効率的にPDFの結合ができるように任意のフォルダ内に保存されたPDFファイルの名前を自動的に取得して結合するプログラムに変更します。

PDFファイルの名前を取得(glob)

これまでファイル名を指定していたPDF結合とは異なり、フォルダに保存されているPDFファイルの名前を自動で取得する方法が必要になります。

フォルダ下に保存されているファイル名を取得するためにglobモジュールを利用します。


import glob

for file_name in glob.glob('*.pdf'):
	
	print(file_name)

上記のプログラムを実行すると実行したpyファイルの存在するフォルダ内のPDFファイルの名前のみ表示されます。*.pdfを設定しているためPDFファイル以外は表示されません。


>py glob_test.py
1.pdf
2.pdf

globパッケージを利用するとPDFのファイル名のみ取得できることが確認できました。

拡張子が大文字のPDFの場合もありますが、globでは小文字でも大文字でもPDFファイルの名前を取得してくれます。
fukidashi

globを使った結合

for文を使うことでglobパッケージを使って取得したファイル名を個別に取り出すことができます。取り出したファイル名をappendメソッドで指定することで追加を行うことができます。


import glob
from PyPDF2 import PdfFileMerger

pdf_file_merger = PdfFileMerger()

for file_name in glob.glob('*.pdf'):

	pdf_file_merger.append(file_name)

pdf_file_merger.write('merge.pdf')

pdf_file_merger.close()

実行後は、merge.pdfファイルが同じフォルダに作成されます。pyファイルが存在するフォルダ内のpdfファイル名を取得することができるので、実行前に手動でpyファイル内のファイル名を更新、追加する必要がなくなりました。

Pythonランチャーを使う

WindowsではpyファイルがPythonランチャーに関連付けられていればファイル名をダブルクリックするだけでプログラムを実行することができます。

ファイルを右クリックするとpyファイルに関連付いているアプリケーションがわかるので確認を行ってください。ロケットのアイコンが特徴です。

Pythonランチャー
Pythonランチャー

関連付けられていればダブルクリックするだけで結合のプログラムが実行されます。

実践的な結合の流れ

  1. デスクトップ等に任意の名前を付けたフォルダを作成します。
  2. 作成したフォルダの中に作成したPythonファイルを保存します。
  3. 結合したいPDFファイルをそのフォルダの中に入れます。
  4. Pythonファイルをダブルクリックします。
  5. PDFファイルが結合されたmerge.pdfというファイルが作成されます。merge.pdfファイルをフォルダから取り出します。
  6. 結合するために保存したPDFファイルのみ削除して、フォルダにはPythonファイル1つが保存された状態にします。

一度1~6を実施後、フォルダを変更しないのであれば3~6を繰り返すことでPDFの結合を行うことができます。

結合後のファイルの名前merge.pdfはpyファイルの中で変更可能です。
fukidashi

pypdfパッケージを利用した場合

pypdfのインストール

PfPDF2ではなくpypdfパッケージを利用した場合の動作確認です。まずpypdfのインストールを行います。


 % pip install pypdf
Collecting pypdf
  Downloading pypdf-3.17.2-py3-none-any.whl.metadata (7.5 kB)
Downloading pypdf-3.17.2-py3-none-any.whl (277 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 277.9/277.9 kB 2.1 MB/s eta 0:00:00
Installing collected packages: pypdf
Successfully installed pypdf-3.17.2

PDFの結合

もっとも基本的な方法

ドキュメントに記載されているもっとも簡単な方法で、ファイル名を指定してPDFに含まれるすべてのページが結合されます。


from pypdf import PdfWriter

merger = PdfWriter()

for pdf in ["./1.pdf", "./2.pdf"]:
    merger.append(pdf)

merger.write("merged.pdf")
merger.close()

pfpdfパッケージからPdfWriterをimportします。配列でファイルを指定してmerger.appendメソッドを利用してファイルを追加してmerger.writeメソッドでファイルを書き出します。

globを利用した方法

for文を使うことでglobパッケージを使って取得したファイル名を個別に取り出すことができます。取り出したファイル名をappendメソッドで指定することで追加を行うことができます。


import glob
from pypdf import PdfWriter

merger = PdfWriter()

for pdf in glob.glob('*.pdf'):
    merger.append(pdf)

merger.write("merged2.pdf")
merger.close()

ファイルの一部のページを結合

ここまでの動作確認では指定してファイルのすべてのページが結合されましたがファイルの一部のページのに結合に利用したい場合には以下の方法で行うことができます。


import glob
from pypdf import PdfWriter

merger = PdfWriter()

input1 = open("./1.pdf", "rb")
input2 = open("./2.pdf", "rb")

merger.append(input1)
merger.append(fileobj=input2, pages=(0, 4))

merger.write("merged2.pdf")
merger.close()

2.pdfファイルについては複数のページで構成されているので最初の4ページのみ取り出して結合を行っています。

このようにPythonのパッケージを利用することで無料で簡単にPDFの結合を行うことができます。