# -*- coding: utf-8 -*-
import logging

LOG_FORMAT = "%(asctime)s>%(levelname)s>PID:%(process)d %(thread)d>%(module)s>%(funcName)s>%(lineno)d>%(message)s"
logging.basicConfig(
    level=logging.DEBUG,
    format=LOG_FORMAT,
)

# 是否打印调试信息标志
debug = True
if debug:
    logging.debug("进入主程序，开始导入包...")

# 导入常规库
import sys, re, string
from pathlib import *
# 导入word文档操作库
from win32com.client import DispatchEx
from docxtpl import DocxTemplate
import docx
from docx import Document
import shutil
import pythoncom
# 导入QT组件
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QDialog, QToolTip
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QFont
# 导入UI转换PY文件
from need.Ui_GUI import Ui_MainWindow
from need import about, zhuan
# 导入工具包文件-时间转换
from need.utils import get_current_time, get_current_name, get_current_date, get_current_hour
from need.zhuan_tool import IEEE754_16_to_float, IEEE754_float_to_16
# 导入其他线程
from need.threads import create_bujian
from need.fpga_record_thrend import create_FPGA_record
from need.fpga_JtoS import create_FPGA_JtoS
from need.new_JtoS import create_new_JtoS


class zhuan_dlg(QDialog, zhuan.Ui_Dialog):

    def __init__(self):
        super().__init__()
        self.setupUi(self)

        if debug:
            logging.debug("初始化转换程序:")

        #linetext信号连接
        self.lineEdit.editingFinished.connect(self.shiliu_zhuan)
        self.lineEdit_2.editingFinished.connect(self.shi_zhuan)
        # 设置气泡提示信息
        QToolTip.setFont(QFont("SansSerif", 12))
        self.lineEdit.setToolTip("注意，编辑输入框后需要点击其他控件才进行转换，且格式不正确不转换")
        self.lineEdit_2.setToolTip("注意，编辑输入框后需要点击其他控件才进行转换，且格式不正确不转换")

    def shiliu_zhuan(self):
        #获取当前文字
        x = self.lineEdit.text()
        if len(x) == 8:
            if self.radioButton.isChecked() == True:  #说明选中了32位转换
                result = IEEE754_16_to_float(x, 32)
                self.lineEdit_2.setText(str(result))
        elif len(x) == 16:
            if self.radioButton_2.isChecked() == True:  #说明选中了64位转换
                result = IEEE754_16_to_float(x, 64)
                self.lineEdit_2.setText(str(result))

    def shi_zhuan(self):
        #获取当前文字
        x = self.lineEdit_2.text()
        #字符串转浮点数
        # if str.isdigit(x):
        #     x = float(x)
        # elif str.isdigit(x.replace(".","")):
        try:
            x = float(x)
        except:
            logging.debug('输入的内容无法转换为浮点数')

        if isinstance(x, float) == True:
            print('进入转换函数里面')
            if self.radioButton.isChecked() == True:  #说明选中了32位转换
                result = IEEE754_float_to_16(x, 32)
                print(result)
                self.lineEdit.setText(str(result))
            else:
                result = IEEE754_float_to_16(x, 64)
                self.lineEdit.setText(str(result))


class userMain(QMainWindow, Ui_MainWindow):
    #自定义信号和槽

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        if debug:
            logging.debug("初始化主程序:")

        # 实例化翻译家
        self.trans = QtCore.QCoreApplication.translate
        self.setWindowTitle('测试个人工具')

        #使用翻译家改变PYQT的空间名字等属性self.label_4.setText(self.trans("MainWindow", "文件名（自动识别）："))

        if debug:
            logging.debug("初始化部分全局变量...")
        # 存放文件夹路径变量
        self.open_dirs_name = ''
        # 存放文件名称路径变量
        self.open_file_name = ''

        # 读取配置文件

        #~~~~~~~~~~~~~~~连接线程函数~~~~~~~~~~~~~~~
        ## 连接大纲生成说明函数
        self.create_shuoming_trd = create_shuoming(self)
        self.create_shuoming_trd.sin_out.connect(self.text_display)
        self.pushButton_2.clicked.connect(self.create_shuoming_btn)

        ## 连接大纲追溯
        self.create_dagang_zhuisu_trd = create_dagang_zhuisu(self)
        self.create_dagang_zhuisu_trd.sin_out.connect(self.text_display)
        self.pushButton_5.clicked.connect(self.creat_shuoming_zhuisu_btn)

        ## 连接说明追踪线程
        self.create_shuoming_zhuisu_trd = create_shuoming_zhuisu(self)
        self.create_shuoming_zhuisu_trd.sin_out.connect(self.text_display)
        self.pushButton_6.clicked.connect(self.creat_dagang_zhuisu_btn)

        ## 连接报告追踪
        self.create_baogao_zhuisu_trd = create_baogao_zhuisu(self)
        self.create_baogao_zhuisu_trd.sin_out.connect(self.text_display)
        self.pushButton_18.clicked.connect(self.create_baogao_zhuisu_btn)

        ## 连接单元追踪线程
        self.create_danyuan_trd = create_danyuan(self)
        self.create_danyuan_trd.sin_out.connect(self.text_display)
        self.pushButton_8.clicked.connect(self.creat_danyuan_btn)

        ## 连接根据测试说明生成记录线程
        self.create_jilu_trd = create_jilu(self)
        self.create_jilu_trd.sin_out.connect(self.text_display)
        self.pushButton_12.clicked.connect(self.creat_jilu_btn)

        ## 记录反向生成说明线程
        self.create_shuomingfanxiang_trd = create_new_JtoS(self)
        self.create_shuomingfanxiang_trd.sin_out.connect(self.text_display)
        self.pushButton_13.clicked.connect(self.creat_shuomingfanxiang_btn)

        ## 自动填充空白表格线程
        self.create_zidong_trd = create_zidong(self)
        self.create_zidong_trd.sin_out.connect(self.text_display)
        self.pushButton_15.clicked.connect(self.creat_zidong_btn)

        ## 清空单元格线程
        self.clear_cell_trd = clear_cell(self)
        self.clear_cell_trd.sin_out.connect(self.text_display)
        self.pushButton_14.clicked.connect(self.clear_cell_btn)

        ## 提取表格内容线程
        self.get_content_trd = get_content(self)
        self.get_content_trd.sin_out.connect(self.text_display)
        self.pushButton_19.clicked.connect(self.get_content_btn)

        ## 部件测试调用关系表格线程
        self.create_bujian_trd = create_bujian(self)
        self.create_bujian_trd.sin_out.connect(self.text_display)
        self.pushButton_28.clicked.connect(self.create_bujian_btn)

        ## FPGA记录填写表格线程
        self.create_FPGA_record_trd = create_FPGA_record(self)
        self.create_FPGA_record_trd.sin_out.connect(self.text_display)
        self.pushButton_30.clicked.connect(self.create_FPGA_record_btn)

        ## FPGA记录转为说明线程
        self.create_FPGA_JtoS_trd = create_FPGA_JtoS(self)
        self.create_FPGA_JtoS_trd.sin_out.connect(self.text_display)
        self.pushButton_32.clicked.connect(self.create_FPGA_JtoS_btn)

        # 自定义信号连接
        # 获取状态栏对象
        self.user_statusbar = self.statusBar()
        # 右下角窗口尺寸调整符号
        self.user_statusbar.setSizeGripEnabled(True)
        self.user_statusbar.setStyleSheet("QStatusBar.item{border:10px}")

        #~~~~~~~~~~~~~~~按钮连接函数~~~~~~~~~~~~~~~~
        ##选择文件按钮连接
        self.pushButton.clicked.connect(self.choose_docx_func)
        self.pushButton_4.clicked.connect(self.choose_docx_func)
        self.pushButton_7.clicked.connect(self.choose_docx_func)
        self.pushButton_11.clicked.connect(self.choose_docx_func)
        self.pushButton_16.clicked.connect(self.choose_docx_func)
        self.pushButton_17.clicked.connect(self.choose_docx_func)
        self.pushButton_27.clicked.connect(self.choose_docx_func)
        self.pushButton_29.clicked.connect(self.choose_docx_func)
        self.pushButton_31.clicked.connect(self.choose_docx_func)
        #清空显示区
        self.pushButton_9.clicked.connect(self.clear_textEdit_content)
        #显示帮助
        self.pushButton_10.clicked.connect(self.display_help)

        #~~~~~~~~~~~~~~~导航栏按钮连接函数~~~~~~~~~~~~~~~~
        #显示关于本软件的菜单
        self.actionAbout.triggered.connect(self.display_about)
        #打开文件夹
        self.actionopen.triggered.connect(self.choose_docx_func)
        #打开IEEE754转换工具
        self.actionIEEE754.triggered.connect(self.open_zhuan_tool)

        if debug:
            logging.debug("界面加载完成...")

#~~~~~~~~~~~~~~~~~~~~初始化直接运行的函数（也就是起始运行一次）~~~~~~~~~~~~~~~~~~~~~~~~~~

