Python_API_os.path_walk_待填充

本文详细介绍了Python标准库os模块中的文件遍历函数os.walk的使用方法、工作原理以及实际应用场景,包括参数解释、注意事项和案例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

os.path.walk(path, visit, arg)

Calls the function visit with arguments (arg, dirname, names) for each directory in the directory tree rooted at path (including path itself, if it is a directory). The argument dirname specifies the visited directory, the argument names lists the files in the directory (gotten from os.listdir(dirname)). The visit function may modify names to influence the set of directories visited below dirname, e.g. to avoid visiting certain parts of the tree. (The object referred to by names must be modified in place, using del or slice assignment.)

Note

Symbolic links to directories are not treated as subdirectories, and that walk() therefore will not visit them. To visit linked directories you must identify them with os.path.islink(file) and os.path.isdir(file), and invoke walk() as necessary.

Note

This function is deprecated and has been removed in 3.0 in favor of os.walk().


#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 模块提供图片加密解密服务 """ import os import cv2 import numpy as np from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding import hashlib class ImageEncryptor: def __init__(self, key): """ 初始化加密器 :param key: 加密密钥(字符串或字节) """ if isinstance(key, str): key = key.encode('utf-8') self.key = hashlib.sha256(key).digest() # 生成256位AES密钥 def encrypt_image(self, img_path, output_path=None): """ 加密单个图像文件 :param img_path: 输入图像路径 :param output_path: 加密后输出路径(默认添加.enc后缀) :return: 加密后文件路径 """ # 读取二进制图片 # img_bytes = np.frombuffer(img_path, dtype=np.uint8).tobytes() # 读取图像并转换为OpenCV格式 img = cv2.imdecode(np.frombuffer(img_path, dtype=np.uint8), cv2.IMREAD_COLOR) if img is None: raise ValueError(f"无法读取图像: {img_path}") # 将图像转换为字节流 _, buffer = cv2.imencode('.png', img) img_bytes = buffer.tobytes() # 生成随机初始化向量 iv = os.urandom(16) # 创建加密器 cipher = Cipher( algorithms.AES(self.key), modes.CBC(iv), backend=default_backend() ) encryptor = cipher.encryptor() # 填充数据 padder = padding.PKCS7(128).padder() padded_data = padder.update(img_bytes) + padder.finalize() # 加密数据 encrypted = encryptor.update(padded_data) + encryptor.finalize() # 确定输出路径 if output_path is None: output_path = img_path + '.enc' # 写入加密文件(包含自定义文件头和IV) with open(output_path, 'wb') as f: f.write(b'ENCIMG1.0') # 自定义文件头标识 f.write(iv) f.write(encrypted) return output_path def decrypt_to_opencv(self, encrypted_path): """ 解密加密图像并返回OpenCV图像对象 :param encrypted_path: 加密图像路径 :return: OpenCV图像对象 (numpy数组) """ with open(encrypted_path, 'rb') as f: header = f.read(8) # 读取文件头 if header != b'ENCIMG1.0': raise ValueError("无效的加密文件格式") iv = f.read(16) encrypted = f.read() # 创建解密器 cipher = Cipher( algorithms.AES(self.key), modes.CBC(iv), backend=default_backend() ) decryptor = cipher.decryptor() # 解密数据 decrypted = decryptor.update(encrypted) + decryptor.finalize() # 移除填充 unpadder = padding.PKCS7(128).unpadder() img_bytes = unpadder.update(decrypted) + unpadder.finalize() # 将字节数据转换为OpenCV图像 nparr = np.frombuffer(img_bytes, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) if img is None: raise ValueError("解密后图像解码失败") return img def encrypt_directory(self, src_dir, dst_dir): """ 递归加密整个目录结构 :param src_dir: 源目录路径 :param dst_dir: 目标目录路径 """ for root, dirs, files in os.walk(src_dir): # 创建对应的输出目录结构 rel_path = os.path.relpath(root, src_dir) output_dir = os.path.join(dst_dir, rel_path) os.makedirs(output_dir, exist_ok=True) for file in files: if file.lower().endswith('.png'): src_path = os.path.join(root, file) dst_path = os.path.join(output_dir, file + '.enc') self.encrypt_image(src_path, dst_path) print(f"加密完成: {src_path} -> {dst_path}") # 使用示例 if __name__ == "__main__": # 初始化加密器(实际应用中应从安全位置获取密钥) SECRET_KEY = "大话西游2经典版" # 建议使用环境变量或密钥管理系统 encryptor = ImageEncryptor(SECRET_KEY) input_path = 'E:\\DHP\\server_socket\\server_resources\\image\\界面\\莲叶载书栏.png' # 加密单个图像示例 encrypted_file = encryptor.encrypt_image(input_path) # 解密单个文件 disen_file = encryptor.decrypt_to_opencv(encrypted_file) # 使用OpenCV显示解密后的图像 cv2.imshow('Decrypted Image', disen_file) cv2.waitKey(0) img = cv2.imdecode(np.frombuffer(img_path, dtype=np.uint8), cv2.IMREAD_COLOR)格式不对
07-23
# PYTHON script import os import pandas as pd # def get_filenames_without_extension(directory): # """获取文件夹中所有文件的纯文件名(不含路径和后缀)""" # filenames = [] # for root, dirs, files in os.walk(directory): # for file in files: # # 分割文件名和后缀 # base_name, extension = os.path.splitext(file) # pure_filename = os.path.basename(base_name) # lowercase_name = pure_filename.lower() # filenames.append(lowercase_name) # return filenames def get_execl_data(): df = pd.read_excel("D:\ll\引望MDS清单.xlsx", sheet_name="Sheet1", usecols="B", skiprows=1, header=None) all_datas = [] # 获取数据列表 a_column_data = df.iloc[:, 0].tolist() # 获取第1列所有行 for data in a_column_data: base_name, extension = os.path.splitext(data) pure_filename = os.path.basename(base_name) lowercase_name = pure_filename.lower() all_datas.append(lowercase_name) return all_datas def find_difference(list1, list2): """返回在list1中存在但在list2中不存在的元素""" return [item for item in list1 if item not in list2] def main(): # Need some documentation? Run this with F5 # all_files = get_filenames_without_extension( # "D:\HwHdpMdaPlugin\hwsdwks\plmfoundation_rnd_huawei_com\pdm\l30077439\workspace\workspace") all_files = pd.read_excel("D:\ll\引望MDS清单.xlsx", sheet_name="中望mds包装设计基础模型列表", usecols="A", skiprows=1, header=None) excel_datas = get_execl_data() result = find_difference(excel_datas, all_files) print(result) if __name__ == '__main__': main() 修改该代码
最新发布
08-05
我想要实现的功能是: 1、用WinMerge生成文件夹比较报告及文件比较报告 2、将生成的报告与目标Excel文件放在同一目录下 3、点击目标Excel文件“一覧”工作表上的“作成”按钮 4、等待处理完成 我的代码是import os import subprocess import shutil import time import tkinter as tk from tkinter import filedialog, ttk, scrolledtext, messagebox, PhotoImage import win32com.client as win32 import threading import tempfile import queue import traceback import webbrowser class DiffProcessorApp: def __init__(self, root): self.root = root root.title("高级文件夹比较工具") root.geometry("1000x700") root.configure(bg="#f5f5f5") # 创建现代风格主题 self.style = ttk.Style() self.style.theme_use('clam') # 自定义主题颜色 self.style.configure('TButton', font=('Segoe UI', 10, 'bold'), borderwidth=1, foreground="#333", background="#4CAF50", bordercolor="#388E3C", relief="flat", padding=8, anchor="center") self.style.map('TButton', background=[('active', '#388E3C'), ('disabled', '#BDBDBD')], foreground=[('disabled', '#9E9E9E')]) self.style.configure('TLabel', font=('Segoe UI', 9), background="#f5f5f5") self.style.configure('TLabelframe', font=('Segoe UI', 10, 'bold'), background="#f5f5f5", relief="flat", borderwidth=2) self.style.configure('TLabelframe.Label', font=('Segoe UI', 10, 'bold'), background="#f5f5f5", foreground="#2E7D32") self.style.configure('Treeview', font=('Segoe UI', 9), rowheight=25) self.style.configure('Treeview.Heading', font=('Segoe UI', 9, 'bold')) # 创建主框架 main_frame = ttk.Frame(root, padding="15") main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) # 标题区域 header_frame = ttk.Frame(main_frame) header_frame.pack(fill=tk.X, pady=(0, 15)) # 添加标题图标 try: icon = PhotoImage(file="folder_icon.png") self.icon_label = ttk.Label(header_frame, image=icon) self.icon_label.image = icon self.icon_label.pack(side=tk.LEFT, padx=(0, 10)) except: self.icon_label = ttk.Label(header_frame, text="📁", font=("Arial", 24)) self.icon_label.pack(side=tk.LEFT, padx=(0, 10)) title_label = ttk.Label(header_frame, text="高级文件夹比较工具", font=("Segoe UI", 18, "bold"), foreground="#2E7D32") title_label.pack(side=tk.LEFT) # 文件选择区域 file_frame = ttk.LabelFrame(main_frame, text="文件夹选择", padding="12") file_frame.pack(fill=tk.X, pady=5) # 文件夹选择 self.old_folder_entry, _ = self.create_folder_selector(file_frame, "原始文件夹:") self.new_folder_entry, _ = self.create_folder_selector(file_frame, "修改后文件夹:") # 比较选项区域 options_frame = ttk.LabelFrame(main_frame, text="比较选项", padding="12") options_frame.pack(fill=tk.X, pady=5) # 递归比较选项 self.recursive_var = tk.BooleanVar(value=True) recursive_check = ttk.Checkbutton(options_frame, text="递归比较子文件夹", variable=self.recursive_var) recursive_check.grid(row=0, column=0, padx=10, pady=5, sticky=tk.W) # 文件过滤 filter_frame = ttk.Frame(options_frame) filter_frame.grid(row=0, column=1, padx=10, pady=5, sticky=tk.W) ttk.Label(filter_frame, text="文件过滤:").pack(side=tk.LEFT, padx=(0, 5)) self.filter_var = tk.StringVar(value="*.*") filter_entry = ttk.Entry(filter_frame, textvariable=self.filter_var, width=15) filter_entry.pack(side=tk.LEFT) # 文件报告选项 self.file_report_var = tk.BooleanVar(value=True) file_report_check = ttk.Checkbutton(options_frame, text="生成文件比较报告", variable=self.file_report_var) file_report_check.grid(row=0, column=2, padx=10, pady=5, sticky=tk.W) # 添加报告格式选择 report_frame = ttk.Frame(options_frame) report_frame.grid(row=1, column=0, columnspan=3, padx=10, pady=5, sticky=tk.W) ttk.Label(report_frame, text="报告格式:").pack(side=tk.LEFT, padx=(0, 5)) self.report_format_var = tk.StringVar(value="html") ttk.Radiobutton(report_frame, text="HTML", variable=self.report_format_var, value="html").pack(side=tk.LEFT, padx=5) ttk.Radiobutton(report_frame, text="XML", variable=self.report_format_var, value="xml").pack(side=tk.LEFT, padx=5) # 输出设置区域 self.excel_frame = ttk.LabelFrame(main_frame, text="输出设置", padding="12") self.excel_frame.pack(fill=tk.X, pady=5) # 目标Excel选择 ttk.Label(self.excel_frame, text="目标Excel文件:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5) self.excel_file_entry = ttk.Entry(self.excel_frame, width=60) self.excel_file_entry.grid(row=0, column=1, padx=5, pady=5) ttk.Button(self.excel_frame, text="浏览...", command=lambda: self.select_file(self.excel_file_entry, [("Excel文件", "*.xlsx *.xlsm")])).grid(row=0, column=2, padx=5, pady=5) # 添加报告目录选择 report_dir_frame = ttk.Frame(self.excel_frame) report_dir_frame.grid(row=1, column=0, columnspan=3, sticky=tk.W, padx=5, pady=5) ttk.Label(report_dir_frame, text="报告存储目录:").grid(row=0, column=0, sticky=tk.W) self.report_dir_entry = ttk.Entry(report_dir_frame, width=60) self.report_dir_entry.grid(row=0, column=1, padx=5) ttk.Button(report_dir_frame, text="浏览...", command=lambda: self.select_folder(self.report_dir_entry)).grid(row=0, column=2) # WinMerge路径设置 winmerge_frame = ttk.Frame(self.excel_frame) winmerge_frame.grid(row=2, column=0, columnspan=3, sticky=tk.W, padx=5, pady=5) ttk.Label(winmerge_frame, text="WinMerge路径:").grid(row=0, column=0, sticky=tk.W) self.winmerge_entry = ttk.Entry(winmerge_frame, width=60) self.winmerge_entry.grid(row=0, column=1, padx=5) self.winmerge_entry.insert(0, r"C:\Program Files\WinMerge\WinMergeU.exe") # 默认路径 ttk.Button(winmerge_frame, text="浏览...", command=lambda: self.select_file(self.winmerge_entry, [("WinMerge 可执行文件", "*.exe")])).grid(row=0, column=2) # 执行按钮区域 button_frame = ttk.Frame(main_frame) button_frame.pack(fill=tk.X, pady=10) self.run_button = ttk.Button(button_frame, text="执行比较", command=self.start_processing, width=20, style='TButton') self.run_button.pack(side=tk.LEFT) # 停止按钮 self.stop_button = ttk.Button(button_frame, text="停止", command=self.stop_processing, width=10, state=tk.DISABLED) self.stop_button.pack(side=tk.LEFT, padx=10) # 查看报告按钮 self.view_report_button = ttk.Button(button_frame, text="查看报告", command=self.view_report, width=10, state=tk.DISABLED) self.view_report_button.pack(side=tk.LEFT, padx=10) # 进度条 self.progress = ttk.Progressbar(main_frame, orient=tk.HORIZONTAL, length=700, mode='determinate') self.progress.pack(fill=tk.X, pady=5) # 状态信息 status_frame = ttk.Frame(main_frame) status_frame.pack(fill=tk.X, pady=5) self.status_var = tk.StringVar(value="准备就绪") status_label = ttk.Label(status_frame, textvariable=self.status_var, font=("Segoe UI", 9), foreground="#2E7D32") status_label.pack(side=tk.LEFT) # 日志和预览区域 notebook = ttk.Notebook(main_frame) notebook.pack(fill=tk.BOTH, expand=True, pady=5) # 文件夹结构标签 tree_frame = ttk.Frame(notebook, padding="5") notebook.add(tree_frame, text="文件夹结构") # 创建树形视图 self.tree = ttk.Treeview(tree_frame, columns=("Status"), show="tree") self.tree.heading("#0", text="文件夹结构", anchor=tk.W) self.tree.heading("Status", text="状态", anchor=tk.W) self.tree.column("#0", width=400) self.tree.column("Status", width=100) vsb = ttk.Scrollbar(tree_frame, orient="vertical", command=self.tree.yview) hsb = ttk.Scrollbar(tree_frame, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) self.tree.grid(row=0, column=0, sticky="nsew") vsb.grid(row=0, column=1, sticky="ns") hsb.grid(row=1, column=0, sticky="ew") # 日志标签 log_frame = ttk.Frame(notebook, padding="5") notebook.add(log_frame, text="执行日志") self.log_text = scrolledtext.ScrolledText(log_frame, height=10, wrap=tk.WORD, font=("Consolas", 9)) self.log_text.pack(fill=tk.BOTH, expand=True) self.log_text.config(state=tk.DISABLED) # 设置网格权重 tree_frame.grid_rowconfigure(0, weight=1) tree_frame.grid_columnconfigure(0, weight=1) # 线程控制 self.processing = False self.queue = queue.Queue() self.last_report_path = None # 启动队列处理 self.root.after(100, self.process_queue) def create_folder_selector(self, parent, label_text): """创建文件夹选择器组件""" frame = ttk.Frame(parent) frame.pack(fill=tk.X, pady=5) ttk.Label(frame, text=label_text).grid(row=0, column=0, sticky=tk.W, padx=5, pady=5) entry = ttk.Entry(frame, width=70) entry.grid(row=0, column=1, padx=5, pady=5) button = ttk.Button(frame, text="浏览文件夹...", command=lambda: self.select_folder(entry)) button.grid(row=0, column=2, padx=5, pady=5) return entry, button def select_folder(self, entry): """选择文件夹""" foldername = filedialog.askdirectory() if foldername: entry.delete(0, tk.END) entry.insert(0, foldername) # 自动填充文件夹结构 self.populate_folder_tree(foldername) def select_file(self, entry, filetypes=None): """选择文件""" if filetypes is None: filetypes = [("所有文件", "*.*")] filename = filedialog.askopenfilename(filetypes=filetypes) if filename: entry.delete(0, tk.END) entry.insert(0, filename) def populate_folder_tree(self, path): """填充文件夹结构树""" self.tree.delete(*self.tree.get_children()) if not os.path.isdir(path): return # 添加根节点 root_node = self.tree.insert("", "end", text=os.path.basename(path), values=("文件夹",), open=True) self.add_tree_nodes(root_node, path) def add_tree_nodes(self, parent, path): """递归添加树节点""" try: for item in os.listdir(path): item_path = os.path.join(path, item) if os.path.isdir(item_path): node = self.tree.insert(parent, "end", text=item, values=("文件夹",)) self.add_tree_nodes(node, item_path) else: self.tree.insert(parent, "end", text=item, values=("文件",)) except PermissionError: self.log_message(f"权限错误: 无法访问 {path}") def log_message(self, message): """记录日志消息""" self.queue.put(("log", message)) def update_progress(self, value): """更新进度条""" self.queue.put(("progress", value)) def update_status(self, message): """更新状态信息""" self.queue.put(("status", message)) def process_queue(self): """处理线程队列中的消息""" try: while not self.queue.empty(): msg_type, data = self.queue.get_nowait() if msg极 == "log": self.log_text.config(state=tk.NORMAL) self.log_text.insert(tk.END, data + "\n") self.log_text.see(tk.END) self.log_text.config(state=tk.DISABLED) elif msg_type == "progress": self.progress['value'] = data elif msg_type == "status": self.status_var.set(data) except queue.Empty: pass self.root.after(100, self.process_queue) def process_report_files(self, report_dir): """处理生成的报告文件""" try: # 收集报告文件 report_files = [] for root, _, files in os.walk(report_dir): for file in files: if file.endswith(('.html', '.xml')): full_path = os.path.join(root, file) report_files.append(full_path) # 更新日志 self.log_message(f"生成 {len(report_files)} 个文件比较报告") self.log_message(f"报告目录: {report_dir}") # 保存最后一个报告路径用于查看 if report_files: self.last_report_path = report_files[0] self.view_report_button.config(state=tk.NORMAL) # 显示第一个报告内容预览 try: with open(report_files[0], 'r', encoding='utf-8') as f: preview = f.read(500) + "..." if len(f.read()) > 500 else f.read() self.log_message(f"示例报告内容:\n{preview}") except Exception as e: self.log_message(f"报告预览错误: {str(e)}") except Exception as e: self.log_message(f"报告处理错误: {str(e)}") def view_report(self): """查看生成的报告""" if self.last_report_path and os.path.exists(self.last_report_path): try: webbrowser.open(self.last_report_path) except Exception as e: messagebox.showerror("错误", f"无法打开报告: {str(e)}") else: messagebox.showwarning("警告", "没有可用的报告文件") def process_folders(self, old_path, new_path, excel_file): """处理文件夹比较的线程函数""" output_html = None try: # 步骤1: 生成HTML差异文件 self.update_status("生成HTML差异文件...") self.update_progress(30) # 使用临时文件存储HTML报告 with tempfile.NamedTemporaryFile(suffix=".html", delete=False) as temp_file: output_html = temp_file.name winmerge_path = self.winmerge_entry.get() if not self.run_winmerge(winmerge_path, old_path, new_path, output_html): self.update_status("WinMerge执行失败") return # 步骤2: 将HTML文件与Excel放在同一目录 self.update_status("复制HTML报告到目标目录...") self.update_progress(60) excel_dir = os.path.dirname(excel_file) if excel_dir: target_html = os.path.join(excel_dir, "diff_report.html") try: shutil.copy(output_html, target_html) self.log_message(f"已将HTML文件复制到: {target_html}") self.last_report_path = target_html self.view_report_button.config(state=tk.NORMAL) except Exception as e: self.log_message(f"文件复制失败: {str(e)}") self.last_report_path = output_html # 步骤2.5: 处理文件级报告 if self.file_report_var.get(): report_dir = self.report_dir_entry.get() or os.path.dirname(excel_file) self.update_status("生成文件级比较报告...") self.update_progress(70) # 确保报告目录存在 os.makedirs(report_dir, exist_ok=True) # 处理报告文件 self.process_report_files(report_dir) # 步骤3: 直接触发目标Excel中的"作成"按钮 self.update_status("触发Excel按钮...") self.update_progress(80) if not self.trigger_excel_button(excel_file): self.update_status("触发按钮失败") return # 完成 self.update_progress(100) self.update_status("处理完成!") self.log_message("文件夹比较流程执行完毕") messagebox.showinfo("完成", "已生成HTML报告并触发Excel处理") except Exception as e: error_msg = f"执行过程中发生错误: {str(e)}\n{traceback.format_exc()}" self.log_message(error_msg) self.update_status("执行失败") messagebox.showerror("错误", f"处理失败: {str(e)}") finally: # 重新启用执行按钮 if self.processing: self.stop_processing() # 清理临时文件 if output_html and os.path.exists(output_html): try: os.remove(output_html) except: pass def start_processing(self): """启动处理线程""" if self.processing: self.log_message("警告: 处理正在进行中") return # 获取路径 old_path = self.old_folder_entry.get() new_path = self.new_folder_entry.get() excel_file = self.excel_file_entry.get() # 详细路径验证 validation_errors = [] if not old_path: validation_errors.append("原始文件夹路径为空") elif not os.path.isdir(old_path): validation_errors.append(f"原始文件夹路径无效: {old_path}") if not new_path: validation_errors.append("新文件夹路径为空") elif not os.path.isdir(new_path): validation_errors.append(f"新文件夹路径无效: {new_path}") if not excel_file: validation_errors.append("Excel文件路径为空") elif not excel_file.lower().endswith(('.xlsx', '.xlsm')): validation_errors.append("Excel文件必须是.xlsx或.xlsm格式") winmerge_path = self.winmerge_entry.get() if not winmerge_path or not os.path.exists(winmerge_path): validation_errors.append("WinMerge路径无效或未设置") if validation_errors: self.log_message("错误: " + "; ".join(validation_errors)) messagebox.showerror("输入错误", "\n".join(validation_errors)) return # 禁用执行按钮,启用停止按钮 self.run_button.config(state=tk.DISABLED) self.stop_button.config(state=tk.NORMAL) self.view_report_button.config(state=tk.DISABLED) self.processing = True # 启动处理线程 thread = threading.Thread(target=self.process_folders, args=(old_path, new_path, excel_file)) thread.daemon = True thread.start() self.log_message("处理线程已启动") def run_winmerge(self, winmerge_path, path1, path2, output_html): """调用WinMerge生成HTML差异文件""" # 验证WinMerge可执行文件 if not os.path.exists(winmerge_path): self.log_message(f"错误: WinMerge路径不存在 {winmerge_path}") return False winmerge_cmd = [ winmerge_path, '/u', '/dl', 'Base', '/dr', 'Modified', '/or', output_html, path1, path2 ] # 添加递归选项 if self.recursive_var.get(): winmerge_cmd.insert(1, '/r') # 添加文件报告参数 if self.file_report_var.get(): # 创建报告目录 report_dir = self.report_dir_entry.get() or os.path.dirname(output_html) os.makedirs(report_dir, exist_ok=True) # 添加文件报告参数 winmerge_cmd.extend([ '/reporttype', self.report_format_var.get(), '/reportoutput', f'"{report_dir}"' ]) # 添加文件过滤 file_filter = self.filter_var.get() if file_filter and file_filter != "*.*": winmerge_cmd.extend(['-f', file_filter]) self.log_message(f"执行WinMerge命令: {' '.join(winmerge_cmd)}") try: result = subprocess.run( winmerge_cmd, capture_output=True, text=True, timeout=120, creationflags=subprocess.CREATE_NO_WINDOW ) if result.returncode == 0: self.log_message(f"HTML差异报告生成完成: {output_html}") return True else: error_msg = f"WinMerge执行失败(退出码{result.returncode}): {result.stderr}" self.log_message(error_msg) return False except subprocess.TimeoutExpired: self.log_message("WinMerge执行超时(120秒),请检查输入文件大小") return False except Exception as e: self.log_message(f"WinMerge执行错误: {str(e)}") return False def trigger_excel_button(self, excel_path): """触发目标Excel文件中的按钮""" self.log_message("正在打开Excel并触发按钮...") excel = None workbook = None try: # 验证Excel文件存在 if not os.path.exists(excel_path): self.log_message(f"错误: Excel文件不存在 {excel_path}") return False # 使用win32com打开Excel excel = win32.gencache.EnsureDispatch('Excel.Application') excel.Visible = True excel.DisplayAlerts = False # 打开工作簿 try: workbook = excel.Workbooks.Open(os.path.abspath(excel_path)) except Exception as e: self.log_message(f"打开Excel文件失败: {str(e)}") return False # 检查工作表是否存在 sheet_names = [sheet.Name for sheet in workbook.Sheets] if "一覧" not in sheet_names: self.log_message("错误: Excel文件中缺少'一覧'工作表") return False sheet = workbook.Sheets("一覧") # 触发"作成"按钮 self.log_message("正在触发'作成'按钮...") try: # 尝试查找按钮 for shape in sheet.Shapes: if shape.Name == "作成": shape.Select() shape.OLEFormat.Object.Activate() self.log_message("已触发'作成'按钮") break else: self.log_message("警告: 未找到名为'作成'的按钮") return False # 等待处理完成 self.update_status("处理中...请等待") wait_time = 0 max_wait = 60 # 最大等待60秒 while self.processing and wait_time < max_wait: if excel.CalculationState == 0: # 0 = xlDone break time.sleep(1) wait_time += 1 self.log_message(f"处理中...({wait_time}秒)") if wait_time >= max_wait: self.log_message("警告: 处理超时") else: self.log_message("处理完成") return True except Exception as e: self.log_message(f"按钮操作失败: {str(e)}. 请手动点击'作成'按钮") return False except Exception as e: self.log_message(f"Excel操作失败: {str(e)}\n{traceback.format_exc()}") return False finally: # 确保正确关闭Excel try: if workbook: workbook.Close(SaveChanges=True) # 保存更改 if excel: excel.Quit() except Exception as e: self.log_message(f"关闭Excel时出错: {str(e)}") def stop_processing(self): """停止处理""" self.processing = False self.stop_button.config(state=tk.DISABLED) self.run_button.config(state=tk.NORMAL) self.update_status("操作已停止") if __name__ == "__main__": root = tk.Tk() app = DiffProcessorApp(root) root.mainloop() 请修改代码,完成我的一键操作
07-11
生成一个python脚本,要求实现以下功能: 1.利用Python PIL 库实现对特定文件夹内图片文件图片格式进行转换并批量重命名, 重命名的名称要求用户输入.脚本参考如下:import os import PIL import fnmatch from PIL import Image # 源目录 source_dir = 'E:\Stu_2025_01\视觉设计制作-张诗军\C4D课件图\LogoPictures' # 目标目录 target_dir = 'E:\Stu_2025_01\视觉设计制作-张诗军\C4D课件图\P_lp' # 遍历源目录中的所有DDS\png\jpg文件 for filename in os.listdir(source_dir): if filename.endswith(('.DDS','.PNG', '.jpg', '.JPG', '.png', '.dds','.webp')): # 检查是否为需要更改文件格式 original_path = os.path.join(source_dir, filename) new_filename = filename[:-4] + '.jpg' # or filename[:-4] + '.png' # 新文件名,转换成.jpg或.png try: with Image.open(original_path) as img: # 转换为JPEG # 颜色模式转换RGB/CMYK img_jpeg = img.convert('RGB') # img_jpeg = img.convert('CMYK') target_path = os.path.join(target_dir, new_filename) img_jpeg.save(target_path) print(f"Converted {original_path} to {target_path}") # IO处理 except IOError: print(f"Error converting {original_path}") # 统计同类型文件数目 def count_files_by_type(directory, file_type): count = 0 for root, dirs, files in os.walk(directory): for name in files: if fnmatch.fnmatch(name, file_type): count += 1 return count # 使用函数,统计当前目录下的所有想要统计的文件 file_count = count_files_by_type('E:\Stu_2025_01\视觉设计制作-张诗军\C4D课件图\P_lp', '*.jpg') print(f'There are {file_count} .jpg files.')
03-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值