『対全書式頁構造分離及び再接続統制機構』は、PDFファイルを対象に分割(ページ分離) および 結合(ページ結合) を行うGUIツールです。
>>GUI外観 >>使い方以下は『対全書式頁構造分離及び再接続統制機構』のソースコード全文です:
import os
from datetime import datetime
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from pypdf import PdfReader, PdfWriter
class PDFToolGUI(tk.Tk):
def __init__(self):
super().__init__()
self.title("PDF分割/結合ツール - 対全書式頁構造分離及び再接続統制機構")
self.geometry("700x450")
self.notebook = ttk.Notebook(self)
self.notebook.pack(fill="both", expand=True)
self.merge_tab = ttk.Frame(self.notebook)
self.split_tab = ttk.Frame(self.notebook)
self.notebook.add(self.merge_tab, text="結合モード")
self.notebook.add(self.split_tab, text="分割モード")
self.create_merge_tab()
self.create_split_tab()
# 起動時は結合モード
self.notebook.select(self.merge_tab)
# =========================
# 分割モード
# =========================
def create_split_tab(self):
frame = self.split_tab
self.split_pdf_path = tk.StringVar()
self.split_save_dir = tk.StringVar()
ttk.Button(frame, text="ファイル選択", command=self.select_split_pdf).pack(pady=5)
ttk.Label(frame, textvariable=self.split_pdf_path).pack(fill="x", padx=10)
ttk.Button(frame, text="保存先変更", command=self.select_split_dir).pack(pady=5)
ttk.Label(frame, textvariable=self.split_save_dir).pack(fill="x", padx=10)
ttk.Button(frame, text="分割", command=self.split_pdf).pack(pady=15)
def select_split_pdf(self):
path = filedialog.askopenfilename(filetypes=[("PDF", "*.pdf")])
if path:
self.split_pdf_path.set(path)
self.split_save_dir.set(os.path.dirname(path))
def select_split_dir(self):
dir_path = filedialog.askdirectory()
if dir_path:
self.split_save_dir.set(dir_path)
def split_pdf(self):
src = self.split_pdf_path.get()
if not src:
messagebox.showerror("エラー", "PDFファイルを選択してください。")
return
reader = PdfReader(src)
base = os.path.splitext(os.path.basename(src))[0]
save_dir = self.split_save_dir.get()
for i, page in enumerate(reader.pages, start=1):
writer = PdfWriter()
writer.add_page(page)
filename = f"{base}-div-{i:03}.pdf"
out_path = os.path.join(save_dir, filename)
with open(out_path, "wb") as f:
writer.write(f)
messagebox.showinfo("完了", "PDFの分割が完了しました。")
# =========================
# 結合モード
# =========================
def create_merge_tab(self):
frame = self.merge_tab
self.merge_list = tk.Listbox(frame, height=12)
self.merge_list.pack(fill="both", expand=True, padx=10, pady=5)
btn_frame = ttk.Frame(frame)
btn_frame.pack()
ttk.Button(btn_frame, text="ファイル選択", command=self.add_merge_pdf).grid(row=0, column=0, padx=5)
ttk.Button(btn_frame, text="↑", command=self.move_up).grid(row=0, column=1)
ttk.Button(btn_frame, text="↓", command=self.move_down).grid(row=0, column=2)
ttk.Button(btn_frame, text="リストから削除", command=self.remove_merge_pdf).grid(row=0, column=3, padx=5)
self.merge_save_dir = tk.StringVar()
ttk.Button(frame, text="保存先変更", command=self.select_merge_dir).pack(pady=5)
ttk.Label(frame, textvariable=self.merge_save_dir).pack(fill="x", padx=10)
ttk.Button(frame, text="結合", command=self.merge_pdfs).pack(pady=15)
def add_merge_pdf(self):
paths = filedialog.askopenfilenames(filetypes=[("PDF", "*.pdf")])
for p in paths:
self.merge_list.insert(tk.END, p)
if paths and not self.merge_save_dir.get():
self.merge_save_dir.set(os.path.dirname(paths[0]))
def remove_merge_pdf(self):
idx = self.merge_list.curselection()
if not idx:
return
if messagebox.askokcancel("確認", "選択したファイルをリストから削除しますか?"):
self.merge_list.delete(idx)
def move_up(self):
idx = self.merge_list.curselection()
if not idx or idx[0] == 0:
return
i = idx[0]
text = self.merge_list.get(i)
self.merge_list.delete(i)
self.merge_list.insert(i - 1, text)
self.merge_list.select_set(i - 1)
def move_down(self):
idx = self.merge_list.curselection()
if not idx or idx[0] == self.merge_list.size() - 1:
return
i = idx[0]
text = self.merge_list.get(i)
self.merge_list.delete(i)
self.merge_list.insert(i + 1, text)
self.merge_list.select_set(i + 1)
def select_merge_dir(self):
dir_path = filedialog.askdirectory()
if dir_path:
self.merge_save_dir.set(dir_path)
def merge_pdfs(self):
if self.merge_list.size() == 0:
messagebox.showerror("エラー", "PDFがリストにありません。")
return
writer = PdfWriter()
for path in self.merge_list.get(0, tk.END):
reader = PdfReader(path)
for page in reader.pages:
writer.add_page(page)
first = os.path.splitext(os.path.basename(self.merge_list.get(0)))[0]
now = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{first}-{now}_merged.pdf"
out_path = os.path.join(self.merge_save_dir.get(), filename)
with open(out_path, "wb") as f:
writer.write(f)
messagebox.showinfo("完了", "PDFの結合が完了しました。")
if __name__ == "__main__":
app = PDFToolGUI()
##タイトルバーアイコン表示用
data = '''R0lGODdhEAAQAIcAAP/zzvPy4fPn0PfkyOfcxuLYx+HWv9rMte3InsXIx+jFp9y/qMm/sb/Cvrq1tq6so6mejIeyzbmMZ8CHWbiGZMB7SLJ9T4uOja97VoGQmH59eXScwmiVsHOTrG2RtWaRtG+QqVaJrlGCqJ90Upl2W5ptSKBsRZxgOZhrRZdlQI9ePGdqdYxaP5VVL41VNY9UMIFbPHxTNWZVTWNxfl1sd1dpfFZlcUNzmUNkgUJrjjppkT1kjVthZk1hc0xWaT9egD5TZzlUbnpQOHtPMnhOMHFQPXNMM3dLNHlJLndDJ2Q+Jl5NRlFNTFBMTEZPW0FRZFpKRWBBLls+KmI8JWE5I1U7L2M0IWMzHFQ5K1I0IUg1LEU1LVcxHVQyIVEtHV0rEksuI00tHEwqGzpQajRLZj5KWTpKYS1SdS9LbzhJaDFCYCxCXy1BWCpBUTo9RjM/TTE6TC09TiY1URg5aRw1Wh81TjAzQik0QikvQCIzTB4yUiIrPCIrOR4qOB0ySRwwRRsvUhwtSBkqPFgoFEooGkQnGEInGEAkFz4jFz0iGDwgFD0fFTwcETIpKS4oLzIoJDsmHDMiHDghFjIcEikdHh8lMxcpQCAjLxcjMiEiJiceIyQaHiIYFBQZIyEWERwUDxsRExgSEBUQFR8LCBULCBQNDBMcMREZJgoXKQkVJxMUFhAUHRMSFAkPGwgOHAYPHBINDxEMDBMLCBELCA0KCQkKEgcKEAYLFAYLEhIJBw4IBxEGAwsICAwHBwkHCQoFBQcFBAoEAwgDBAcEAgYDBAYCAQMLIwUJDwEHEQEHEAQIDgMGEAMGDwMGDgUGCQQGCwMGDAQFDAUFBwQFBgMFCQEFCgQECgQEBgMDBAUEAwMDAwIEDQEEDAEDCAUEAgUDAgQDAQMDAgUCAgUCAQQCAgMCAgMCAQMCAAMBAQMBAAICBAECBgECBQEBBAEBAgIBAAEAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAEAAQAEAI/wDPnXO3jpq1aKJAESNHLt45b+9e9aiho48GBg4SEICA5YWKGLuqpcrRwYecQJoWMVKkBAWRYMO0PRuzYc0eOE6abIF0xIQUXePc4UJl6YkbKBImTEE0BEyuT8CQ+Xlj5kyDAAUQADggJEmhQ72UYWKjRwQaY3PojLJyYpCXSNm0XXNmi9spQTZ4ZGIlLBYvc+fKtTvWylUlRyRGTPL0KxStcOCmLcMRoYyMJUWMZAlDxQKMWe+61QliZ8cHECtYYKDg4gsXQ8WU0ZhBhs+DAQoWCDCgpUuKEqSS/clzo82qSyE4NOIUpYUYSemw3frhIY0aQKY2JSJ0pQISWN/UqSPqhOdOHCAZLjB5VIVSKVnpzJXTxg5as23MasGT5kscOoEBAQA7'''
app.tk.call('wm', 'iconphoto', app._w, tk.PhotoImage(data=data))
####
app.mainloop()