#~~~~~~~~~~~~~~~~~~~~间接按钮函数，用户点击后操作~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#清空显示区函数

    def clear_textEdit_content(self):
        self.textBrowser.clear()
        return

    #显示帮助函数
    def display_help(self):
        txt_path = Path.cwd() / 'need' / 'others' / 'readme.txt'
        with open(txt_path, 'r', encoding='utf-8') as f:
            data = f.read()
            self.textBrowser.append(data)
        return

    #显示关于函数
    def display_about(self):
        dlg = QDialog()
        about_dlg = about.Ui_Dialog()
        about_dlg.setupUi(dlg)
        dlg.show()
        dlg.exec_()
        print("显示关于界面")
        return

    #显示IEEE754转换工具
    def open_zhuan_tool(self):
        dlg_zhuan = zhuan_dlg()  #实例化界面
        dlg_zhuan.show()
        dlg_zhuan.exec_()
        return

#~~~~~~~~~~~~~~~~~~~~线程区域函数，用于启动线程~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#生成测试说明启动函数

    def create_shuoming_btn(self):
        self.create_shuoming_trd.start()
        self.tabWidget.setEnabled(False)
        return

# 大纲追溯线程启动函数

    def creat_dagang_zhuisu_btn(self):
        self.create_dagang_zhuisu_trd.start()
        self.tabWidget.setEnabled(False)

# 说明追溯线程启动函数

    def creat_shuoming_zhuisu_btn(self):
        self.create_shuoming_zhuisu_trd.start()
        self.tabWidget.setEnabled(False)

# 提取单元格标题右侧内容线程启动函数

    def create_baogao_zhuisu_btn(self):
        self.create_baogao_zhuisu_trd.start()
        self.tabWidget.setEnabled(False)

# 记录反向生成说明线程

    def creat_shuomingfanxiang_btn(self):
        self.create_shuomingfanxiang_trd.start()
        self.tabWidget.setEnabled(False)

# 单元测试报告转换为我们的用例线程

    def creat_danyuan_btn(self):
        self.create_danyuan_trd.start()
        self.tabWidget.setEnabled(False)

# 单元测试报告转换为我们的用例线程

    def creat_jilu_btn(self):
        self.create_jilu_trd.start()
        self.tabWidget.setEnabled(False)

# 自动填充线程

    def creat_zidong_btn(self):
        self.create_zidong_trd.start()
        self.tabWidget.setEnabled(False)

# 清空表格单元格内容

    def clear_cell_btn(self):
        self.clear_cell_trd.start()
        self.tabWidget.setEnabled(False)

# 提取单元格标题右侧内容线程启动函数

    def get_content_btn(self):
        self.get_content_trd.start()
        self.tabWidget.setEnabled(False)

# 部件测试提取调用启动线程函数

    def create_bujian_btn(self):
        self.create_bujian_trd.start()
        self.tabWidget.setEnabled(False)

# FPGA记录填写

    def create_FPGA_record_btn(self):
        self.create_FPGA_record_trd.start()
        self.tabWidget.setEnabled(False)

# FPGA记录转说明

    def create_FPGA_JtoS_btn(self):
        self.create_FPGA_JtoS_trd.start()
        self.tabWidget.setEnabled(False)

#选择文档函数

    def choose_docx_func(self):
        self.open_file_name = QFileDialog.getOpenFileName(
            self, '选择文件', '.', "Word files(*.docx)")
        self.textBrowser.append('已选择文件路径：' + self.open_file_name[0])

#关闭线程函数

    def stop_shuoming_thread(self):
        self.tabWidget.setEnabled(True)
        QMessageBox.warning(self, '处理完毕', '文档处理完毕！')
        print("停止线程成功！")

