PDF分割/結合ツール『対全書式頁構造分離及び再接続統制機構』 ソースコード

『対全書式頁構造分離及び再接続統制機構』は、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()
        
    

📦 ダウンロード 🏠 ホームへ