第一次提交,完成
This commit is contained in:
commit
4f94f5d2b8
76
README.md
Normal file
76
README.md
Normal file
@ -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
|
||||
18
create_test_file.py
Normal file
18
create_test_file.py
Normal file
@ -0,0 +1,18 @@
|
||||
import pandas as pd
|
||||
|
||||
# 创建测试数据
|
||||
data = {
|
||||
'标题': ['第一章', '第二章', '第三章', '附录'],
|
||||
'内容': [
|
||||
'这是第一章的内容,包含了详细的介绍和说明',
|
||||
'这是第二章的内容,讲述了主要的故事情节',
|
||||
'这是第三章的内容,总结了全文的主要内容',
|
||||
'这是附录部分,包含了一些补充信息'
|
||||
],
|
||||
'作者': ['张三', '李四', '王五', '赵六']
|
||||
}
|
||||
|
||||
# 创建DataFrame并保存为Excel文件
|
||||
df = pd.DataFrame(data)
|
||||
df.to_excel('测试数据.xlsx', index=False)
|
||||
print("测试Excel文件已创建: 测试数据.xlsx")
|
||||
197
excel_to_txt_converter.py
Normal file
197
excel_to_txt_converter.py
Normal file
@ -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()
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
pandas>=1.3.0
|
||||
openpyxl>=3.0.0
|
||||
Loading…
Reference in New Issue
Block a user