#~~~~~~~~~~~~~~~~~~~~显示函数~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    def text_display(self, texttmp):
        if texttmp[:9] == 'stoperror':
            QMessageBox.warning(self, '处理完毕', '文档处理失败！')
            self.tabWidget.setEnabled(True)
            return

        if texttmp[:11] == 'stopsuccess':
            self.stop_shuoming_thread()
            self.tabWidget.setEnabled(True)
            return

        if texttmp[:6] == 'total:':
            cnt = int(texttmp[6:])
            self.progressBar.setRange(0, cnt - 1)

        if texttmp == 'function success':
            QMessageBox.information(self, '操作成功', '请查看本程序当前文件夹下的相关文档！')
            self.textBrowser.append('完成！！！')
            self.tabWidget.setEnabled(True)
            return
        if texttmp == '保存文件错':
            QMessageBox.warning(self, '出错了', '保存文件失败！')
            self.tabWidget.setEnabled(True)
            return
        if texttmp == 'no folder':
            QMessageBox.information(self, '没有选择文件夹', '还没有选择文件夹，点击"文件"菜单进行选择！')
            self.tabWidget.setEnabled(True)
            return
        if texttmp.find('warning:') != -1:
            QMessageBox.information(self, 'WARNING', texttmp[8:])
            self.tabWidget.setEnabled(True)
            return

        if texttmp.find('open failed:') != -1:
            QMessageBox.warning(
                self, '打开文件失败',
                '打开' + texttmp[12:] + '失败' + '请确认文档是否打开或者模板文件存在且后缀名为docx！')
            self.tabWidget.setEnabled(True)
            return
        if texttmp == 'nofile':
            QMessageBox.information(self, '错误',
                                    '还没有选择文件（夹），点击"文件"菜单或者工具栏进行选择！')
            self.tabWidget.setEnabled(True)
            return
        if texttmp.isdigit() == True:
            self.progressBar.setValue(int(texttmp))
            self.tabWidget.setEnabled(True)
        else:
            self.textBrowser.append(texttmp)
            self.tabWidget.setEnabled(True)
        # 如果前面是all_doned:则进度条填满
        if texttmp.find('all_doned:') != -1:
            self.progressBar.setRange(0, 100)
            self.progressBar.setValue(100)

    def closeEvent(self, event):
        reply = QMessageBox.question(self, '提示', "是否要关闭所有窗口?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
            sys.exit(0)  # 退出程序
        else:
            event.ignore()


##################################################################################
#大纲生成测试说明线程
##################################################################################
class create_shuoming(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        #用来储存测试项DC等转换
        zhuan_dict = {'DC':'文档审查','SU':'功能测试','CR':'代码审查','SA':'静态分析','AC':'性能测试',\
            'IO':'接口测试','SE':'安全性测试','BT':'边界测试','RE':'恢复性测试','ST':'强度测试',\
                'AT':'余量测试','GUI':'人机交互界面测试','DP':'数据处理测试','JR':'兼容性测试',\
                    'LG':'逻辑测试','AZ':'安装性测试','TT':'时序测试','PA':'功耗分析'}

        self.sin_out.emit("进入军品大纲转说明......")
        self.sin_out.emit("开始转换......")
        #如果没有选择路径则退出
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        #告诉windows单线程
        pythoncom.CoInitialize()
        #在用户选择的目录中查找大纲文档
        self.sin_out.emit('打开测评大纲文档...')

        #使用win32com打开-记得关闭
        #打开word应用
        self.w = DispatchEx('Word.Application')
        #self.w.visible=True
        self.w.DisplayAlerts = 0
        try:
            dagangfile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        self.sin_out.emit('复制测试说明文档模板到本程序所在目录...')
        curpath = Path.cwd() / 'need'
        shuoming_path_tmp = curpath / 'document_templates' / '测试说明模板.docx'
        print(shuoming_path_tmp)
        if shuoming_path_tmp.is_file():
            self.sin_out.emit('已检测到有说明模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return

        #创建一个字典来储存单个用例

        data_list = []

        #获取表格数量
        try:
            csx_tb_count = dagangfile.Tables.Count
            self.sin_out.emit('total:' + str(csx_tb_count))
        except:
            self.sin_out.emit('不存在表格！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                dagangfile.Close()
            except:
                pass
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        #循环表格
        yongli_count = 0
        #用来储存章节号中的DC、SU等标识，用于章节号判断
        is_fire_su = ""
        #用来储存基本_分割后个数
        num_fenge = 3
        for i in range(csx_tb_count):
            self.sin_out.emit(str(i))
            if dagangfile.Tables[i].Rows.Count > 2:
                #注意win32com的Cell从1开始不是从0开始
                if dagangfile.Tables[i].Cell(1,
                                             1).Range.Text.find('测试项名称') != -1:
                    #一个用例不变内容获取
                    dagangfile.Tables[i].Rows.First.Select()
                    zhangjiehao = self.w.Selection.Bookmarks("\headinglevel").\
                        Range.Paragraphs(1).Range.ListFormat.ListString
                    zhangjieming = self.w.Selection.Bookmarks("\headinglevel").\
                        Range.Paragraphs(1).Range.Text.rstrip('\r')
                    print("测试项所在章节号：", zhangjiehao)
                    #获取用例标识不加上序号_1
                    basic_biaoshi = dagangfile.Tables[i].Cell(
                        1, 4).Range.Text.rstrip()[:-2]
                    print("测试项标识为：", basic_biaoshi)

                    #储存num_fenge的数值，初始化
                    if yongli_count == 0:
                        num_fenge = len(basic_biaoshi.split("_"))
                    #获取测试用例名称Cell(4,2)整行
                    info_ceshi_buzhou = dagangfile.Tables[i].Cell(4,
                                                                  2).Range.Text
                    info_ceshi_yuqi = dagangfile.Tables[i].Cell(9,
                                                                2).Range.Text
                    #判断是否只有一行，如果只有一行处理表格
                    if dagangfile.Tables[i].Cell(
                            4, 2).Range.Paragraphs.Count <= 1:

                        #缓存一个用例的data填入数据
                        data = {'zhangjie':'','mingcheng':'','biaoshi':'','is_first':'1', \
                        'yueshu':'软件正常工作，环境连接正常', 'yongli_biaoshi':'','renyuan':'陈俊亦',\
                        'chushi':'外接设备或软件运行正常','csx_mingcheng':'','is_begin':'0',\
                            'zongsu':'',"zuhe":[],'csxbs':""}
                        zuhe_dict = {"buzhou": "", "yuqi": "", "xuhao": "1"}
                        try:
                            #填写一行情况下表格
                            data['mingcheng'] = dagangfile.Tables[i].Cell(
                                1, 2).Range.Text.rstrip('\r\x07')
                            #注意word中后面都有2个字符
                            data['yongli_biaoshi'] = (basic_biaoshi +
                                                      "_1").replace(
                                                          'XQ', 'YL')
                            data['zhangjie'] = zhangjiehao
                            data['csx_mingcheng'] = zhangjieming
                            data['biaoshi'] = basic_biaoshi
                            data['zongsu'] = dagangfile.Tables[i].Cell(
                                3, 2).Range.Text[:-2]

                            zuhe_dict["buzhou"] = dagangfile.Tables[i].Cell(
                                4, 2).Range.Text.rstrip('\r\x07')
                            zuhe_dict["yuqi"] = dagangfile.Tables[i].Cell(
                                9, 2).Range.Text.rstrip('\r\x07')
                            zuhe_dict["xuhao"] = '1'
                            data["zuhe"].append(zuhe_dict)
                            #判断是否为第一个测试类型，如果是修改章节号标识,则将章节号展示，如果和储存相同
                            #则章节号不展示
                            #首先获取测试项标识，分割成列表
                            fenge = data['biaoshi'].split("_")
                            #获取当前测试项分割后的个数
                            if len(fenge) == 4:
                                if fenge[-2] != is_fire_su:
                                    is_fire_su = fenge[-2]
                                    data['is_begin'] = "1"
                                    data['csxbs'] = zhuan_dict[fenge[-2]]
                            elif len(fenge) == 3:
                                if fenge[-1] == 'DC' or fenge[
                                        -1] == 'CR' or fenge[-1] == 'SA':
                                    if fenge[-1] != is_fire_su:
                                        is_fire_su = fenge[-1]
                                        data['is_begin'] = "1"
                                        data['csxbs'] = zhuan_dict[fenge[-1]]
                                else:
                                    if fenge[-2] != is_fire_su:
                                        is_fire_su = fenge[-2]
                                        data['is_begin'] = "1"
                                        data['csxbs'] = zhuan_dict[fenge[-2]]
                            else:
                                if fenge[-1] != is_fire_su:
                                    is_fire_su = fenge[-1]
                                    data['is_begin'] = "1"
                                    data['csxbs'] = zhuan_dict[fenge[-1]]

                            if self.parent.lineEdit.text():
                                data['renyuan'] = self.parent.lineEdit.text()
                            #将data加入data_list
                            data['is_first'] = "1"
                            data_list.append(data)
                            yongli_count += 1

                            self.sin_out.emit(
                                '###获取用例序号：{}'.format(yongli_count))
                            self.sin_out.emit('###该用例标识为：{}'.format(
                                data['yongli_biaoshi']))
                        except:
                            self.sin_out.emit(
                                f'$$$$$$$$$$$$第{str(i+1)}个表格处理失败$$$$$$$$$$$$')
                            pass

                    elif dagangfile.Tables[i].Cell(
                            4, 2).Range.Paragraphs.Count > 1:

                        try:
                            #下面拆分每行，使用\r（回车）分割
                            info_buzhou_list = list(
                                filter(lambda x: x != "\x07" and x != "",
                                       info_ceshi_buzhou.split('\r')))
                            info_yuqi_list = list(
                                filter(lambda x: x != "\x07" and x != "",
                                       info_ceshi_yuqi.split('\r')))

                            #去掉括号和以下字符
                            rule = "[;；。]"  #rule为去掉的符号（这个可以改TODO）

                            #初始化去掉rule的列表
                            buzhou_list = []
                            yuqi_list = []

                            for item in info_buzhou_list:
                                index = item.find("(")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find("（")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find(")")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find("）")
                                if index != -1:
                                    item = item[index + 1:]
                                buzhou_list.append(
                                    re.sub(rule, "",
                                           item).lstrip(string.digits))
                            for item in info_yuqi_list:
                                index = item.find("(")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find("（")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find(")")
                                if index != -1:
                                    item = item[index + 1:]
                                index = item.find("）")
                                if index != -1:
                                    item = item[index + 1:]
                                yuqi_list.append(
                                    re.sub(rule, "",
                                           item).lstrip(string.digits))

                            #获取测试项综述-为该循环前不变内容
                            basic_zongshu = buzhou_list.pop(0).strip()
                            print('获取的测试用例综述是：', data["zongsu"])

                            #获取字典中的buzhou和yuqi,找冒号
                            j = -1  #自制列表索引
                            substrict_list = []  #差值列表
                            for item in buzhou_list:
                                #先找到冒号所在索引
                                j = j + 1
                                if item.find(":") != -1 or item.find(
                                        "：") != -1:
                                    #现在知道冒号所在行号，现在要确定每个用例几行
                                    substrict_list.append(j)

                            #！！！注意差值计算步骤需要-1才是正确的步骤数量
                            # self.sin_out.emit("解析测试项序号"+ str(i) + "|检测到冒号所在行号为：" \
                            #     + str(substrict_list))
                            # self.sin_out.emit("|检测到步骤总行数(序号)：" \
                            #     + str(len(buzhou_list)))

                            #循环用例个数
                            count_test = len(substrict_list)
                            temp_list = substrict_list
                            temp_list.append(len(buzhou_list))

                            for item in range(count_test):
                                #初始化data数据,包括步骤和预期、序号dict
                                data = {'zhangjie':'','mingcheng':'','biaoshi':'','is_first':'0', \
                                    'yueshu':'软件正常工作，环境连接正常', 'yongli_biaoshi':'','renyuan':'陈俊亦',\
                                    'chushi':'外接设备或软件运行正常','csx_mingcheng':'','is_begin':'0',\
                                        'zongsu':'',"zuhe":[],'csxbs':""}

                                #这里要求冒号最后一个
                                data['mingcheng'] = buzhou_list[
                                    substrict_list[item]][:-1]
                                data['yongli_biaoshi'] = (
                                    basic_biaoshi + f'_{item+1}').replace(
                                        'XQ', 'YL')
                                #常规填入
                                data['zhangjie'] = zhangjiehao
                                data['csx_mingcheng'] = zhangjieming
                                data['biaoshi'] = basic_biaoshi
                                data['zongsu'] = basic_zongshu
                                #步骤填入,首先根据substrict_list获取有几个步骤

                                #循环行数
                                for x in range(temp_list[item + 1] -
                                               (temp_list[item] +
                                                1)):  #循环一个用例步骤预期数
                                    zuhe_dict = {
                                        "buzhou": "",
                                        "yuqi": "",
                                        "xuhao": ""
                                    }
                                    #把每个步骤和预期都放进zuhe_dict中
                                    zuhe_dict["buzhou"] = buzhou_list[
                                        temp_list[item] + x + 1]
                                    zuhe_dict["yuqi"] = yuqi_list[
                                        temp_list[item] + x + 1]
                                    zuhe_dict["xuhao"] = str(x + 1)
                                    data["zuhe"].append(zuhe_dict)

                                if item == 0:
                                    data['is_first'] = '1'
                                #判断是否为SU标题
                                fenge = data['biaoshi'].split("_")
                                #获取当前测试项分割后的个数
                                if len(fenge) == 4:
                                    if fenge[-2] != is_fire_su:
                                        is_fire_su = fenge[-2]
                                        data['is_begin'] = "1"
                                        data['csxbs'] = zhuan_dict[fenge[-2]]
                                elif len(fenge) == 3:
                                    if fenge[-1] == 'DC' or fenge[
                                            -1] == 'CR' or fenge[-1] == 'SA':
                                        if fenge[-1] != is_fire_su:
                                            is_fire_su = fenge[-1]
                                            data['is_begin'] = "1"
                                            data['csxbs'] = zhuan_dict[
                                                fenge[-1]]
                                    else:
                                        if fenge[-2] != is_fire_su:
                                            is_fire_su = fenge[-2]
                                            data['is_begin'] = "1"
                                            data['csxbs'] = zhuan_dict[
                                                fenge[-2]]
                                else:
                                    if fenge[-1] != is_fire_su:
                                        is_fire_su = fenge[-1]
                                        data['is_begin'] = "1"
                                        data['csxbs'] = zhuan_dict[fenge[-1]]
                                if self.parent.lineEdit.text():
                                    data[
                                        'renyuan'] = self.parent.lineEdit.text(
                                        )
                                #加入data_list
                                data_list.append(data)
                                yongli_count += 1  #用例计数加一

                                self.sin_out.emit(
                                    '###获取用例序号：{}'.format(yongli_count))
                                self.sin_out.emit('###该用例标识为：{}'.format(
                                    data['yongli_biaoshi']))
                        except:
                            self.sin_out.emit(
                                f'$$$$$$$$$$$$第{str(i+1)}个表格处理失败$$$$$$$$$$$$')
                            pass

        #关闭大纲文档（因为以及提取完毕）
        try:
            dagangfile.Close()
            self.w.Quit()
            pythoncom.CoUninitialize()
        except:
            self.sin_out.emit('function fail')
            self.w.Quit()
            pythoncom.CoUninitialize()
            return

        #打开模板文件进行渲染，然后就是用docxtpl生成用例
        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "测试说明模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  #模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        #开始渲染模板文件-有2层循环
        try:
            context = {
                "tables": data_list,
            }
            tpl.render(context)
            tpl.save("生成的说明文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
#大纲生成追踪关系
##################################################################################
class create_dagang_zhuisu(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit("进入大纲追踪线程......")
        self.sin_out.emit("开始填写追踪......")

        #如果没有选择路径则退出
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        #告诉windows单线程
        pythoncom.CoInitialize()
        #在用户选择的目录中查找大纲文档
        self.sin_out.emit('打开测评大纲文档...')

        #使用win32com打开-记得关闭
        #打开word应用
        self.w = DispatchEx('Word.Application')
        #self.w.visible=True
        self.w.DisplayAlerts = 0
        try:
            dagangfile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        curpath = Path.cwd() / 'need'
        zhuisu_path_tmp = curpath / 'document_templates' / '大纲追踪模板.docx'
        print(zhuisu_path_tmp)

        if zhuisu_path_tmp.is_file():
            self.sin_out.emit('已检测到有追溯模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return

        #创建个列表放数据
        data_list = []
        data2_list = []

        try:
            csx_tb_count = dagangfile.Tables.Count
            self.sin_out.emit('total:' + str(csx_tb_count))
        except:
            self.sin_out.emit('不存在表格！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                dagangfile.Close()
            except:
                pass
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        for i in range(csx_tb_count):
            self.sin_out.emit(str(i))
            self.sin_out.emit("正在处理第{}个表格...".format(str(i)))
            print("正在处理第{}个表格...".format(str(i)))
            #准备填入的data
            data = {
                'xuqiu': [],
                'dg_zhangjie': '',
                'mingcheng': '',
                'biaoshi': ''
            }
            data2 = {
                'xuqiu': [],
                'dg_zhangjie': '',
                'mingcheng': '',
                'biaoshi': ''
            }
            if dagangfile.Tables[i].Rows.Count > 2:
                #注意win32com的Cell从1开始不是从0开始
                if dagangfile.Tables[i].Cell(1,
                                             1).Range.Text.find('测试项名称') != -1:
                    #一个用例不变内容获取
                    dagangfile.Tables[i].Rows.First.Select()  #获取测试项章节号
                    zhangjiehao = self.w.Selection.Bookmarks("\headinglevel").\
                        Range.Paragraphs(1).Range.ListFormat.ListString #获取测试项章节名
                    zhangjieming = self.w.Selection.Bookmarks("\headinglevel").\
                        Range.Paragraphs(1).Range.Text.rstrip('\r')
                    biaoshi = dagangfile.Tables[i].Cell(
                        1, 4).Range.Text.rstrip()[:-2]

                    #获取需规的章节号和描述
                    if dagangfile.Tables[i].Cell(
                            2, 1).Range.Text.find("追踪关系") != -1:
                        zhuizong_tmp = dagangfile.Tables[i].Cell(
                            2, 2).Range.Text[:-2]
                        #由于有/的存在，先判断/和隐含需求
                        zhuizong_list = zhuizong_tmp.split("\r")
                        print(zhuizong_list)
                        if zhuizong_tmp == "/" or zhuizong_tmp == "隐含需求":
                            xuqiu_dict = {
                                'xq_zhangjie': '/',
                                'xq_miaoshu': '/'
                            }
                            data['xuqiu'].append(xuqiu_dict)
                            data2['xuqiu'].append(xuqiu_dict)
                        else:
                            if len(zhuizong_list) >= 1:
                                for item in zhuizong_list:
                                    xuqiu_dict = {}
                                    if item.find("需求") != -1:
                                        try:
                                            match_string = re.search(
                                                "\d(.\d+)+", item).group()
                                            match_ming = item.split(
                                                match_string)[-1]
                                            xuqiu_dict[
                                                'xq_zhangjie'] = match_string
                                            xuqiu_dict[
                                                'xq_miaoshu'] = match_ming.lstrip(
                                                    " ")
                                            data['xuqiu'].append(xuqiu_dict)
                                        except:
                                            self.sin_out.emit(
                                                f'$$$$$$$$$$$$第{str(i+1)}个表格无章节号$$$$$$$$$$$$'
                                            )
                                            self.sin_out.emit(
                                                "转换终止！请检查表格中追踪关系有无章节号")
                                            pass
                                    else:
                                        try:
                                            match_string = re.search(
                                                "\d(.\d+)+", item).group()
                                            match_ming = item.split(
                                                match_string)[-1]
                                            xuqiu_dict[
                                                'xq_zhangjie'] = match_string
                                            xuqiu_dict[
                                                'xq_miaoshu'] = match_ming.lstrip(
                                                    " ")
                                            data2['xuqiu'].append(xuqiu_dict)
                                        except:
                                            self.sin_out.emit(
                                                f'$$$$$$$$$$$$第{str(i+1)}个表格无章节号$$$$$$$$$$$$'
                                            )
                                            self.sin_out.emit(
                                                "转换终止！请检查表格中追踪关系有无章节号")
                                            pass

                            #如果追踪关系行数小于1行的情况
                            else:
                                xuqiu_dict = {
                                    'xq_zhangjie': '/',
                                    'xq_miaoshu': '/'
                                }
                                data['xuqiu'].append(xuqiu_dict)
                                data2['xuqiu'].append(xuqiu_dict)

                        try:
                            data['dg_zhangjie'] = zhangjiehao
                            data['mingcheng'] = zhangjieming
                            data['biaoshi'] = biaoshi
                            data_list.append(data)
                            data2['dg_zhangjie'] = zhangjiehao
                            data2['mingcheng'] = zhangjieming
                            data2['biaoshi'] = biaoshi
                            data2_list.append(data2)
                        except:
                            print("获取追踪出错啦！")
                            self.sin_out.emit(
                                f'$$$$$$$$$$$$第{str(i+1)}个表格追踪处理失败$$$$$$$$$$$$'
                            )
                            pass

        #最后关闭文档
        try:
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
        except:
            QMessageBox.warning(self.parent, "关闭文档失败", "关闭文档失败！")
            return

        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "大纲追踪模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  #模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        #开始渲染模板文件
        try:
            context = {
                "tables": data_list,
                "tables2": data2_list,
            }
            tpl.render(context)
            tpl.save("生成的大纲追踪文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            QMessageBox.warning(self.parent, "生成文档出错",
                                "生成文档错误，请确认模板文档是否已打开或格式错误")
            self.sin_out.emit('stoperror')
            return


##################################################################################
#单元测试UAS转换
##################################################################################
class create_danyuan(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit("进入单元测试SunwiseAUnit转换线程......")
        self.sin_out.emit("开始填写文档......")

        #如果没有选择路径则退出
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return

        #告诉windows单线程
        pythoncom.CoInitialize()
        #在用户选择的目录中查找UAS单位测试报告文档
        self.sin_out.emit('打开单元测试原文件...')

        #使用win32com打开-记得关闭
        #打开word应用
        self.w = DispatchEx('Word.Application')
        #self.w.visible=True
        self.w.DisplayAlerts = 0
        try:
            danyuanfile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        curpath = Path.cwd() / 'need'
        danyuan_file_tmp = curpath / 'document_templates' / 'SunwiseAUnit单元测试转换模板.docx'
        print(danyuan_file_tmp)

        if danyuan_file_tmp.is_file():
            self.sin_out.emit('已检测到有追溯模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return

        #创建个列表放数据-important
        data_list = []

        #try统计表格数量
        try:
            csx_tb_count = danyuanfile.Tables.Count
            self.sin_out.emit('total:' + str(csx_tb_count))
            self.sin_out.emit("正在调用word文档操作接口,可能会有点慢...")
        except:
            self.sin_out.emit('不存在表格！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                danyuanfile.Close()
            except:
                pass
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        #开始处理表格-important
        #我先统计有多少个生成的表格-即用例有多少个呗
        yongli_count = 0
        for i in range(csx_tb_count):
            if danyuanfile.Tables[i].Rows.Count > 2:
                #注意win32com的Cell从1开始不是从0开始
                if danyuanfile.Tables[i].Cell(1,
                                              1).Range.Text.find('用例名称') != -1:
                    yongli_count += 1

        #yongli_num指向当前处理的用例
        yongli_num = 0
        hanshuming = ''
        hanshuming_duibi = ''
        wenjian = ''
        wenjian_duibi = ''
        for i in range(csx_tb_count):
            self.sin_out.emit('正在处理的表格序号：' + str(yongli_num + 1))
            self.sin_out.emit(str(i))
            #准备填入的data
            data = {'ruanjian_ming':'','ruanjian_biaoshi':'yongli_biaoshi','wenjian_ming':'',\
                'hanshu_ming':'','bianlian_and_canshu':'','zhuang':[],\
                    'yuqi_jieguo':'','ceshi_jieguo':'','is_begin':'0','is_wenjian':'0'}

            #填入用户输入的软件名
            try:
                data['ruanjian_ming'] = self.parent.lineEdit_2.text()
                data['ruanjian_biaoshi'] = self.parent.lineEdit_3.text()

            except:
                QMessageBox.critical(self.parent, "未填入数据", "请先填入软件名和软件标识或.C名称")
                self.w.Quit()
                pythoncom.CoUninitialize()
                self.parent.tabWidget.setEnabled(True)
                pass

            #找到函数名,这里容易出问题
            if danyuanfile.Tables[i].Rows.Count > 2:
                if danyuanfile.Tables[i].Cell(1,
                                              1).Range.Text.find('功能描述') != -1:
                    danyuanfile.Tables[i].Cell(1, 1).Range.Select()
                    self.w.Selection.MoveUp()
                    self.w.Selection.MoveUp()
                    self.w.Selection.MoveUp()
                    s = self.w.Selection.Paragraphs(1).Range.Text[:-1]
                    s1 = s.split(". ")[-1]
                    #放入函数名比对
                    if s1 != hanshuming_duibi:
                        hanshuming_duibi = s1

                    #再向上看1行
                    self.w.Selection.MoveUp()
                    temp2 = self.w.Selection.Paragraphs(1).Range.Text[:-1]
                    s2 = temp2.split("\\")[-1]
                    if '.' in temp2 and '\\' in temp2:
                        print('@@@@@@:', s2)
                        if s2 != wenjian_duibi:  #这里有改动
                            wenjian_duibi = s2

            #找章节号
            if danyuanfile.Tables[i].Rows.Count > 2:
                #注意win32com的Cell从1开始不是从0开始
                if danyuanfile.Tables[i].Cell(1,
                                              1).Range.Text.find('用例名称') != -1:
                    #TODO：如何找到测试模块？
                    biaoshi_temp = danyuanfile.Tables[i].Cell(
                        1, 4).Range.Text[:-2]
                    data['yongli_biaoshi'] = biaoshi_temp

                    #获取表格中参数组合()
                    quanju = danyuanfile.Tables[i].Cell(5, 3).Range.Text[:-2]
                    hcan = danyuanfile.Tables[i].Cell(6, 3).Range.Text[:-2]
                    qitashu = danyuanfile.Tables[i].Cell(7, 3).Range.Text[:-2]

                    if quanju.find('无') != -1:
                        quanju = ""
                    if hcan.find('无') != -1:
                        hcan = ""
                    if qitashu.find('无') != -1:
                        qitashu = ""

                    data['bianlian_and_canshu'] = quanju + hcan + qitashu
                    #将预期结果和测试结果填入
                    data['yuqi_jieguo'] = danyuanfile.Tables[i].Cell(
                        8, 2).Range.Text[:-2]
                    data['ceshi_jieguo'] = danyuanfile.Tables[i].Cell(
                        13, 2).Range.Text[:-2]
                    #函数名获取
                    if hanshuming_duibi != hanshuming:
                        hanshuming = hanshuming_duibi
                        data['is_begin'] = '1'
                    data['hanshu_ming'] = hanshuming_duibi
                    #文件名获取
                    if wenjian_duibi != wenjian:
                        wenjian = wenjian_duibi
                        data['is_wenjian'] = '1'
                    data['wenjian_ming'] = wenjian_duibi

                    data_list.append(data)
                    yongli_num += 1  #用例创建加一

                elif danyuanfile.Tables[i].Cell(1,
                                                2).Range.Text.find('定义') != -1:
                    #定义个桩函数dict
                    zhuang_dict = {'zhuang_name':'','zhuang_dingyi':'','zhuang_fanhui':'',\
                        'zhuang_fuzuoyong':''}

                    zhuang_dict['zhuang_name'] = danyuanfile.Tables[i].Cell(
                        1, 1).Range.Text[:-2]
                    zhuang_dict['zhuang_dingyi'] = danyuanfile.Tables[i].Cell(
                        1, 3).Range.Text[:-2]
                    zhuang_dict['zhuang_fanhui'] = danyuanfile.Tables[i].Cell(2, 3).Range.Paragraphs(1).\
                        Range.Text[:-1]

                    #副作用可能有多行
                    fuzuoyong_temp = ''
                    for count_fuzuo in range(
                            len(danyuanfile.Tables[i].Cell(
                                2, 3).Range.Paragraphs) - 2):
                        fuzuoyong_temp = fuzuoyong_temp + ';' + danyuanfile.Tables[i].Cell(2, 3).\
                        Range.Paragraphs(count_fuzuo + 3).Range.Text[:-2].replace(" ", "")
                    zhuang_dict['zhuang_fuzuoyong'] = fuzuoyong_temp

                    data_list[yongli_num - 1]['zhuang'].append(zhuang_dict)

        #最后关闭文档
        try:
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
        except:
            QMessageBox.warning(self.parent, "关闭文档失败", "关闭文档失败！")
            return

        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "SunwiseAUnit单元测试转换模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  #模板导入成功
        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        #开始渲染模板文件
        try:
            context = {
                "tables": data_list,
            }
            tpl.render(context)
            tpl.save("软件单元测试用例记录表.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
#测试说明追踪以及用例表
##################################################################################
class create_shuoming_zhuisu(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit("进入说明追踪线程......")
        self.sin_out.emit("开始填写说明追踪以及用例表格......")

        # 如果没有选择文件
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        # 告诉windows单线程
        pythoncom.CoInitialize()
        # 在用户选择的目录中查找大纲文档
        self.sin_out.emit('打开测试说明文档...')

        # 使用win32com打开-记得关闭
        # 打开word应用
        self.w = DispatchEx('Word.Application')
        # self.w.visible=True
        self.w.DisplayAlerts = 0
        try:
            shuomingfile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        self.sin_out.emit('已正确打开说明文档...')
        curpath = Path.cwd() / 'need'
        zhuisu_path_tmp = curpath / 'document_templates' / '说明追踪模板.docx'
        print("打开追踪模板文件", zhuisu_path_tmp)

        if zhuisu_path_tmp.is_file():
            self.sin_out.emit('已检测到有说明追溯模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return

        # 创建个列表放数据
        data_list = []
        data2_list = []

        #统计整个表格数量用于processbar显示进度
        try:
            tb_count = shuomingfile.Tables.Count
            self.sin_out.emit('total:' + str(tb_count))
        except:
            self.sin_out.emit('不存在表格！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                shuomingfile.Close()
            except:
                QMessageBox.warning(self.parent, '错误', "未正确关闭Word文档！")
                return
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        #遍历循环表格，这里面就要初始化数据dict了
        #不能像大纲追踪一样data在循环表格里面
        #创建一个大纲测试项索引
        csx_name = ''
        data = {
            'dg_zhangjie': '',
            'mingcheng': '',
            'biaoshi': '',
            'yongli': [],
            'index': 0
        }
        for i in range(tb_count):
            self.sin_out.emit(str(i))
            #self.sin_out.emit("正在处理第{}个表格...".format(str(i+1)))
            print("正在处理第{}个表格...".format(str(i + 1)))
            # 准备填入的data
            data2 = {
                'yongli_ming': '',
                'yongli_biaoshi': '',
                'yongli_zongsu': ''
            }
            yongli_dict = {'yongli_ming': '', 'yongli_biaoshi': ''}
            yongliming = ''
            biaoshi = ''
            zongsu = ''
            zhui_temp = ''

            if shuomingfile.Tables[i].Rows.Count > 2:
                try:
                    # 注意win32com的Cell从1开始不是从0开始
                    if shuomingfile.Tables[i].Cell(1, 1).Range.Text.find('测试用例名称') != -1 or \
                        shuomingfile.Tables[i].Cell(2, 1).Range.Text.find('测试用例名称') != -1:
                        #取出cell(1,,1)的数据
                        table_heard = shuomingfile.Tables[i].Cell(1,
                                                                  1).Range.Text
                        if table_heard.find("测试用例名称") != -1:
                            yongliming = shuomingfile.Tables[i].Cell(
                                1, 2).Range.Text.rstrip()[:-2]
                            biaoshi = shuomingfile.Tables[i].Cell(
                                1, 4).Range.Text.rstrip()[:-2]
                            zongsu = shuomingfile.Tables[i].Cell(
                                3, 2).Range.Text.rstrip()[:-2]
                            zhui_temp = shuomingfile.Tables[i].Cell(
                                2, 2).Range.Text.rstrip()[:-2]
                        elif table_heard.find('用例') != -1:
                            yongliming = shuomingfile.Tables[i].Cell(
                                2, 2).Range.Text.rstrip()[:-2]
                            biaoshi = shuomingfile.Tables[i].Cell(
                                2, 4).Range.Text.rstrip()[:-2]
                            zongsu = shuomingfile.Tables[i].Cell(
                                4, 2).Range.Text.rstrip()[:-2]
                            zhui_temp = shuomingfile.Tables[i].Cell(
                                3, 2).Range.Text.rstrip()[:-2]
                        else:
                            self.sin_out.emit("未找到合适的填写数据，退出处理")
                            print("未找到合适的填写数据")
                            self.w.Quit()
                            pythoncom.CoUninitialize()
                            self.parent.tabWidget.setEnabled(True)
                            return
                        shuomingfile.Tables[i].Rows.First.Select()  # 获取测试项章节号
                        #############################目前模板不用获取用例章节号暂时省去
                        # zhangjiehao = self.w.Selection.Bookmarks("\headinglevel"). \
                        #     Range.Paragraphs(1).Range.ListFormat.ListString  # 获取测试项章节名
                        ##############################################################
                        zhangjieming = self.w.Selection.Bookmarks("\headinglevel"). \
                            Range.Paragraphs(1).Range.Text.rstrip('\r')

                        yongli_dict['yongli_ming'] = yongliming
                        yongli_dict['yongli_biaoshi'] = biaoshi
                        data2['yongli_ming'] = yongliming
                        data2['yongli_biaoshi'] = biaoshi
                        data2['yongli_zongsu'] = zongsu
                        data2_list.append(data2)
                        print("当前yongli_dict为：", yongli_dict)
                        # 获取大纲的章节号和用例名，而且data按自己的来
                        ## 按python行进行分割为列表
                        zhui_list = zhui_temp.split("\r")
                        if len(zhui_list) == 3:
                            if zhui_list[1].find("需求") != -1:
                                #使用re模块正则表达式
                                match_string = re.search(
                                    "\d(.\d+)+", zhui_list[1]).group()
                                match_ming = zhui_list[1].split(
                                    match_string)[-1]
                                #使用re.sub模块替换为空
                                rules = "[)(）（] "
                                match_ming = re.sub(rules, '', match_ming)
                                if zhui_list[2]:
                                    rules = ":"
                                    dg_biaoshi_temp = re.sub(
                                        rules, '：', zhui_list[2])
                                    dg_biaoshi = dg_biaoshi_temp.split("：")[-1]
                                #判断是否是新的测试项，如果是新的索引index加1，创建新dict进入
                                if zhangjieming != csx_name:
                                    data_list.append(data)
                                    data_index = data['index'] + 1
                                    data = {
                                        'dg_zhangjie': '',
                                        'mingcheng': '',
                                        'biaoshi': '',
                                        'yongli': [],
                                        'index': data_index
                                    }
                                    data['dg_zhangjie'] = match_string
                                    data['mingcheng'] = match_ming
                                    data['biaoshi'] = dg_biaoshi
                                    data['yongli'].append(yongli_dict)
                                    csx_name = zhangjieming
                                    self.sin_out.emit("已处理第{}个测试项...".format(
                                        data['index']))
                                else:
                                    data['yongli'].append(yongli_dict)
                except:
                    self.sin_out.emit(
                        f'$$$$$$$$$$$$第{str(i+1)}个表格，获取单元格内容不存在$$$$$$$$$$$$')
                    pass

        # 最后关闭文档
        try:
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
        except:
            QMessageBox.warning(self.parent, "关闭文档失败", "关闭文档失败！")
            return

        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "说明追踪模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  # 模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        # 开始渲染模板文件
        try:
            context = {
                "tables": data_list,
                "tables2": data2_list,
            }
            tpl.render(context)
            tpl.save("说明追踪文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
#根据说明生成测试记录线程
##################################################################################
class create_jilu(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        #用来储存章节号转换
        zhuan_dict = {'DC':'文档审查','SU':'功能测试','CR':'代码审查','SA':'静态分析','AC':'性能测试',\
            'IO':'接口测试','SE':'安全性测试','BT':'边界测试','RE':'恢复性测试','ST':'强度测试',\
                'AT':'余量测试','GUI':'人机交互界面测试','DP':'数据处理测试','JR':'兼容性测试',\
                    'LG':'逻辑测试','AZ':'安装性测试','TT':'时序测试','PA':'功耗分析'}

        self.sin_out.emit("进入根据说明转换记录线程......")
        self.sin_out.emit("开始转换......")
        #如果没有选择文件则退出
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        pythoncom.CoInitialize()
        self.sin_out.emit('打开说明文档...')
        self.w = DispatchEx('Word.Application')
        self.w.DisplayAlerts = 0
        try:
            shuomingfile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return
        self.sin_out.emit('复制测试记录文档模板到本程序所在目录...')
        curpath = Path.cwd() / 'need'
        shuoming_path_tmp = curpath / 'document_templates' / '说明生成记录模板.docx'
        if shuoming_path_tmp.is_file():
            self.sin_out.emit('已检测到有记录模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return
        #创建一个字典来储存单个用例
        data_list = []
        #获取表格数量
        try:
            csx_tb_count = shuomingfile.Tables.Count
            self.sin_out.emit('total:' + str(csx_tb_count))
        except:
            self.sin_out.emit('不存在表格，请检查文档！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                shuomingfile.Close()
            except:
                pass
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        #用来储存章节号中的DC、SU等标识，用于章节号判断
        is_type_su = ""
        #储存章节号标志
        is_fire_su = ""
        for i in range(csx_tb_count):
            self.sin_out.emit(str(i))
            self.sin_out.emit("正在处理第{}个表格".format(i + 1))
            try:
                if shuomingfile.Tables[i].Rows.Count > 2:
                    if shuomingfile.Tables[i].Cell(
                            2, 1).Range.Text.find('测试用例名称') != -1:
                        #一个用例不变内容获取
                        try:
                            shuomingfile.Tables[i].Rows.First.Select()
                            #获取章节名，用于判断
                            zhangjieming = self.w.Selection.Bookmarks("\headinglevel").\
                                Range.Paragraphs(1).Range.Text.rstrip('\r')
                            #获取表格基本信息
                            mingcheng = shuomingfile.Tables[i].Cell(
                                2, 2).Range.Text[:-2]
                            biaoshi = shuomingfile.Tables[i].Cell(
                                2, 4).Range.Text[:-2]
                            self.sin_out.emit(f"正在处理{biaoshi}用例{mingcheng}")
                            zhuizong = shuomingfile.Tables[i].Cell(
                                3, 2).Range.Text[:-2]
                            zongsu = shuomingfile.Tables[i].Cell(
                                4, 2).Range.Text[:-2]
                            chushihua = shuomingfile.Tables[i].Cell(
                                5, 2).Range.Text[:-2]
                            qianti = shuomingfile.Tables[i].Cell(
                                6, 2).Range.Text[:-2]

                            #缓存一个data数据
                            data = {'mingcheng':'','biaoshi':'','zhuizong':'','is_first':'0',\
                                'zongsu':'','chushihua':'','qianti':'','zuhe':[],'is_begin':'0',\
                                    'csx_type':'','csx_name':''}
                            #获取步骤和预期
                            step_count = shuomingfile.Tables[i].Rows.Count - 11
                            for j in range(step_count):
                                buzhou_dict = {
                                    'buzhou': "",
                                    'yuqi': "",
                                    'xuhao': ''
                                }
                                buzhou_dict['buzhou'] = shuomingfile.Tables[
                                    i].Cell(j + 9, 2).Range.Text[:-2]
                                buzhou_dict['yuqi'] = shuomingfile.Tables[
                                    i].Cell(j + 9, 3).Range.Text[:-2]
                                buzhou_dict['xuhao'] = str(j + 1)
                                data['zuhe'].append(buzhou_dict)

                            #开始判断当前是否为测试项的第一个，如果是第一个则is_first改为1
                            if is_fire_su != zhangjieming:
                                is_fire_su = zhangjieming
                                data['is_first'] = '1'

                            #判断测试类型，这里从标识里面获取
                            biaoshi_list = biaoshi.split("_")
                            print('当前取的类型列表分割：', biaoshi_list)
                            if len(biaoshi_list) >= 4:
                                biaoshi_tmp = biaoshi_list[-3]
                            else:
                                biaoshi_tmp = biaoshi_list[1]
                            if biaoshi_tmp != is_type_su:
                                is_type_su = biaoshi_tmp
                                data['is_begin'] = '1'
                                if zhuan_dict[biaoshi_tmp] == '文档审查' or  zhuan_dict[biaoshi_tmp] == '代码审查' or \
                                    zhuan_dict[biaoshi_tmp] == '静态分析':
                                    data['is_first'] = '0'

                            #data补全
                            data['mingcheng'] = mingcheng
                            data['biaoshi'] = biaoshi
                            data['zhuizong'] = zhuizong.replace('\r', '\n')
                            data['zongsu'] = zongsu
                            data['chushihua'] = chushihua
                            data['qianti'] = qianti
                            data['csx_type'] = zhuan_dict[biaoshi_tmp]
                            data['csx_name'] = zhangjieming
                            data_list.append(data)
                            self.sin_out.emit("处理完毕{}用例".format(biaoshi))
                        except:
                            self.sin_out.emit(f'错误！第{i+1}个表格处理失败!')
            except:
                self.sin_out.emit(f'错误！第{i+1}个表格处理失败!')

        #关闭大纲文档（因为以及提取完毕）
        try:
            shuomingfile.Close()
            self.w.Quit()
            pythoncom.CoUninitialize()
        except:
            self.sin_out.emit('function fail')
            self.w.Quit()
            pythoncom.CoUninitialize()
            return

        #打开模板文件进行渲染，然后就是用docxtpl生成用例
        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "说明生成记录模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  #模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        #开始渲染模板文件-有2层循环
        try:
            context = {
                "tables": data_list,
                "cs_renyuan": self.parent.lineEdit_4.text(),
                "jc_renyuan": self.parent.lineEdit_5.text(),
                "shijian": self.parent.lineEdit_6.text(),
            }
            tpl.render(context)
            tpl.save("生成的测试记录文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
# 根据测试记录反向生成说明
##################################################################################
class create_shuomingfanxiang(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        # 用来储存测试项DC等转换
        zhuan_dict = {'DC':'文档审查','SU':'功能测试','CR':'代码审查','SA':'静态分析','AC':'性能测试',\
            'IO':'接口测试','SE':'安全性测试','BT':'边界测试','RE':'恢复性测试','ST':'强度测试',\
                'AT':'余量测试','GUI':'人机交互界面测试','DP':'数据处理测试','JR':'兼容性测试',\
                    'LG':'逻辑测试','AZ':'安装性测试','TT':'时序测试','PA':'功耗分析'}

        self.sin_out.emit("进入测试记录转说明......")
        self.sin_out.emit("开始转换......")
        # 如果没有选择文件路径则退出
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        pythoncom.CoInitialize()
        self.sin_out.emit('打开测试记录文件...')
        self.w = DispatchEx('Word.Application')
        #self.w.visible=True
        self.w.DisplayAlerts = 0
        try:
            jilufile = self.w.Documents.Open(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        self.sin_out.emit('复制测试说明文档模板到本程序所在目录...')
        curpath = Path.cwd() / 'need'
        shuoming_path_tmp = curpath / 'document_templates' / '反向测试说明模板.docx'
        print(shuoming_path_tmp)
        if shuoming_path_tmp.is_file():
            self.sin_out.emit('已检测到有说明模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return
        #创建一个字典来储存单个用例
        data_list = []
        #获取表格数量
        try:
            csx_tb_count = jilufile.Tables.Count
            self.sin_out.emit('total:' + str(csx_tb_count))
        except:
            self.sin_out.emit('不存在表格！')
            QMessageBox.warning(self.parent, '出错了', '测试说明文档格式错误或者没有正确表格')
            try:
                jilufile.Close()
            except:
                pass
            self.w.Quit()
            pythoncom.CoUninitialize()
            self.parent.tabWidget.setEnabled(True)
            return

        #初始化表格外全局变量
        is_fire_su = ''
        is_type_su = ''
        for i in range(csx_tb_count):
            self.sin_out.emit(str(i))
            self.sin_out.emit(f"正在处理第{str(i+1)}个表格")
            if jilufile.Tables[i].Rows.Count > 2:
                if jilufile.Tables[i].Cell(2,
                                           1).Range.Text.find('测试用例名称') != -1:
                    #将表格中信息全部先拿出来
                    try:
                        jilufile.Tables[i].Rows.First.Select()
                        zhangjieming = self.w.Selection.Bookmarks("\headinglevel").\
                            Range.Paragraphs(1).Range.Text.rstrip('\r')
                        zhangjiehao = self.w.Selection.Bookmarks("\headinglevel").\
                            Range.Paragraphs(1).Range.ListFormat.ListString
                        mingcheng = jilufile.Tables[i].Cell(2,
                                                            2).Range.Text[:-2]
                        biaoshi = jilufile.Tables[i].Cell(2, 4).Range.Text[:-2]
                        self.sin_out.emit(f"正在处理{biaoshi}-用例{mingcheng}")
                        zhuizong = jilufile.Tables[i].Cell(3,
                                                           2).Range.Text[:-2]
                        zongsu = jilufile.Tables[i].Cell(4, 2).Range.Text[:-2]
                        chushi = jilufile.Tables[i].Cell(5, 2).Range.Text[:-2]
                        qianti = jilufile.Tables[i].Cell(6, 2).Range.Text[:-2]

                        #缓存一个data数据
                        data = {'mingcheng':'','biaoshi':'','zhuizong':'','is_first':'0',\
                            'zongsu':'','chushi':'','qianti':'','zuhe':[],'is_begin':'0',\
                                'csx_type':'','csx_mingcheng':'','renyuan':''}
                        #获取步骤和预期
                        step_count = jilufile.Tables[i].Rows.Count - 12
                        #获取人员信息
                        data['renyuan'] = jilufile.Tables[i].Cell(
                            10 + step_count, 2).Range.Text[:-2]
                        for j in range(step_count):
                            buzhou_dict = {
                                'buzhou': "",
                                'yuqi': "",
                                'xuhao': ''
                            }
                            buzhou_dict['buzhou'] = jilufile.Tables[i].Cell(
                                j + 9, 2).Range.Text[:-2]
                            buzhou_dict['yuqi'] = jilufile.Tables[i].Cell(
                                j + 9, 3).Range.Text[:-2]
                            buzhou_dict['xuhao'] = str(j + 1)
                            data['zuhe'].append(buzhou_dict)

                        # 开始判断当前是否为测试项的第一个，如果是第一个则is_first改为1
                        if is_fire_su != zhangjieming:
                            is_fire_su = zhangjieming
                            data['is_first'] = '1'
                        # 判断测试类型，这里从标识里面获取
                        biaoshi_list = biaoshi.split("_")
                        print('当前取的类型列表分割：', biaoshi_list)
                        if len(biaoshi_list) >= 4:
                            biaoshi_tmp = biaoshi_list[-4]
                        else:
                            biaoshi_tmp = biaoshi_list[1]
                        if biaoshi_tmp != is_type_su:
                            is_type_su = biaoshi_tmp
                            data['is_begin'] = '1'
                            if zhuan_dict[biaoshi_tmp] == '文档审查' or  zhuan_dict[biaoshi_tmp] == '代码审查' or \
                                zhuan_dict[biaoshi_tmp] == '静态分析':
                                data['is_first'] = '0'

                        #data补全
                        data['mingcheng'] = mingcheng
                        data['biaoshi'] = biaoshi
                        data['zhuizong'] = zhuizong.replace('\r', '\n')
                        data['zongsu'] = zongsu
                        data['chushi'] = chushi
                        data['qianti'] = qianti
                        data['csx_type'] = zhuan_dict[biaoshi_tmp]
                        data['csx_mingcheng'] = zhangjieming
                        data_list.append(data)
                        self.sin_out.emit("处理完毕{}用例".format(biaoshi))
                    except:
                        self.sin_out.emit("第{}个表格处理失败，请检查".format(str(i + 1)))
                        pass

                else:
                    self.sin_out.emit(
                        "该表格生成错误，请检查是否存在用例序号，每个用例必须有序号且必须包含【记录】两个字...")
            else:
                self.sin_out.emit("该表格生成错误，请检查表格是否存在并大于2行...")

        #关闭大纲文档（因为以及提取完毕）
        try:
            jilufile.Close()
            self.w.Quit()
            pythoncom.CoUninitialize()
        except:
            self.sin_out.emit('function fail')
            self.w.Quit()
            pythoncom.CoUninitialize()
            return

        #打开模板文件进行渲染，然后就是用docxtpl生成用例
        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / "反向测试说明模板.docx"
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  #模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        #开始渲染模板文件-有2层循环
        try:
            context = {
                "tables": data_list,
            }
            tpl.render(context)
            tpl.save("反向生成的说明文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
#自动填充单元格线程
##################################################################################
class create_zidong(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit('开始...')
        if self.parent.open_file_name == '':
            self.sin_out.emit('请点击“选择文档”按钮选择要填充的文档')
            self.parent.tabWidget.setEnabled(True)
            QMessageBox.warning(self.parent, '出错了！', '请选择要填充的文档！')
            return
        try:
            t_s_file = docx.Document(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.parent.tabWidget.setEnabled(True)
            QMessageBox.warning(self.parent, '出错了！',
                                '打开选择的文档失败，请确认文档类型为docx，且未被打开！')
            return
        if self.parent.lineEdit_9.text() == '':
            self.sin_out.emit('单元格左侧不能为空！!!!')
            self.parent.tabWidget.setEnabled(True)
            QMessageBox.warning(self.parent, '出错了！', '单元格标题不能为空！')
            return
        if self.parent.lineEdit_10.text() == '':
            self.sin_out.emit('确定填充内容为空吗？填充内容为空相当于清空操作。可直接点击清空按钮！！')
            self.parent.tabWidget.setEnabled(True)
            QMessageBox.warning(self.parent, '警告！',
                                '确定填充内容为空吗？填充内容为空相当于清空操作。可点击清空按钮！！')
            return
        tmp_fill = self.parent.lineEdit_11.text()
        if tmp_fill == '':
            tmp_fill = str(len(t_s_file.tables))

        if (tmp_fill.strip().isdigit()) and (int(tmp_fill.strip()) < len(
                t_s_file.tables)):
            tmp_ran = int(tmp_fill)
        else:
            tmp_ran = len(t_s_file.tables)

        tmp_fillnum = 0
        k = 0

        self.sin_out.emit('total:' + str(tmp_ran))

        self.parent.progressBar.setRange(0, tmp_ran - 1)
        for ft1 in t_s_file.tables:
            k += 1
            self.sin_out.emit(str(k))
            self.parent.progressBar.setValue(k)
            tmp_row = 0
            for r in ft1.rows:
                tmpflag = 0
                tmp_column = 0
                for cell in r.cells:
                    if cell.text.strip() == self.parent.lineEdit_9.text():
                        while ft1.cell(tmp_row, tmp_column).text.strip(
                        ) == self.parent.lineEdit_9.text():
                            tmp_column += 1
                        #这里如果需要替换还是不替换
                        if ft1.cell(tmp_row, tmp_column).text == '':
                            ft1.cell(tmp_row, tmp_column
                                     ).text = self.parent.lineEdit_10.text()
                            tmp_fillnum += 1
                        else:
                            pass
                        tmpflag = 1
                        break
                    else:
                        tmp_column += 1
                if tmpflag == 1:
                    break
                tmp_row += 1
            if tmp_fillnum >= int(tmp_fill):
                break

        try:
            t_s_file.save(self.parent.open_file_name[0])
            self.sin_out.emit('function success')
            self.parent.tabWidget.setEnabled(True)
            return
        except:
            self.parent.tabWidget.setEnabled(True)
            self.sin_out.emit('function fail')
            QMessageBox.information(self.parent, '', '填充完成！')
            return


##################################################################################
#清空单元格线程
##################################################################################
class clear_cell(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit('开始...')
        if self.parent.open_file_name == '':
            self.sin_out.emit('请点击“选择文档”按钮选择要填充的文档')
            self.parent.tabWidget.setEnabled(True)
            QMessageBox.warning(self.parent, '出错了！', '请选择要填充的文档！')
            return
        try:
            t_s_file = docx.Document(self.parent.open_file_name[0])
        except:
            self.sin_out.emit('open failed:要填充的文档')
            QMessageBox.warning(self.parent, '出错了！',
                                '打开选择的文档失败，请确认文档类型为docx，且未被打开！')
            self.parent.tabWidget.setEnabled(True)
            return
        if self.parent.lineEdit_9.text() == '':
            self.parent.tabWidget.setEnabled(True)
            self.sin_out.emit('单元格标题不能为空！')
            QMessageBox.warning(self.parent, '出错了！', '单元格标题不能为空！')
            return
        tmp_tblcnt = len(t_s_file.tables)
        k = 0
        self.sin_out.emit('total:' + str(tmp_tblcnt))
        for ft1 in t_s_file.tables:
            k += 1
            self.sin_out.emit(str(k))
            tmp_row = 0
            for r in ft1.rows:
                tmpflag = 0
                tmp_column = 0
                for cell in r.cells:

                    if cell.text.strip() == self.parent.lineEdit_9.text():
                        while ft1.cell(tmp_row, tmp_column).text.strip(
                        ) == self.parent.lineEdit_9.text():
                            tmp_column += 1

                        ft1.cell(tmp_row, tmp_column).text = ''
                        tmpflag = 1
                        break
                    else:
                        tmp_column += 1
                if tmpflag == 1:
                    break
                tmp_row += 1
        try:
            t_s_file.save(self.parent.open_file_name[0])
            self.sin_out.emit('function success')
            self.parent.tabWidget.setEnabled(True)
            return
        except:
            self.parent.tabWidget.setEnabled(True)
            self.sin_out.emit('function fail')
            QMessageBox.information(self.parent, '', '清空单元格成功！')
            return


##################################################################################
#提取表格内容线程
##################################################################################
class get_content(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    #获取文档中表格内容函数
    def run(self):
        curpath = Path.cwd()
        content_tmp = curpath / 'need' / 'document_templates' / 'get_content.docx'
        shutil.copy(content_tmp, curpath)
        content_tmp_path = curpath / 'get_content.docx'
        print(content_tmp_path)
        try:
            #c_file = self.w.Documents.Add()
            c_file = docx.Document(content_tmp_path)
        except:
            self.sin_out.emit('open failed:文档模板')
            self.parent.tabWidget.setEnabled(True)
            return

        try:
            s_file = docx.Document(self.parent.open_file_name[0])
            s_tbls = s_file.tables
        except:
            self.sin_out.emit('open failed:选择的文档')
            c_file.save(content_tmp_path)
            self.parent.tabWidget.setEnabled(True)
            return
        #原来是5,6,7
        if self.parent.lineEdit_12.text(
        ) == '' and self.parent.lineEdit_13.text(
        ) == '' and self.parent.lineEdit_14.text() == '':

            self.sin_out.emit(
                'warning:请至少填写一个要提取的内容的标题，\n标题为要提取的单元格的前一单元格中的内容!')
            c_file.save(content_tmp_path)
            s_file.save(self.parent.open_file_name[0])
            self.parent.tabWidget.setEnabled(True)
            return

        line_list = [
            self.parent.lineEdit_12.text(),
            self.parent.lineEdit_13.text(),
            self.parent.lineEdit_14.text()
        ]
        self.sin_out.emit('开始提取...')
        rownum = 0
        self.sin_out.emit('total:' + str(len(s_tbls)))
        for stb in s_tbls:
            c_file.tables[0].add_row()
            rownum += 1
            self.sin_out.emit(str(rownum))

            row = 0
            for r1 in stb.rows:
                col = 0
                for ce in r1.cells:
                    if line_list[0] != '' and ce.text == line_list[0]:
                        while stb.cell(row, col).text == line_list[0]:
                            col += 1
                        c_file.tables[0].cell(rownum,
                                              0).text = stb.cell(row, col).text
                        break
                    col += 1
                col = 0
                for ce in r1.cells:
                    if line_list[1] != '' and ce.text == line_list[1]:
                        while stb.cell(row, col).text == line_list[1]:
                            col += 1
                        c_file.tables[0].cell(rownum,
                                              1).text = stb.cell(row, col).text
                        break
                    col += 1
                col = 0
                for ce in r1.cells:
                    if line_list[2] != '' and ce.text == line_list[2]:
                        while stb.cell(row, col).text == line_list[2]:
                            col += 1
                        c_file.tables[0].cell(rownum,
                                              2).text = stb.cell(row, col).text
                        break
                    col += 1
                row += 1
        try:
            c_file.save(content_tmp_path)
            s_file.save(self.parent.open_file_name[0])
            self.sin_out.emit('function success')
            self.sin_out.emit('生成文件名为(get_content.docx)，在根目录下查看')
            self.parent.tabWidget.setEnabled(True)
            return
        except:
            self.sin_out.emit('function fail')
            self.parent.tabWidget.setEnabled(True)
            return


##################################################################################
#测评报告追溯表
##################################################################################
class create_baogao_zhuisu(QtCore.QThread):
    sin_out = pyqtSignal(str)

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        self.sin_out.emit("进入报告追溯线程......")
        self.sin_out.emit("开始填写报告追溯表......")

        # 如果没有选择文件
        if not self.parent.open_file_name:
            self.sin_out.emit('nofile')
            self.parent.tabWidget.setEnabled(True)
            return
        self.sin_out.emit('打开测试记录文档...')
        # 打开word应用
        try:
            doc_path = self.parent.open_file_name[0]
            doc = Document(doc_path)
        except:
            self.sin_out.emit('open failed:选择的文档')
            self.parent.tabWidget.setEnabled(True)
            return

        self.sin_out.emit('已正确打开说明文档...')
        curpath = Path.cwd() / 'need'
        zhuisu_path_tmp = curpath / 'document_templates' / '报告追踪模板.docx'
        if zhuisu_path_tmp.is_file():
            self.sin_out.emit('已检测到有报告追溯模板文件...')
        else:
            self.sin_out.emit('open failed:选择的文档')
            return

        # 创建个列表放数据
        data_list = []
        # 由于docx的是列表，所以直接len函数统计count
        count = len(doc.tables)
        self.sin_out.emit('total:' + str(count))
        k = 0
        for tb in doc.tables:
            k += 1
            self.sin_out.emit('total:' + str(k))
            #注意docx处理方式不一样从0开始，并且要算总行数
            try:
                if tb.cell(1, 1).text.find('测试用例名称') != -1:
                    data = {
                        'yongli_ming': '',
                        'yongli_biaoshi': '',
                        'yongli_qingkuang': '',
                        'beizhu': ''
                    }
                    data['yongli_ming'] = tb.cell(1, 4).text
                    data['yongli_biaoshi'] = tb.cell(1, 8).text
                    wenti = tb.rows[-2].cells[2]
                    print('提取出来的信息：', wenti.text)
                    if wenti.text == '/' or wenti.text == '':
                        data['yongli_qingkuang'] = '通过'
                        data['beizhu'] = '/'
                    else:
                        data['yongli_qingkuang'] = '不通过'
                        data['beizhu'] = wenti.text
                    self.sin_out.emit(f'处理完毕({tb.cell(1,8).text})用例..')
                    data_list.append(data)
                else:
                    self.sin_out.emit(f'当前表格({tb.cell(1,8).text})用例无法识别请检查')
            except:
                self.sin_out.emit(f'处理第{k}个表格失败，请检查该表格...')
                pass

        try:
            tpl_path = Path.cwd(
            ) / "need" / "document_templates" / '报告追踪模板.docx'
            self.sin_out.emit('导入模板文件路径为：' + str(tpl_path))
            tpl = DocxTemplate(tpl_path)  # 模板导入成功

        except:
            QMessageBox.warning(self.parent, "出错了", "导入模板出错请检查模板文件是否存在或名字不正确")
            return

        # 开始渲染模板文件
        print(data_list)
        try:
            context = {
                "tables": data_list,
            }
            tpl.render(context)
            tpl.save("说明追踪文档.docx")
            self.sin_out.emit('stopsuccess')
        except:
            self.sin_out.emit('stoperror')
            return


##################################################################################
##
##################################################################################
