admin 发表于 2026-10-15 19:27:12

PDF批量合并

PDF批量合并

纯文本查看 复制代码import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import os
import threading
from queue import Queue
try:
    from PyPDF2 import PdfMerger
except ModuleNotFoundError:
    import sys
    sys.exit("Error: PyPDF2 模块未安装,请运行 'pip install PyPDF2' 进行安装")

class PDFMergerApp:
    def __init__(self):
      self.window = tk.Tk()
      self.window.title('📄 PDF合并打印软件')
      self.window.geometry('700x450')
      self.window.configure(bg='#F8FAFC')
      
      # 创建现代风格按钮
      self.button_style = {
            'background': '#4F46E5',
            'foreground': 'white',
            'borderwidth': 0,
            'relief': 'flat',
            'font': ('微软雅黑', 12, 'bold'),
            'padx': 30,
            'pady': 15
      }
      
      # 主容器框架,添加圆角和阴影效果
      main_frame = tk.Frame(self.window, bg='#FFFFFF')
      main_frame.grid_columnconfigure(0, weight=1)
      main_frame.grid_rowconfigure(1, weight=1)
      main_frame.pack(expand=True, fill='both', padx=35, pady=30)
      
      # 标题标签
      title_label = tk.Label(
            main_frame,
            text='PDF文件合并工具',
            font=('微软雅黑', 20, 'bold'),
            fg='#1E293B',
            bg='#FFFFFF',
            pady=20
      )
      title_label.grid(row=0, column=0, sticky='ew')
      
      # 文件选择按钮容器
      button_frame = tk.Frame(main_frame, bg='#FFFFFF', padx=20)
      button_frame.grid(row=1, column=0, sticky='ew')
      button_frame.grid_columnconfigure(0, weight=1)
      
      # 文件选择按钮
      select_button = tk.Button(
            button_frame,
            text='🖇️ 选择并合并PDF文件',
            command=self.select_and_merge_pdfs,
            cursor='hand2',
            **self.button_style
      )
      select_button.grid(row=0, column=0, pady=(25,35), sticky='ew')
      
      # 状态标签
      self.status_label = tk.Label(main_frame,
                                 text='准备就绪',
                                 font=('微软雅黑', 11),
                                 fg='#64748B',
                                 bg='#FFFFFF',
                                 padx=15,
                                 pady=12)
      self.status_label.grid(row=2, column=0, pady=(5,15), sticky='ew')
      
      # 配置悬停效果
      select_button.bind('<Enter>', lambda e: select_button.config(background='#4338CA'))
      select_button.bind('<Leave>', lambda e: select_button.config(background='#4F46E5'))
      
      # 设置窗口图标
      try:
            self.window.iconbitmap('pdf_icon.ico')
      except:
            pass
      
      # 用于线程间通信
      self.queue = Queue()

    def update_progress(self):
      try:
            while not self.queue.empty():
                msg = self.queue.get_nowait()
                if msg.startswith('status:'):
                  self.status_label['text'] = msg.split(':')
                elif msg.startswith('error:'):
                  messagebox.showerror('错误', f'处理PDF时出错:{msg.split(":", 1)}')
                elif msg == 'done':
                  return
      except Queue.Empty:
            pass
      self.window.after(50, self.update_progress)

    def merge_pdfs_thread(self, files):
      try:
            merger = PdfMerger(strict=False)
            total_files = len(files)
            
            for i, pdf_file in enumerate(files, 1):
                with open(pdf_file, 'rb') as pdf:
                  merger.append(fileobj=pdf, import_outline=False)
                self.queue.put(f'status:正在处理: {os.path.basename(pdf_file)}')

            
            output_path = os.path.join(os.path.dirname(files), 'merged_output.pdf')
            self.queue.put('status:正在保存文件...')
            with open(output_path, 'wb') as output:
                merger.write(fileobj=output)
            merger.close()
            
            self.queue.put('status:完成!')

            os.startfile(output_path)
            
      except Exception as e:
            self.queue.put(f'error:{str(e)}')
      finally:
            self.queue.put('done')
   
    def select_and_merge_pdfs(self):
      # 打开文件选择对话框
      files = filedialog.askopenfilenames(
            title='选择PDF文件',
            filetypes=[('PDF files', '*.pdf')]
      )
      
      if files:
            # 重置状态
            self.status_label['text'] = '准备处理...'
            
            # 启动处理线程
            thread = threading.Thread(target=self.merge_pdfs_thread, args=(files,))
            thread.daemon = True
            thread.start()
            
            # 启动进度更新
            self.window.after(100, self.update_progress)

    def run(self):
      self.window.mainloop()

if __name__ == '__main__':
    app = PDFMergerApp()
    app.run()
页: [1]
查看完整版本: PDF批量合并