from docx import Document from docxtpl import DocxTemplate from stuctor.constants import PREFIX from docx.oxml.text.paragraph import CT_P from docx.table import Table from stuctor.item import TitleItem, TableItemList, Item from nicegui import ui from pathlib import Path template_path = Path.cwd() / "templates" class Operator: """ 参数1: 传入被解析文档名称,不加.docx 参数2: 传入说明模版文档名称,不加.docx 参数3: 传入记录模版文档名称,不加.docx 属性1: item_list - 储存所有Item对象的列表 """ # 标题过滤 TITLE_LIST = ['3', '30', '4', '40', '5', '50', '6', '60', '7', '70'] BASIC_CAPTER = '6.2' def __init__(self, doc_name: str, tp_shuoming_name: str, tp_jilu_name: str, logger: ui.log) -> None: # 记录器 self.logger = logger # 被解析文档对象 self.doc = Document(doc_name) # 说明模版文件 self.tp_shuom = DocxTemplate(template_path / (tp_shuoming_name+'.docx')) # 记录模版文件 self.tp_jilu = DocxTemplate(template_path / (tp_jilu_name+'.docx')) # 储存所有item对象的列表 self.item_list: list[Item] = [] # 储存大纲章节号排布 self.c3 = 0 self.c4 = 0 self.c5 = 0 self.c6 = 0 self.c7 = 0 self.last_title_item = None def main_parse(self, parse_content_strategy: str = 'FPGA'): """默认是未解析的,调用该函数开始解析""" # 解析开始-这里有点耦合了,其实该请TitleItem对象去处理的 for ele in self.doc._element.body.iter(): # type: ignore if ele.tag.endswith('}p'): for child in ele.iter(): if child.tag.endswith("pStyle"): rank = child.get(f"{PREFIX}val") title = self.__parse_ele_title(ele) # 标题只有30,40,5,6 if rank in self.TITLE_LIST: current_title_item = TitleItem(rank, title) self.item_list.append(current_title_item) # 解析当前章节号 self.__parse_current_capter(current_title_item) elif ele.tag.endswith('}tbl'): table = Table(ele, self.doc) if table.cell(0, 0).text == "测试项名称": self.item_list.append(TableItemList(table, self.last_title_item, self.logger, parse_content_strategy)) # 私有:解析标题文字 def __parse_ele_title(self, ele: CT_P): t_ele = ele.findall(f".//{PREFIX}t") # type: ignore title = '' for i in range(len(t_ele)): if not t_ele[i].text.isdigit(): title = title + t_ele[i].text return title # 私有:解析当前章节号-根据其rank def __parse_current_capter(self, current_title_item: TitleItem): rank = current_title_item.type if rank == '30' or rank == '3': self.c3 += 1 self.c4 = 0 self.c5 = 0 self.c6 = 0 self.c7 = 0 current_title_item.capter = ".".join([self.BASIC_CAPTER, str(self.c3)]) elif rank == '40' or rank == '4': self.c4 += 1 self.c5 = 0 self.c6 = 0 self.c7 = 0 current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4)]) elif rank == '50' or rank == '5': self.c5 += 1 self.c6 = 0 self.c7 = 0 current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c5)]) elif rank == '60' or rank == '6': self.c6 += 1 self.c7 = 0 current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c6)]) elif rank == '70' or rank == '7': self.c7 += 1 current_title_item.capter = '.'.join([self.BASIC_CAPTER, str(self.c3), str(self.c4), str(self.c6), str(self.c7)]) self.last_title_item = current_title_item # 最后渲染 def render(self): context = self.__create_context() self.tp_shuom.render(context, autoescape = True) self.tp_shuom.save("测试说明-输出.docx") self.tp_jilu.render(context, autoescape = True) self.tp_jilu.save("测试记录-输出.docx") # 构造context def __create_context(self): data_list = [] for item in self.item_list: if isinstance(item, TableItemList): for it in item.table_item: temp_item = { 'type': 'table', 'name': it.name, 'ident': it.ident, 'zhui': item.zhui, 'zong': it.zong, 'step': it.step, 'csh': it.csh } data_list.append(temp_item) elif isinstance(item, TitleItem): data_list.append({'type': item.type, 'title': item.title}) return {"datas": data_list}