You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python区分Word文档中的项目符号列表与编号列表?

Python-docx区分项目符号和编号列表的解决办法

问题核心

你的源文档里,编号和项目符号列表的段落样式全是List Paragraph,靠样式名根本分不出来;而且原代码还犯了低级错误——new_paragraph没定义就直接用,判断逻辑完全走不通,自然复制后格式乱套。

解决思路

别盯着段落样式名看,直接去读段落的列表编号底层属性(也就是Word XML里的numPr节点),通过这个节点就能区分是编号还是项目符号。

修正后的完整代码

import docx
from docx.oxml.ns import qn

my_doc = docx.Document()
source_doc = docx.Document('source.docx')

for para in source_doc.paragraphs:
    # 先复制段落文本和基础样式
    new_para = my_doc.add_paragraph(para.text, style=para.style)
    
    # 复制字符级格式(比如加粗、字体、颜色这些)
    for run, new_run in zip(para.runs, new_para.runs):
        new_run.bold = run.bold
        new_run.italic = run.italic
        new_run.underline = run.underline
        new_run.font.name = run.font.name
        new_run.font.size = run.font.size
        new_run.font.color.rgb = run.font.color.rgb
    
    # 检查当前段落是不是列表项
    num_pr = para._element.numPr
    if num_pr is not None:
        # 获取列表的编号ID和级别
        num_id = num_pr.numId.val
        ilvl = num_pr.ilvl.val if hasattr(num_pr, 'ilvl') else 0
        
        # 找到源文档对应的列表定义
        num_def = source_doc.part.numbering_definitions._numbering.find(qn(f'w:num[@w:numId="{num_id}"]'))
        if num_def is not None:
            abstract_num_id = num_def.abstractNumId.val
            abstract_num = source_doc.part.numbering_definitions._numbering.find(qn(f'w:abstractNum[@w:abstractNumId="{abstract_num_id}"]'))
            if abstract_num is not None:
                lvl = abstract_num.find(qn(f'w:lvl[@w:ilvl="{ilvl}"]'))
                if lvl is not None:
                    # 判断是项目符号还是编号
                    is_bullet = lvl.find(qn('w:bullet')) is not None
                    is_number = lvl.find(qn('w:numFmt')) is not None
                    
                    if is_bullet:
                        new_para.style = my_doc.styles['List Bullet']
                    elif is_number:
                        new_para.style = my_doc.styles['List Number']

关键点说明

  • 直接操作Word的XML底层节点numPr,这才是存储列表类型的真实地方,比表面的样式名靠谱
  • 通过w:bullet节点判断项目符号,w:numFmt节点判断编号列表
  • 顺便补上了字符格式的复制,确保复制的内容和源文档完全一致
  • 修复了原代码里new_paragraph未定义的致命错误

内容的提问来源于stack exchange,提问作者Jasleen Kaur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 06:50:25