"""Word 文档解析引擎""" from docx import Document from docx.paragraph import Paragraph from docx.table import Table as DocxTable from typing import List, Dict, Any def parse_document(file_path: str) -> List[Dict[str, Any]]: """ 解析 Word 文档,返回 block 列表(不含表格数据,仅标记位置)。 每个 block 包含:type, text, level, style """ doc = Document(file_path) blocks = [] for para in doc.paragraphs: block = classify_paragraph(para) if block: blocks.append(block) return blocks def classify_paragraph(para: Paragraph) -> Dict[str, Any] | None: """识别段落类型""" text = para.text.strip() style_name = para.style.name if para.style else "" if not text and "Heading" not in style_name: return None # 跳过空段落 if "Heading" in style_name: level = int(style_name.replace("Heading", "").strip()) if style_name.replace("Heading", "").strip().isdigit() else 1 return {"type": "heading", "text": text, "level": level, "style": style_name} else: return {"type": "paragraph", "text": text, "level": 0, "style": style_name} def parse_tables(doc: Document) -> List[Dict[str, Any]]: """解析 Word 表格""" tables = [] for i, table in enumerate(doc.tables): headers = [cell.text.strip() for cell in table.rows[0].cells] if table.rows else [] tables.append({ "type": "table", "text": " | ".join(headers), "level": 0, "rows": len(table.rows), "cols": len(table.columns), "headers": headers, "table_index": i, }) return tables def generate_block_id(index: int) -> str: """生成 block_id,格式:block_001""" return f"block_{index:03d}" def build_tree(blocks: List[Dict]) -> Dict: """构建层级树结构""" tree = [] stack = [] # 存父级节点 for block in blocks: node = {"block_id": block["block_id"], "text": block["text"][:50], "children": []} level = block.get("level", 0) # 回退栈 while stack and stack[-1]["level"] >= level: stack.pop() if stack: parent = stack[-1]["node"] parent["children"].append(node) block["parent_block_id"] = parent["block_id"] else: tree.append(node) block["parent_block_id"] = None # 非叶子节点入栈 if level < 2 or block["type"] == "heading": stack.append({"level": level, "node": node}) return {"blocks": tree}