commit 4f94f5d2b8b70920749b1fa0f0f7cab6225dbbb5 Author: taiyi Date: Sun Oct 12 10:47:45 2025 +0800 第一次提交,完成 diff --git a/README.md b/README.md new file mode 100644 index 0000000..87e3e3d --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# Excel转TXT工具 + +一个简单易用的Excel转TXT文件工具,可以将Excel表格中的数据批量导出为多个TXT文件。 + +## 功能特点 + +- 📊 支持Excel文件(.xlsx, .xls)导入 +- 🎯 可指定标题字段作为TXT文件名 +- 📝 可指定内容字段作为TXT文件内容 +- 📁 批量导出到指定文件夹 +- 🖥️ 友好的图形化界面 +- ⚡ 实时进度显示 +- 🔒 文件名安全处理 + +## 安装依赖 + +```bash +pip install -r requirements.txt +``` + +## 使用方法 + +1. 运行程序: +```bash +python excel_to_txt_converter.py +``` + +2. 选择Excel文件:点击"浏览"按钮选择要转换的Excel文件 + +3. 加载字段:点击"加载字段"按钮,程序会读取Excel文件的列名 + +4. 绑定字段: + - 选择"标题字段":作为TXT文件名的列 + - 选择"内容字段":作为TXT文件内容的列 + +5. 选择导出文件夹:点击"浏览"按钮选择TXT文件的导出路径 + +6. 开始转换:点击"开始转换"按钮,程序会批量生成TXT文件 + +## 注意事项 + +- 每行数据会生成一个独立的TXT文件 +- 如果标题字段包含非法文件名字符,会自动替换为下划线 +- 如果文件名重复,会自动添加序号避免覆盖 +- 支持实时进度显示和错误处理 + +## 技术栈 + +- Python 3.x +- pandas:Excel文件处理 +- tkinter:图形化界面 +- openpyxl:Excel文件读取 + +## 示例 + +假设Excel文件内容如下: + +| 标题 | 内容 | +|------|------| +| 文件1 | 这是第一个文件的内容 | +| 文件2 | 这是第二个文件的内容 | + +转换后会生成: +- `文件1.txt`(内容为"这是第一个文件的内容") +- `文件2.txt`(内容为"这是第二个文件的内容") + +## 错误处理 + +- 自动处理文件名中的非法字符 +- 重复文件名自动添加序号 +- 详细的错误提示和状态显示 +- 转换完成后的统计信息 + +## 许可证 + +MIT License \ No newline at end of file diff --git a/create_test_file.py b/create_test_file.py new file mode 100644 index 0000000..c1f4ef0 --- /dev/null +++ b/create_test_file.py @@ -0,0 +1,18 @@ +import pandas as pd + +# 创建测试数据 +data = { + '标题': ['第一章', '第二章', '第三章', '附录'], + '内容': [ + '这是第一章的内容,包含了详细的介绍和说明', + '这是第二章的内容,讲述了主要的故事情节', + '这是第三章的内容,总结了全文的主要内容', + '这是附录部分,包含了一些补充信息' + ], + '作者': ['张三', '李四', '王五', '赵六'] +} + +# 创建DataFrame并保存为Excel文件 +df = pd.DataFrame(data) +df.to_excel('测试数据.xlsx', index=False) +print("测试Excel文件已创建: 测试数据.xlsx") \ No newline at end of file diff --git a/excel_to_txt_converter.py b/excel_to_txt_converter.py new file mode 100644 index 0000000..fed6918 --- /dev/null +++ b/excel_to_txt_converter.py @@ -0,0 +1,197 @@ +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() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..5e9bfb7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pandas>=1.3.0 +openpyxl>=3.0.0 \ No newline at end of file