目录
效果展示
xmind示例:
GUI界面:
excel结果文件:
实现步骤
1.xmindparser.xmind_to_dict读取xmind文件
2.xlwt写入表格内容保存为excel
3.ttkbootstrap编写GUI交互界面
4.pyinstaller将程序打包为可执行的exe文件(参考文章)
核心代码
XmindToExcel类,继承XlwtSetting,设置了表头和表格内容单元格样式
import datetime
import os
import traceback
import xlwt
from xmindparser import xmind_to_dict
from common.log_handle import get_log
from common.path_handle import outputs_path
log = get_log(os.path.split(__file__)[-1])
class XmindToExcel(XlwtSetting):
def __init__(self, file):
"""将xmind文件转换为excel表格"""
self.xm = xmind_to_dict(file)[0]['topic'] # 获取xmind topic
self.workbook = xlwt.Workbook(encoding='utf-8') # 创建工作簿
def save(self, name):
"""保存excel"""
self.workbook.save(name + ".xlsx")
@staticmethod
def get_num(value):
"""获取xmind标题数量"""
try:
return len(value["topics"])
except KeyError:
return 0
@staticmethod
def get_title(value):
"""获取xmind标题内容"""
return value["title"]
def write_excel(self):
"""遍历xmind内容,写入excel"""
ws = self.workbook.add_sheet(self.xm["title"], cell_overwrite_ok=True) # 创建工作表
head = ["模块", "功能点/测试点"] # 表头数据
style_head = self.style_head(ws, [12, 35]) # 表头单元格样式
for i, v in enumerate(head): # 写入表头
ws.write(0, i, v, style_head)
style_body = self.style_body() # 表格内容单元格样式
row = 1 # 表格当前行数,从第二行开始
try:
for i, v in enumerate(self.xm["topics"]): # 遍历模块
lv1_num = self.get_num(v) # 一级测试点数量
mod = self.get_title(v) # 模块名称
if lv1_num != 0:
for n, val in enumerate(v["topics"]): # 遍历一级测试点
lv2_num = self.get_num(val) # 二级测试点数量
p_lv1 = self.get_title(val) # 一级测试点名称
if lv2_num != 0:
for j, p in enumerate(val["topics"]): # 遍历二级测试点
lv3_num = self.get_num(p) # 三级测试点数量
p_lv2 = self.get_title(p) # 二级测试点名称
p_lv1 = self.get_title(val) + '--' + p_lv2 # 拼接测试点
if lv3_num != 0:
for k, value in enumerate(p["topics"]): # 遍历三级测测试点
p_lv3 = self.get_title(value) # 三级测试点名称
p_lv1 = self.get_title(val) + '--' + self.get_title(p) + '--' + p_lv3 # 拼接测试点
ws.write(row, 0, mod, style_body) # 写入模块,第一列
ws.write(row, 1, p_lv1, style_body) # 写入测试点,第二列
row += 1 # 当前行数增加1
else:
ws.write(row, 0, mod, style_body)
ws.write(row, 1, p_lv1, style_body)
row += 1
else:
ws.write(row, 0, mod, style_body)
ws.write(row, 1, p_lv1, style_body)
row += 1
else:
log.info(f"{mod}无测试点")
return
if not os.path.exists(outputs_path): # 结果输出文件夹,不存在则创建
os.makedirs(outputs_path)
sj = datetime.datetime.now().strftime("%Y-%m-%d %H%M%S") # 当前时间
file_name = outputs_path + self.xm["title"] + sj # 拼接文件名称
self.save(file_name) # 保存excel
log.info(f"excel保存成功【{file_name}】")
return file_name
except Exception as err:
info = f"出了点小问题!\n{repr(err)}\n{traceback.format_exc()}"
log.error(info)
GUI界面,点击按钮判断文件是否为xmind格式,是则调用XmindToExcel类,转换为excel
import os
import re
from tkinter.filedialog import askopenfilename
import ttkbootstrap as ttk
from ttkbootstrap.dialogs import Messagebox
from common.path_handle import icon_path
from xmind_to_excel import XmindToExcel
class GUI:
def __init__(self, master):
"""xmind转换为excel的GUI"""
self.root = master
self.create_page() # 调用创建页面元素方法
def create_page(self):
# xmind路径标签控件
lf = ttk.Labelframe(self.root, text="xmind转换为excel", bootstyle='primary')
lf.pack(padx=20, pady=30) # 使用pack布局
# xmind文件选择按钮
ttk.Button(lf, text="选择文件开始转换", bootstyle='outline', command=self.select_file).pack(padx=2, pady=5)
def select_file(self):
"""选择xmind文件开始转换"""
path_file = askopenfilename()
if path_file: # 若选择了文件
if not self.is_xmind(path_file): # 若文件不是xmind则提示
Messagebox.show_error(title="哦豁,出错了!", message=f"请选择xmind文件!")
else: # 若文件是xmind则转换为excel
file_name = XmindToExcel(path_file).write_excel()
Messagebox.show_info(title="恭喜发财!", message=f"excel保存路径:{file_name}")
else: # 若关闭对话框未选择文件并且文件不是xmind则提示
if not self.is_xmind(path_file):
Messagebox.show_error(title="哦豁,出错了!", message=f"请选择xmind文件!")
@staticmethod
def is_xmind(path):
"""判断文件名称是否以xmind结尾"""
reg_value = '.*\.xmind$'
xmind_reg = re.match(reg_value, path)
return xmind_reg
if __name__ == "__main__":
root = ttk.Window(
title="XTE", # 窗口标题
themename="cyborg", # 主题
minsize=(0, 0), # 窗口最小宽高
maxsize=(1920, 1080), # 窗口最大宽高
alpha=1.0 # 窗口的透明度(0.0--完全透明)
)
root.place_window_center() # 设置窗口居中
root.resizable(width=False, height=False) # 将窗口大小设置为不可变
root.iconbitmap(icon_path) # 更改GUI的图标
GUI(root)
root.mainloop()