どうもこんにちは。コンです。
今日はPythonのライブラリの1つであるPyPDF2とtkinterを使って
PDFを1枚1枚分割するアプリの作成について解説したいと思います。
1枚1枚分割とは、例えばtest.pdfファイルが3ページ構成だとしたら、test_1.pdf, test_2.pdf, test_3.pdfのように1ページごとに1つのpdfにすることを意図しております。
会社によっては、PDFを扱うソフトが充実していないという所もあると思うので
是非このアプリを活用してもらえたらと思います。
作成したアプリ
今回作成したアプリは PDFを読み込んで、分割したPDFの出力先を選び、1つ1つ保存するアプリです。
- PDFファイルを選択するために「Select PDF」というボタンを押す&ユーザーがファイル選択。
- 選択したPDFファイルのファイル名を表示。
- 分割したPDFファイルを保存するフォルダーを選択するための「Select Output Folder」というボタンを押す&ユーザーがフォルダ選択。
- 選択したフォルダーのパスを表示。
- 「Split PDF」というボタンを提供し、クリックすると、選択したPDFファイルを単一のページに分割し、各ページを別々のPDFファイルとして、選択した出力フォルダーに保存。
- 処理が完了したことをユーザーに通知するために、「PDF split successfully!」というメッセージを表示。
という動きをするように最初に決めて、コーディングに取り掛かりました。
アプリのGUIは以下のようなシンプルなものにしました。
ボタンは3つで
Select PDF:分割するPDFファイルを選択するボタン
Select Output Folder : 分割したPDFを保存するフォルダを選択するボタン
Split PDF:PDFの分割を実行するボタン
で構成されています。
選択したファイル名やフォルダが分かりやすいように、ボタンの下に/文字で出力するようになってます。
上の写真の例だとtest.pdfを分割して、デスクトップに分割したpdfを作成するので
デスクトップにはtest_1~test_3のPDFファイルが作成されました。
また今回は分割に成功すると、成功したよ〜的なメッセージボックスがでるようにしました。
Pythonコード
今回のアプリは、1つのPythonコードのファイルだけで作成しました。
import os
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
import PyPDF2
class PDFSplitter:
def __init__(self, root):
self.root = root
self.root.title("PDF Splitter")
self.root.geometry("500x300")
#UI作成
self.btn_select_file = tk.Button(self.root, text="Select PDF", command=self.select_file)
self.btn_select_file.pack(pady=10)
self.lbl_file_name = tk.Label(self.root, text="Selected File: Not Selected")
self.lbl_file_name.pack(pady=10)
self.btn_select_folder = tk.Button(self.root, text="Select Output Folder", command=self.select_folder)
self.btn_select_folder.pack(pady=10)
self.lbl_output_folder = tk.Label(self.root, text="Output Folder: Not Selected")
self.lbl_output_folder.pack(pady=10)
self.btn_split = tk.Button(self.root, text="Split PDF", command=self.split_pdf)
self.btn_split.pack(pady=10)
#PDFファイルを開いて、ファイル名を取得する
def select_file(self):
# Open file dialog to select PDF file
self.file_path = filedialog.askopenfilename(initialdir="/", title="Select PDF File", filetypes=(("PDF files", "*.pdf"),))
self.lbl_file_name.configure(text=f"Selected File: {os.path.basename(self.file_path)}")
#分解したPDFを置くフォルダーの選択
def select_folder(self):
self.output_folder = filedialog.askdirectory(initialdir="/", title="Select Output Folder")
self.lbl_output_folder.configure(text=f"Output Folder: {self.output_folder}")
def split_pdf(self):
# Check
if not hasattr(self, "file_path") or not hasattr(self, "output_folder"):
return
#PDFファイルを開く
pdf_file = open(self.file_path, "rb")
pdf_reader = PyPDF2.PdfFileReader(pdf_file)
filename = os.path.basename(self.file_path)
filename_no_extension = os.path.splitext(filename)[0]
#分解
for page_num in range(pdf_reader.getNumPages()):
#ファイル名の作成
output_file_name = os.path.join(self.output_folder, filename_no_extension+f"{page_num + 1}.pdf")
#1ページづつ保存する。
pdf_writer = PyPDF2.PdfFileWriter()
pdf_writer.addPage(pdf_reader.getPage(page_num))
with open(output_file_name, "wb") as output_file:
pdf_writer.write(output_file)
#PDFを閉じる
pdf_file.close()
#メッセージ
messagebox.showinfo("PDF Splitter", "PDF split successfully!")
def main():
root = tk.Tk()
app = PDFSplitter(root)
root.mainloop()
if __name__=="__main__":
main()
このコードはPythonのライブラリであるPyPDF2を使って、PDFファイルを分割するGUIアプリケーションを実装したものです。
特に今回のコードの肝はsplit_pdfメソッドになります。
PyPDF2.PdfFileReaderは調べてみると
file = open(‘PDFファイル, ‘rb’)
reader = PyPDF2.PdfFileReader(file)のようにopenとセットで使うらしいので、今回は私もopenで開いてから使用しました。
PDFファイルを開くと、PyPDF2.PdfFileReaderオブジェクトが作成され、ページ数を取得できます。
次に、for文を使って1ページごとにPDFファイルを抽出し、PyPDF2.PdfFileWriterオブジェクトを使用して出力ファイルにページを書き込みます。
おわりに
ここまで読んでいただき、ありがとうました。
今回の記事は、自分の職場でも使えそうなアプリを考えてみようとして
実際にどういうものがあったら便利かを考え、実装してみました。
Excelファイルより、PDFの扱いの方が個人的には難しく、苦労しました。。。。
今回のデスクトップアプリのコードが皆様の何かしらの参考になれば嬉しいです。
それでは。