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

使用python-docx拆分Word文档时图片无法正常显示的问题

问题原因与解决方案

问题根源

你直接将原文档的XML元素(element)追加到新文档的body中,仅复制了图片的占位符结构,未同步复制图片的实际二进制数据。Word文档的图片存储在独立的媒体部件(Parts)中,XML元素通过rId引用这些部件;新文档没有对应的媒体部件,因此无法加载图片,显示“Can't display drawing”。

修复方案

不能直接操作底层XML元素进行迁移,必须同步复制图片的媒体部件,并更新引用ID(rId)。以下是修改后的核心逻辑:

替换原元素追加逻辑

删除原代码中elements_to_save.append(element)的逻辑,改用高层API+部件复制的方式迁移内容,确保图片资源被正确拷贝:

# 初始化新文档时保留这行
doc2 = docx.Document()

# 遍历原文档内容块时,替换原有的元素处理逻辑
for block in doc.element.body:
    if isinstance(block, CT_Tbl):
        table = Table(block, doc)
        # 创建新表格并复制结构
        new_table = doc2.add_table(rows=len(table.rows), cols=len(table.columns))
        # 复制单元格内容(含图片)
        for i, row in enumerate(table.rows):
            for j, cell in enumerate(row.cells):
                new_cell = new_table.cell(i, j)
                # 复制单元格内的所有段落
                for p in cell.paragraphs:
                    new_p = new_cell.add_paragraph()
                    for run in p.runs:
                        new_run = new_p.add_run(run.text)
                        # 复制文字格式
                        new_run.bold = run.bold
                        new_run.italic = run.italic
                        new_run.font.size = run.font.size
                        # 处理run内的嵌入式图片
                        for inline_shape in run._element.xpath('.//pic:pic'):
                            # 获取原文档中图片的引用ID
                            rId = inline_shape.xpath('.//a:blip/@r:embed')[0]
                            # 从原文档获取图片部件
                            image_part = doc.part.related_parts[rId]
                            # 在新文档中添加图片部件,生成新的引用ID
                            new_rId = doc2.part.relate_to(
                                image_part.target_ref,
                                image_part.reltype,
                                is_external=False
                            )
                            # 更新图片元素的引用ID为新文档的ID
                            inline_shape.xpath('.//a:blip')[0].set('r:embed', new_rId)
                            # 将处理后的图片元素添加到新run中
                            new_run._element.append(inline_shape)
        
        # --- 保留你原有的表格拆分、目录创建等业务逻辑 ---
        # (即原代码中if isinstance(element, CT_Tbl):下的业务代码,除了elements_to_save相关部分)

    elif isinstance(block, CT_P):
        p = Paragraph(block, doc)
        new_p = doc2.add_paragraph()
        for run in p.runs:
            new_run = new_p.add_run(run.text)
            # 复制文字格式
            new_run.bold = run.bold
            new_run.italic = run.italic
            new_run.font.size = run.font.size
            # 处理run内的嵌入式图片
            for inline_shape in run._element.xpath('.//pic:pic'):
                rId = inline_shape.xpath('.//a:blip/@r:embed')[0]
                image_part = doc.part.related_parts[rId]
                new_rId = doc2.part.relate_to(
                    image_part.target_ref,
                    image_part.reltype,
                    is_external=False
                )
                inline_shape.xpath('.//a:blip')[0].set('r:embed', new_rId)
                new_run._element.append(inline_shape)
        
        # --- 保留你原有的段落提取编号等业务逻辑 ---
        # (即原代码中if isinstance(element, CT_P):下的业务代码)

# 当需要保存文档时,直接保存doc2即可(无需elements_to_save的循环)
doc2.save(f'{pv_dir_path}/{doc_name_unique}.docx')

关键说明

  1. 媒体部件复制:通过doc.part.related_parts[rId]获取原图片的二进制部件,再用doc2.part.relate_to()将其添加到新文档,生成新的rId。
  2. 引用更新:将图片XML元素中的r:embed属性替换为新文档的rId,确保新文档能找到对应的图片资源。
  3. 格式同步:复制段落、run的格式(加粗、斜体等),保证拆分后的文档与原格式一致。

浮动图片处理(可选)

如果原文档包含浮动图片(非嵌入式),需额外处理wp:anchor元素,逻辑与嵌入式图片一致:

# 在处理run的元素时,添加浮动图片的处理
for anchor in run._element.xpath('.//wp:anchor'):
    rId = anchor.xpath('.//a:blip/@r:embed')[0]
    image_part = doc.part.related_parts[rId]
    new_rId = doc2.part.relate_to(image_part.target_ref, image_part.reltype, is_external=False)
    anchor.xpath('.//a:blip')[0].set('r:embed', new_rId)
    new_run._element.append(anchor)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 06:30:55