import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
from PyPDF2 import PdfReader
class PDFPageCounterApp:
def __init__(self, root):
self.root = root
self.root.title("PDF页数统计工具")
self.root.geometry("800x600")
self.root.resizable(True, True)
# 初始化变量
self.folder_path = tk.StringVar()
self.total_pages = tk.IntVar(value=0)
self.file_count = tk.IntVar(value=0)
self.file_details = {}
# 创建UI组件
self.create_widgets()
# 设置样式
self.set_styles()
def create_widgets(self):
# 主框架
main_frame = ttk.Frame(self.root, padding="20")
main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
title_label = ttk.Label(main_frame, text="PDF页数统计工具", font=("Arial", 16, "bold"))
title_label.pack(pady=(0, 20))
# 文件夹选择区域
folder_frame = ttk.LabelFrame(main_frame, text="选择PDF文件夹")
folder_frame.pack(fill=tk.X, pady=10)
folder_entry = ttk.Entry(folder_frame, textvariable=self.folder_path, width=50)
folder_entry.pack(side=tk.LEFT, padx=5, pady=5, fill=tk.X, expand=True)
browse_button = ttk.Button(folder_frame, text="浏览...", command=self.browse_folder)
browse_button.pack(side=tk.RIGHT, padx=5, pady=5)
# 控制按钮区域
button_frame = ttk.Frame(main_frame)
button_frame.pack(fill=tk.X, pady=10)
count_button = ttk.Button(button_frame, text="开始统计", command=self.start_counting)
count_button.pack(side=tk.LEFT, padx=5)
export_button = ttk.Button(button_frame, text="导出结果", command=self.export_results)
export_button.pack(side=tk.LEFT, padx=5)
clear_button = ttk.Button(button_frame, text="清空结果", command=self.clear_results)
clear_button.pack(side=tk.LEFT, padx=5)
# 统计结果区域
result_frame = ttk.LabelFrame(main_frame, text="统计结果")
result_frame.pack(fill=tk.BOTH, expand=True, pady=10)
# 摘要信息
summary_frame = ttk.Frame(result_frame)
summary_frame.pack(fill=tk.X, pady=5)
ttk.Label(summary_frame, text="文件夹路径:").grid(row=0, column=0, sticky=tk.W, padx=5)
ttk.Label(summary_frame, textvariable=self.folder_path).grid(row=0, column=1, sticky=tk.W, padx=5)
ttk.Label(summary_frame, text="文件总数:").grid(row=1, column=0, sticky=tk.W, padx=5)
ttk.Label(summary_frame, textvariable=self.file_count).grid(row=1, column=1, sticky=tk.W, padx=5)
ttk.Label(summary_frame, text="总页数:").grid(row=2, column=0, sticky=tk.W, padx=5)
ttk.Label(summary_frame, textvariable=self.total_pages).grid(row=2, column=1, sticky=tk.W, padx=5)
# 详细结果表格
columns = ("文件名", "页数", "路径")
self.tree = ttk.Treeview(result_frame, columns=columns, show="headings", height=15)
for col in columns:
self.tree.heading(col, text=col)
self.tree.column(col, width=150, anchor=tk.W)
self.tree.column("路径", width=300)
scrollbar = ttk.Scrollbar(result_frame, orient=tk.VERTICAL, command=self.tree.yview)
self.tree.configure(yscroll=scrollbar.set)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.tree.pack(fill=tk.BOTH, expand=True, pady=10)
# 状态栏
self.status_var = tk.StringVar(value="就绪")
status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
def set_styles(self):
style = ttk.Style()
style.configure("TButton", padding=6)
style.configure("TLabel", padding=5)
style.configure("Treeview", rowheight=25)
style.configure("Treeview.Heading", font=('Arial', 10, 'bold'))
def browse_folder(self):
folder_selected = filedialog.askdirectory()
if folder_selected:
self.folder_path.set(folder_selected)
self.status_var.set(f"已选择文件夹: {folder_selected}")
def start_counting(self):
folder = self.folder_path.get()
if not folder:
messagebox.showwarning("警告", "请先选择PDF文件夹")
return
if not os.path.isdir(folder):
messagebox.showerror("错误", "文件夹路径无效")
return
self.status_var.set("正在统计PDF页数,请稍候...")
self.root.update() # 更新界面显示状态
total_pages, file_details = self.count_pdf_pages(folder)
# 更新结果
self.total_pages.set(total_pages)
self.file_count.set(len(file_details))
self.file_details = file_details
# 更新表格
self.tree.delete(*self.tree.get_children())
for filename, (pages, full_path) in file_details.items():
self.tree.insert("", tk.END, values=(filename, pages, full_path))
self.status_var.set(f"统计完成! 共找到 {len(file_details)} 个PDF文件,总计 {total_pages} 页")
def count_pdf_pages(self, folder_path):
total_pages = 0
file_details = {}
for root, _, files in os.walk(folder_path):
for file in files:
if file.lower().endswith('.pdf'):
file_path = os.path.join(root, file)
try:
with open(file_path, 'rb') as f:
reader = PdfReader(f)
if reader.is_encrypted:
reader.decrypt('')
page_count = len(reader.pages)
total_pages += page_count
file_details[file] = (page_count, file_path)
# 实时更新状态
self.status_var.set(f"处理中: {file} - {page_count}页")
self.root.update()
except Exception as e:
file_details[file] = (f"错误: {str(e)}", file_path)
return total_pages, file_details
def export_results(self):
if not self.file_details:
messagebox.showinfo("提示", "没有可导出的结果")
return
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
)
if not file_path:
return
try:
with open(file_path, "w", encoding="utf-8") as f:
f.write(f"PDF页数统计报告\n")
f.write(f"统计时间: {os.popen('date /t').read().strip()} {os.popen('time /t').read().strip()}\n")
f.write(f"文件夹路径: {self.folder_path.get()}\n")
f.write(f"文件总数: {self.file_count.get()}\n")
f.write(f"总页数: {self.total_pages.get()}\n\n")
f.write("=" * 80 + "\n")
f.write(f"{'文件名':
