from pathlib import Path
import re
from docxtpl import DocxTemplate
from docx import Document
from docx.table import Table
from docx.text.paragraph import Paragraph
from nicegui import ui, app
# 定义全局变量
input_document_path = ''
# 匹配测试方法里面的标题
re_title = re.compile(r'(\w{2}_\w+_[a-zA-Z0-9]+_\w+\d+)')
ui.html("
测试大纲生成测试说明demo
")
# 进度全变量
class DataModel:
content = 0.0
db = DataModel()
def generat_document():
global input_document_path
global db
# 定义当前四级标题的编号和名称
current_level4_title = ''
# 定义储存标题的东西
level1_title = []
level2_title = []
level3_title = []
level4_title = []
level5_title = []
level6_title = []
level7_title = []
if input_document_path:
tpl_path = Path.cwd() / 'document_template' / '测试大纲生成测试说明模版.docx'
tpl = DocxTemplate(tpl_path) # 模板导入成功
ui.notify('导入模版成功...')
try:
doc = Document(input_document_path)
except:
ui.notify('选择的文件格式不正确!!,请重新选择')
return
shuoming_path_tmp = Path.cwd() / 'generate_document' / '生成的测试说明.docx'
# 获取表格数量
tables = doc.tables
# 创建一个字典来储存单个用例
data_list = []
# 定义开关-当识别到测试定义的标题时候
open_title = False
ui.notify('开始生成测试说明...')
for ele in doc._element.body.iter():
if ele.tag.endswith('}p'):
elePstyle = ele.findall('.//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}pStyle')
if len(elePstyle) >= 1:
parag = Paragraph(ele, doc)
if parag.style.name.startswith("Heading") or parag.style.name.startswith("标题"):
data = {}
rank = parag.style.name.split(" ")[-1] # 标题等级str类型
text = parag.text # 标题文字
# 先将标题储存在一个地方
if rank == '1' or rank == '10':
level1_title.append(1)
level2_title.clear()
level3_title.clear()
level4_title.clear()
level5_title.clear()
level6_title.clear()
level7_title.clear()
elif rank == '2' or rank == '20':
level2_title.append(1)
level3_title.clear()
level4_title.clear()
level5_title.clear()
level6_title.clear()
level7_title.clear()
elif rank == '3' or rank == '30':
level3_title.append(1)
level4_title.clear()
level5_title.clear()
level6_title.clear()
level7_title.clear()
elif rank == '4' or rank == '40':
level4_title.append(1)
level5_title.clear()
level6_title.clear()
level7_title.clear()
current_level4_title = f"({len(level1_title)}.{len(level2_title)}.{len(level3_title)}.{len(level4_title)}){text}"
elif rank == '5' or rank == '50':
level5_title.append(1)
level6_title.clear()
level7_title.clear()
elif rank == '6' or rank == '60':
level6_title.append(1)
level7_title.clear()
elif rank == '7' or rank == '70':
level7_title.append(1)
# 如果识别到标题为"测试定义"则打开获取标题开关
if text == '功能测试':
open_title = True
if text == '测试进度':
open_title = False
if open_title:
data['type'] = rank
data['text'] = text
data_list.append(data)
elif ele.tag.endswith('}tbl'):
table = Table(ele, doc)
# 1识别到大纲的一个表格
temp = table.cell(0, 0).text
if temp == '测试项名称' and table.cell(0, 1).text != '文档审查' \
and table.cell(0, 1).text != '静态分析' and \
table.cell(0, 1).text != '代码审查':
# 先提取表格其他信息
csx_name = table.cell(0, 1).text
csx_ident = table.cell(0, 3).text
res_text = ''
prefix = ''
count = 1
for para in table.cell(4, 2).paragraphs:
# 2.1 识别到测试方法的标题
re_res = re_title.findall(para.text)
if re_res:
data = {}
count = 1
data['type'] = '5'
data['text'] = re.sub(r'\d{1,2}[.]', '', para.text).strip()
prefix = re_res[0].replace('(', '').replace(")", "")
res_text = data['text'].split('(')[0]
data_list.append(data)
# print('生成五级标题为:', data['text'])
# 2.2 如果不是标题则需要生成表格了
else:
tb_data = {'type': 'table'}
tb_data['name'] = f"{res_text}_{count}"
tb_data['ident'] = f"{prefix}_{count}"
tb_data['destination'] = f"验证{csx_name.replace('测试','')}是否正确"
tb_data['xqfx'] = current_level4_title
tb_data['xqident'] = prefix
tb_data['step'] = []
# 步骤处理共4个字段
# 要求每句话必须有;中文分号
split_temp = para.text.split(';')
if len(split_temp) == 1:
split_temp.append("")
index = 1
for sss in split_temp:
if sss:
# 根据“查看分割”
ck_split = sss.split('查看')
if len(ck_split) == 1:
ck_split.insert(0, "")
step = {}
step['index'] = index
step['shuru'] = '巡天主控软件'
step['guocheng'] = ck_split[0]
# 去掉guocheng里面逗号
if step['guocheng']:
if step['guocheng'][-1] == ',':
step['guocheng'] = step['guocheng'][:-1]
else:
ui.notify('请检查,未有查看字样...', type = 'negative')
step['yuqi'] = ck_split[1]
tb_data['step'].append(step)
index += 1
count += 1
data_list.append(tb_data)
db.content = 1
try:
context = {
"tables": data_list,
}
tpl.render(context)
tpl.save(shuoming_path_tmp)
except:
ui.notify('在生成文档时报错', type = 'warning')
else:
ui.notify('请先选择需要转换的文件!')
ui.notify('生成完成!', type = 'positive')
async def choose_file():
global input_document_path
files = await app.native.main_window.create_file_dialog(file_types = ("excel文件(*.docx)", ))
if files:
input_document_path = files[0]
# 设置界面label显示文件路径
label.text = input_document_path
# 按钮
with ui.row().classes('flex justify-center items-center'):
ui.button("上传文件", on_click = choose_file)
label = ui.label("")
with ui.row().classes('flex justify-center items-center'):
ui.button('点击生成说明', on_click = generat_document)
# 定义进度条
knob = ui.knob(0.0, show_value = True).bind_value(db, 'content')
ui.run(native = True)