Pythonでpdfファイルを結合するには?
PDFファイルを結合して1つにまとめたいことがビジネスや日常業務の中で非常に多くあります。例えば以下のような場合です。
本記事では、Pythonでフォルダ内のPDFを結合する関数とGUIでフォルダを指定し結合するサンプルアプリを紹介します。
※プログラムは苦手だからexeファイルが欲しいという方は本ページの「最後に」を参照ください、GUIでフォルダを指定し結合するアプリを公開しています。
事前準備
サンプルコード実行用にtestpdf.zipファイルを以下からダウンロードします。
ダウンロード後は以下の図のようにCドライブにtestpdfというフォルダを作成し、その中にファイルをコピーしてください。
pdfファイルを結合するサンプルコード
次に、pdfファイルを結合するサンプルコードを紹介します。
import os
# pip install PyPDF2
from PyPDF2 import PdfReader, PdfWriter
def combine_pdf(folder_path, output_filename):
"""
指定されたフォルダ内の全てのPDFファイルを結合します。
Args:
folder_path (str): PDFファイルが含まれるフォルダのパス。
output_filename (str): 結合されたPDFファイルの出力名。
Returns:
bool: 処理が成功した場合はTrue、失敗した場合はFalseを返します。
"""
# 拡張子が'.pdf'のファイルのみをリストアップしてファイル名でソートします。
pdf_files = [f for f in os.listdir(folder_path) if f.endswith('.pdf')]
pdf_files.sort()
# PDFファイルが一つも見つからなかった場合、処理を終了します。
if not pdf_files:
print("PDFファイルが見つかりませんでした。")
return False
# PdfWriterオブジェクトを作成します。
pdf_writer = PdfWriter()
# フォルダ内の各PDFファイルに対して処理を行う。
for filename in pdf_files:
# ファイルのフルパスを取得しPDFファイルを読み込む。
filepath = os.path.join(folder_path, filename)
pdf_reader = PdfReader(filepath) #
for page in range(len(pdf_reader.pages)):
pdf_writer.add_page(pdf_reader.pages[page])
# 結果のPDFを指定された出力ファイルに書き込みます。
with open(output_filename, 'wb') as out:
pdf_writer.write(out)
print(f"{output_filename}にPDFファイルが結合されました。")
return True
##############################################################
# 関数のテスト
if __name__ == "__main__":
# 関数のテストを行います。指定されたパスにあるPDFを結合して、指定された出力ファイル名で保存します。
combine_pdf('c:\\testpdf', 'c:\\testpdf\\combine.pdf')
サンプルを実行する前にPyPDF2のインストールが必要ですのでインストールしていない場合には対応してください。
pip install PyPDF2
実行結果
c:\testpdf\combine.pdfにPDFファイルが結合されました。
結合されたcombine.pdfファイルが作成されます。
GUIで操作するサンプルコード
先ほどの例はコンソールから操作する例でしたが、ファイル名順で結合される処理しかできません。そのためGUI画面からファイルを選択して変換する例もサンプルも紹介します。
import os
import tkinter as tk
from tkinter import filedialog, scrolledtext, messagebox
# pip install PyPDF2
from PyPDF2 import PdfReader, PdfWriter
import webbrowser # PDFファイルを開くために必要
def select_folder():
"""
フォルダ選択ダイアログを開き、選択されたフォルダのパスを返します。
"""
folder_selected = filedialog.askdirectory()
if folder_selected:
folder_path.set(folder_selected)
display_pdf_files(folder_selected)
def display_pdf_files(folder_path):
"""
指定されたフォルダ内のPDFファイル一覧を表示します。
Args:
folder_path (str): ファイルを表示するフォルダのパス。
"""
try:
files = [f for f in os.listdir(folder_path) if f.endswith('.pdf')]
files.sort()
file_list_text.delete('1.0', tk.END)
for file in files:
file_list_text.insert(tk.END, file + '\n')
except Exception as e:
messagebox.showerror("エラー", f"エラー: {e}")
def combine_process():
"""
ScrolledTextウィジェットに表示された順番でPDFファイルを結合し、結合後にファイルを開きます。
"""
folder = folder_path.get()
pdf_files = file_list_text.get("1.0", "end-1c").splitlines()
if not pdf_files:
messagebox.showwarning("警告", "PDFファイルが見つかりませんでした。")
return
if folder:
output_filename = output_file_name_entry.get()
if not output_filename:
output_filename = "combined.pdf"
output_path = os.path.join(folder, output_filename)
if combine_pdf(folder, output_path):
messagebox.showinfo("成功", f"{output_path}にPDFが結合されました。")
webbrowser.open(output_path) # 結合したPDFファイルを開く
else:
messagebox.showerror("失敗", "PDF結合に失敗しました。")
else:
messagebox.showwarning("警告", "フォルダが選択されていません。")
def combine_pdf(folder_path, output_filename):
"""
ScrolledTextウィジェットに表示された順番でPDFファイルを結合します。
Args:
folder_path (str): PDFファイルが含まれるフォルダのパス。
output_filename (str): 結合されたPDFファイルの出力名。
Returns:
bool: 処理が成功した場合はTrue、失敗した場合はFalseを返します。
"""
pdf_files = file_list_text.get("1.0", "end-1c").splitlines()
pdf_writer = PdfWriter()
for filename in pdf_files:
filepath = os.path.join(folder_path, filename)
pdf_reader = PdfReader(filepath)
for page in range(len(pdf_reader.pages)):
pdf_writer.add_page(pdf_reader.pages[page])
with open(output_filename, 'wb') as out:
pdf_writer.write(out)
return True
def exit_app():
"""
アプリケーションを終了します。
"""
root.destroy()
# GUIのセットアップ
root = tk.Tk()
root.title("PDF結合ツール")
folder_path = tk.StringVar()
# GUIコンポーネントの設定
top_frame = tk.Frame(root)
top_frame.pack(pady=10)
folder_label = tk.Label(top_frame, text="PDFフォルダ:")
folder_label.pack(side=tk.LEFT)
folder_entry = tk.Entry(top_frame, textvariable=folder_path, width=50, state='readonly', readonlybackground='#ffffe0')
folder_entry.pack(side=tk.LEFT)
select_button = tk.Button(top_frame, text="フォルダ選択", command=select_folder, width=10)
select_button.pack(side=tk.LEFT)
# 新しいフレームを追加して出力ファイル名の入力フィールドを配置
output_file_frame = tk.Frame(root)
output_file_frame.pack(pady=10)
output_file_label = tk.Label(output_file_frame, text="出力ファイル名:")
output_file_label.pack(side=tk.LEFT)
output_file_name_entry = tk.Entry(output_file_frame, width=50)
output_file_name_entry.insert(0, "combined.pdf") # 初期値を設定
output_file_name_entry.pack(side=tk.LEFT)
bottom_frame = tk.Frame(root)
bottom_frame.pack(side=tk.BOTTOM, anchor='e')
file_list_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10)
file_list_text.pack(side=tk.LEFT)
combine_button = tk.Button(bottom_frame, text="PDF結合", command=combine_process, width=10)
combine_button.pack(side=tk.LEFT)
exit_button = tk.Button(bottom_frame, text="終了", command=exit_app, width=10)
exit_button.pack(side=tk.LEFT)
root.mainloop()
実行結果
フォルダ選択してPDF結合するとpdfファイルが結合され結合したファイルが自動的に起動します。
また、テキストエリアのファイル名の順番を変更するとその順番に結合できますし、ファイル名を削除すると結合対象から外れます。
exeファイルの作り方
exeファイルとして作成したい場合には、コンソールから以下コマンドでexe化してください。
※筆者はcombine_pdf_ui.pyという名前でファイル作成しています。
pyinstaller combine_pdf_ui.py --onefile --noconsole
最後に
以上がPythonでpdfファイルを結合する方法です。
PDFファイルを結合して1つにまとめたい利用シチュエーションは豊富にあると思いますので試してみてはいかがでしょうか。
また本プログラムのexeファイルもダウンロードできますので動作確認してみたい方は活用ください。
※zipファイルで圧縮されています。
実行時に「WindowsによってPCが保護されました」と表示される場合にはこちらを参照ください。
コメント