|
|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- import os
- import tkinter as tk
- from tkinter import filedialog, messagebox
- from openpyxl import load_workbook
- import win32com.client
- import xlrd
- import sys
- # 创建 Tk 实例并隐藏主窗口
- root = tk.Tk()
- root.withdraw() # 隐藏默认窗口
- # 定义全局变量存储勾选框状态
- checkbox_vars = {} # 只需定义一次
- def create_checkbutton_command(key, var):
- """闭包工厂函数确保正确绑定变量"""
- def _command():
- pass # 调试信息已移除
- return _command
- # 获取用户选择的文件夹路径
- folder_path = filedialog.askdirectory()
- if not folder_path:
- messagebox.showerror("错误", "未选择文件夹")
- exit()
-
- # 打印选中的文件夹路径(可选)
- # print(f"Selected folder path: {folder_path}")
- # 搜索文件夹内的所有 Excel 或 WPS 表格文件
- excel_files = []
- for root, dirs, files in os.walk(folder_path):
- for file in files:
- if file.endswith((".xlsx", ".xls",".et",".xlsm")):
- excel_files.append(os.path.join(root, file))
- if not excel_files:
- messagebox.showinfo("提示", "未找到 Excel 或 WPS 表格文件")
- exit()
- # 创建 Tkinter 窗口
- window = tk.Tk()
- window.title("选择工作表")
- window.geometry("800x600")
- # 确保没有默认窗口
- root = tk.Tk() # 假设这里无意中创建了默认窗口
- root.withdraw() # 隐藏默认窗口
- # 创建滚动区域
- canvas = tk.Canvas(window)
- scrollbar_y = tk.Scrollbar(window, orient="vertical", command=canvas.yview)
- scrollbar_x = tk.Scrollbar(window, orient="horizontal", command=canvas.xview)
- scrollable_frame = tk.Frame(canvas)
- # 配置滚动区域
- scrollable_frame.bind(
- "<Configure>",
- lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
- )
- canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
- canvas.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
- # 添加鼠标滚轮支持
- def _on_mousewheel(event):
- try:
- canvas.yview_scroll(int(-1*(event.delta/120)), "units")
- except tk.TclError:
- pass # 忽略滚动错误
-
- canvas.bind_all("<MouseWheel>", _on_mousewheel)
- # 布局滚动区域到窗口顶部
- canvas.pack(side="top", fill="both", expand=True)
- scrollbar_y.pack(side="right", fill="y")
- scrollbar_x.pack(side="bottom", fill="x")
- # 遍历每个 Excel 文件,获取工作表名称并创建勾选框
- for file_path in excel_files:
- # 获取工作表名称
- if file_path.endswith(".xls"):
- try:
- workbook = xlrd.open_workbook(file_path)
- sheet_names = workbook.sheet_names()
- except Exception as e:
- messagebox.showerror("文件错误", f"无法读取 {file_path}\n错误: {str(e)}")
- continue
- else:
- try:
- wb = load_workbook(filename=file_path, read_only=True)
- sheet_names = wb.sheetnames
- wb.close()
- except Exception as e:
- messagebox.showerror("文件错误", f"无法读取 {file_path}\n错误: {str(e)}")
- continue
- # 创建文件分组框
- file_frame = tk.LabelFrame(scrollable_frame, text=os.path.basename(file_path))
- file_frame.pack(fill="x", padx=5, pady=5)
- # 创建全选变量和按钮
- select_all_var = tk.BooleanVar(master=file_frame, value=False)
-
- # 创建全选命令函数(修正全选功能)
- def create_select_all_command(f_path, var, sheet_names):
- """创建全选命令函数"""
- def _command():
- # 获取当前值并取反作为新值
- new_value = var.get()
- # 更新所有工作表的勾选状态
- norm_path = os.path.normpath(f_path).replace("\", "\\\") # 保留原始路径格式
- for sheet_name in sheet_names:
- unique_key = f"{norm_path}__SHEET__{sheet_name}"
- if unique_key in checkbox_vars:
- checkbox_vars[unique_key].set(new_value)
- return _command
- # 创建全选按钮
- select_all_checkbox = tk.Checkbutton(
- file_frame,
- text="全选",
- variable=select_all_var,
- command=create_select_all_command(file_path, select_all_var, sheet_names),
- anchor="w",
- width=5
- )
- select_all_checkbox.pack(side="left", padx=5, pady=2)
- # 添加全选变量到全局变量字典(使用文件路径作为键)
- checkbox_vars[file_path] = select_all_var
- for sheet_name in sheet_names:
- # 创建唯一标识
- norm_path = os.path.normpath(file_path).replace("\", "\\\") # 保留原始路径格式
- unique_key = f"{norm_path}__SHEET__{sheet_name}"
-
- # 创建变量和勾选框
- var = tk.BooleanVar(master=file_frame, value=False)
- checkbox_vars[unique_key] = var
-
- # 创建勾选框组件
- checkbox = tk.Checkbutton(
- file_frame,
- text=sheet_name,
- variable=var, # 确保变量直接关联
- command=create_checkbutton_command(unique_key, var), # 直接绑定命令
- anchor="w",
- padx=0, # 移除内边距
- )
- checkbox.config(width=len(sheet_name) + 2)
- checkbox.pack(side="left", padx=0, pady=1) # 只在x方向有5像素间距
- # 创建打印份数输入框
- copies_var = tk.StringVar(master=file_frame, value="1")
-
- # 创建一个子框架用于精确控制左右边距
- copies_frame = tk.Frame(file_frame)
- copies_frame.pack(side="left") # 将子框架放置到主容器中
- # 左侧占位标签,宽度为5
- left_spacer = tk.Label(copies_frame, width=1)
- left_spacer.pack(side="left")
- # 输入框放在左侧占位后
- copies_entry = tk.Entry(copies_frame, textvariable=copies_var, width=3)
- copies_entry.pack(side="left")
- # 右侧占位标签,宽度为50
- right_spacer = tk.Label(copies_frame, width=10)
- right_spacer.pack(side="left")
- # 将 copies_var 存入 checkbox_vars 中(使用 unique_key_copies 做唯一标识)
- unique_key_copies = f"{norm_path}__COPIES__{sheet_name}"
- checkbox_vars[unique_key_copies] = copies_var
- # 在全局变量字典之后添加打印函数
- def print_selected_sheets():
- """处理选中的工作表进行打印"""
- # 获取所有选中的工作表
- selected_sheets = []
- for key, var in checkbox_vars.items():
- if var.get() and '__SHEET__' in key:
- file_path, sheet_name = key.split('__SHEET__')
- unique_key_copies = f"{file_path}__COPIES__{sheet_name}"
- copies_str = checkbox_vars.get(unique_key_copies, tk.StringVar(value="1")).get()
- try:
- copies = int(copies_str)
- except ValueError:
- copies = 1
- selected_sheets.append((file_path.replace('\\\\', '\\'), sheet_name, copies))
- if not selected_sheets:
- messagebox.showinfo("提示", "未选择要打印的工作表")
- return
- # 使用Excel进行打印(需要安装Microsoft Office)
- try:
- excel = win32com.client.Dispatch("Excel.Application")
- excel.Visible = False
- for file_path, sheet_name, copies in selected_sheets:
- wb = excel.Workbooks.Open(file_path)
- ws = wb.Sheets(sheet_name)
- for _ in range(copies):
- ws.PrintOut()
- wb.Close(SaveChanges=False)
- excel.Quit()
- messagebox.showinfo("完成", "打印任务已发送")
- except Exception as e:
- messagebox.showerror("打印错误", f"打印失败: {str(e)}")
- # 打印完成后关闭窗口
- # window.destroy()
- def select_all_sheets(select_all):
- """设置所有工作表的勾选状态"""
- for key, var in checkbox_vars.items():
- if '__SHEET__' in key: # 只处理工作表勾选框
- var.set(select_all)
- def on_exit():
- window.destroy()
- sys.exit()
- # 创建按钮框架并放在底部
- button_frame = tk.Frame(window)
- button_frame.pack(side="bottom", fill="x", pady=10)
- print_button = tk.Button(button_frame, text="开始打印", command=print_selected_sheets)
- print_button.pack(side="left", padx=20)
- # 创建并放置 "全部打印" 按钮
- tk.Button(
- button_frame,
- text="全部打印",
- command=lambda: select_all_sheets(True)
- ).pack(side="left", padx=20)
- exit_button = tk.Button(button_frame, text="退出", command=on_exit)
- exit_button.pack(side="right", padx=20)
- window.protocol("WM_DELETE_WINDOW", on_exit) # 绑定关闭事件
- # 启动 GUI
- window.mainloop()
复制代码 |
|