import pandas as pd import os import tkinter as tk from tkinter import ttk, filedialog, messagebox import json class ExcelToTxtConverter: def __init__(self, root): self.root = root self.root.title("Excel转TXT工具") self.root.geometry("600x500") # 变量 self.excel_path = tk.StringVar() self.export_path = tk.StringVar() self.title_field = tk.StringVar() self.content_field = tk.StringVar() self.df = None self.columns = [] self.setup_ui() def setup_ui(self): # 主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # Excel文件选择 ttk.Label(main_frame, text="Excel文件:").grid(row=0, column=0, sticky=tk.W, pady=5) ttk.Entry(main_frame, textvariable=self.excel_path, width=50).grid(row=0, column=1, padx=5) ttk.Button(main_frame, text="浏览", command=self.browse_excel).grid(row=0, column=2, padx=5) # 加载字段按钮 ttk.Button(main_frame, text="加载字段", command=self.load_fields).grid(row=1, column=1, pady=10) # 字段选择框架 fields_frame = ttk.LabelFrame(main_frame, text="字段绑定", padding="10") fields_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=10) # 标题字段选择 ttk.Label(fields_frame, text="标题字段:").grid(row=0, column=0, sticky=tk.W, pady=5) self.title_combo = ttk.Combobox(fields_frame, textvariable=self.title_field, width=30) self.title_combo.grid(row=0, column=1, padx=5) # 内容字段选择 ttk.Label(fields_frame, text="内容字段:").grid(row=1, column=0, sticky=tk.W, pady=5) self.content_combo = ttk.Combobox(fields_frame, textvariable=self.content_field, width=30) self.content_combo.grid(row=1, column=1, padx=5) # 导出路径选择 ttk.Label(main_frame, text="导出文件夹:").grid(row=3, column=0, sticky=tk.W, pady=5) ttk.Entry(main_frame, textvariable=self.export_path, width=50).grid(row=3, column=1, padx=5) ttk.Button(main_frame, text="浏览", command=self.browse_export_folder).grid(row=3, column=2, padx=5) # 转换按钮 ttk.Button(main_frame, text="开始转换", command=self.convert, style="Accent.TButton").grid(row=4, column=1, pady=20) # 状态显示 self.status_label = ttk.Label(main_frame, text="准备就绪", foreground="blue") self.status_label.grid(row=5, column=0, columnspan=3, pady=5) # 进度条 self.progress = ttk.Progressbar(main_frame, mode='determinate', length=400) self.progress.grid(row=6, column=0, columnspan=3, pady=5) # 配置网格权重 self.root.columnconfigure(0, weight=1) self.root.rowconfigure(0, weight=1) main_frame.columnconfigure(1, weight=1) def browse_excel(self): filename = filedialog.askopenfilename( title="选择Excel文件", filetypes=[("Excel文件", "*.xlsx *.xls"), ("所有文件", "*.*")] ) if filename: self.excel_path.set(filename) def browse_export_folder(self): folder = filedialog.askdirectory(title="选择导出文件夹") if folder: self.export_path.set(folder) def load_fields(self): if not self.excel_path.get(): messagebox.showwarning("警告", "请先选择Excel文件") return try: # 读取Excel文件 self.df = pd.read_excel(self.excel_path.get()) self.columns = list(self.df.columns) # 更新下拉框 self.title_combo['values'] = self.columns self.content_combo['values'] = self.columns if self.columns: self.title_combo.current(0) if len(self.columns) > 1: self.content_combo.current(1) else: self.content_combo.current(0) self.status_label.config(text=f"已加载 {len(self.df)} 行数据,{len(self.columns)} 个字段", foreground="green") except Exception as e: messagebox.showerror("错误", f"加载Excel文件失败: {str(e)}") self.status_label.config(text="加载失败", foreground="red") def sanitize_filename(self, filename): """清理文件名,移除非法字符""" invalid_chars = '<>:"/\\|?*' for char in invalid_chars: filename = filename.replace(char, '_') return filename.strip() def convert(self): if not self.excel_path.get(): messagebox.showwarning("警告", "请先选择Excel文件") return if not self.export_path.get(): messagebox.showwarning("警告", "请先选择导出文件夹") return if not self.title_field.get() or not self.content_field.get(): messagebox.showwarning("警告", "请先选择标题和内容字段") return if self.df is None: messagebox.showwarning("警告", "请先加载Excel文件") return try: # 创建导出文件夹 os.makedirs(self.export_path.get(), exist_ok=True) # 获取字段索引 title_col = self.title_field.get() content_col = self.content_field.get() # 重置进度条 self.progress['maximum'] = len(self.df) self.progress['value'] = 0 success_count = 0 error_count = 0 # 遍历每一行数据 for index, row in self.df.iterrows(): try: # 获取标题和内容 title = str(row[title_col]) if pd.notna(row[title_col]) else f"文件_{index + 1}" content = str(row[content_col]) if pd.notna(row[content_col]) else "" # 清理文件名 filename = self.sanitize_filename(title) + '.txt' filepath = os.path.join(self.export_path.get(), filename) # 如果文件已存在,添加序号 counter = 1 original_filepath = filepath while os.path.exists(filepath): name, ext = os.path.splitext(original_filepath) filepath = f"{name}_{counter}{ext}" counter += 1 # 写入文件 with open(filepath, 'w', encoding='utf-8') as f: f.write(content) success_count += 1 except Exception as e: error_count += 1 print(f"处理第 {index + 1} 行时出错: {str(e)}") # 更新进度 self.progress['value'] = index + 1 self.root.update() # 显示结果 messagebox.showinfo("完成", f"转换完成!\n成功: {success_count} 个文件\n失败: {error_count} 个文件") self.status_label.config(text=f"转换完成!成功: {success_count}, 失败: {error_count}", foreground="green") except Exception as e: messagebox.showerror("错误", f"转换过程中出错: {str(e)}") self.status_label.config(text="转换失败", foreground="red") def main(): root = tk.Tk() app = ExcelToTxtConverter(root) root.mainloop() if __name__ == "__main__": main()