"""DOCX 解析器(python-docx fallback)。""" from app.core.logging import get_logger logger = get_logger(__name__) def parse_docx_with_python_docx(file_content: bytes) -> str | None: """用 python-docx 解析 DOCX,返回 Markdown 或 None(失败时)。""" try: import io from docx import Document doc = Document(io.BytesIO(file_content)) md_parts = [] for para in doc.paragraphs: text = para.text.strip() if not text: continue style = para.style.name.lower() if style.startswith("heading 1"): md_parts.append(f"# {text}") elif style.startswith("heading 2"): md_parts.append(f"## {text}") elif style.startswith("heading 3"): md_parts.append(f"### {text}") elif style.startswith("heading"): md_parts.append(f"#### {text}") elif style.startswith("list"): md_parts.append(f"- {text}") else: md_parts.append(text) # 处理表格 for table in doc.tables: rows = [] for row in table.rows: cells = [cell.text.strip() for cell in row.cells] rows.append("| " + " | ".join(cells) + " |") if rows: # 添加表头分隔行 if len(rows) > 1: sep = "| " + " | ".join(["---"] * len(table.columns)) + " |" rows.insert(1, sep) md_parts.append("\n".join(rows)) markdown = "\n\n".join(md_parts) return markdown if markdown.strip() else None except Exception as e: logger.warning("python-docx 解析失败: %s", e) return None