用 Python 提取 Word 文本框中的文字、表格和图片

Evan
Evan
发布时间:2026-08-23 | 69人浏览过
原创

前言

Word 文档里的文本框经常承载说明文字、表格和配图,但它们不属于正文主流程,批量处理时最容易被漏掉。本文按“先识别对象入口,再分别提取文字、表格和图片”的思路重组示例代码,并补充适用场景和易错点,帮助你判断该用通用遍历、直接读表格,还是递归处理嵌套文本框。

Word 文档里的文本框经常用来承载独立说明、表格和配图,但它们并不在正文段落流里,做迁移、归档或批处理时很容易被漏掉。要把这些内容完整取出,关键不在字符串查找,而在按文档对象模型逐层遍历:先定位文本框,再根据子对象类型分别处理段落、表格和图片,必要时继续递归到更深层级。

为什么文本框内容不能按正文方式直接读取

在 Word 的对象模型里,文本框对应的是 TextBox 对象。它内部通过 Body 暴露内容,结构和文档主体相似,但不属于主段落流,因此常规的正文遍历未必能覆盖到这里。

这也是很多脚本“能读正文、读不到文本框”的原因。只要把遍历入口切换到 document.TextBoxes,再往下访问 Body.ChildObjects 或 Body.Tables,就能把文本框里的段落、表格乃至图片逐一取出。

先准备环境:安装 Spire.Doc for Python

本文使用的库是 Spire.Doc for Python。它提供了较完整的文档对象模型,适合按对象类型拆分处理文本框中的不同内容。

pip install Spire.Doc

导入模块后即可开始读取文档:

from spire.doc import *
from spire.doc.common import *

遍历文本框,提取段落和表格文字

如果你的目标是“尽可能完整地拿到文本框里的文字”,通用做法是遍历每个文本框的 Body.ChildObjects。遇到 Paragraph 就直接读 Text;遇到 Table,再按“行 → 单元格 → 段落”的层次继续展开。

展示从 Word 文档到文本框、段落、表格与图片对象的提取路径关系图
文本框内容的对象层级用对象层级梳理文本框内容提取的通用入口,适合解释为什么不能直接按正文读取。
from spire.doc import *
from spire.doc.common import *

inputFile = "/文本框.docx"
outputFile = "ExtractedText.txt"

# 加载文档
document = Document()
document.LoadFromFile(inputFile)

# 检查文档中是否包含文本框
if document.TextBoxes.Count > 0:
    with open(outputFile, 'w', encoding='utf-8') as sw:
        for i in range(document.TextBoxes.Count):
            textbox = document.TextBoxes.get_Item(i)
            # 遍历文本框内的子对象
            for j in range(textbox.Body.ChildObjects.Count):
                obj = textbox.Body.ChildObjects.get_Item(j)
                # 提取段落文字
                if obj.DocumentObjectType == DocumentObjectType.Paragraph:
                    para = obj if isinstance(obj, Paragraph) else None
                    sw.write(para.Text + "n")
                # 提取表格中的文字
                if obj.DocumentObjectType == DocumentObjectType.Table:
                    table = obj if isinstance(obj, Table) else None
                    for row_idx in range(table.Rows.Count):
                        row = table.Rows[row_idx]
                        for cell_idx in range(row.Cells.Count):
                            cell = row.Cells[cell_idx]
                            for para_idx in range(cell.Paragraphs.Count):
                                para = cell.Paragraphs.get_Item(para_idx)
                                sw.write(para.Text + "t")
                        sw.write("n")

document.Close()

这段代码的核心价值在于覆盖面足够广。先通过 document.TextBoxes 拿到文档中的全部文本框,再逐个访问其内部子对象;这样即使文本框里混合了普通段落和表格,也能一次性处理。

段落和表格为什么要分开处理

因为二者的结构不同。段落只需要读取 Text 属性,而表格是多层嵌套结构,必须继续遍历行、单元格和单元格中的段落,才能把内容完整展开。

示例里同一行的单元格内容用 t 分隔,不同行用 n 分隔。按原文代码保留了这种写法;如果你是要生成真正的制表符和换行,通常会改成 "\t" 和 "\n"。

已知文本框里是表格时,直接走 Body.Tables

如果你已经确定目标文本框中存放的是表格,而且位置固定,那么可以不遍历 ChildObjects,而是直接访问 Body.Tables。这种写法更短,也更适合结构明确的模板文档。

from spire.doc import *
from spire.doc.common import *

inputFile = "./Data/TextBoxTable.docx"
outputFile = "TableFromTextBox.txt"

# 加载文档
doc = Document()
doc.LoadFromFile(inputFile)

# 获取第一个文本框
textbox = doc.TextBoxes[0]

# 获取文本框中的第一个表格
table = textbox.Body.Tables[0] if isinstance(textbox.Body.Tables[0], Table) else None

result = ""
for i in range(table.Rows.Count):
    row = table.Rows.get_Item(i)
    for j in range(row.Cells.Count):
        cell = row.Cells.get_Item(j)
        for k in range(cell.Paragraphs.Count):
            paragraph = cell.Paragraphs.get_Item(k)
            result += paragraph.Text + "t"
    result += "n"

with open(outputFile, 'w', encoding='utf-8') as fp:
    fp.write(result)

doc.Close()

和前一种通用遍历相比,这种方式依赖更强的前提:你知道要读的是哪个文本框、哪个表格。但在标准化表单、固定版式报表这类场景里,它往往更省事。

什么场景适合直接读取表格

典型情况包括:文档模板固定、文本框数量少、目标表格位置恒定,或者你只关心一个指定文本框中的表格数据。此时直接访问 doc.TextBoxes[0] 和 textbox.Body.Tables[0],可以减少无关遍历。

提取文本框中的图片

文本框中的图片由 DocPicture 对象表示,图片字节数据保存在 ImageBytes 属性中。需要注意的是,图片往往不是直接挂在文本框根层,而是嵌套在段落的子对象里,因此通常要先遍历段落,再检查段落内部的 ChildObjects。

展示文本框图片提取时段落内嵌图片的查找与保存流程图
图片提取的实际遍历路径图片通常嵌在段落子对象中,提取时要先过段落层,再判断 `Picture` 类型并写出字节流。
from spire.doc import *
from spire.doc.common import *
import os

inputFile = "./Data/TextBoxWithImages.docx"
outputDir = "ExtractedImages/"

if not os.path.exists(outputDir):
    os.makedirs(outputDir)

# 加载文档
document = Document()
document.LoadFromFile(inputFile)

image_index = 0

# 遍历所有文本框
for i in range(document.TextBoxes.Count):
    textbox = document.TextBoxes.get_Item(i)
    # 遍历文本框中的子对象
    for j in range(textbox.Body.ChildObjects.Count):
        obj = textbox.Body.ChildObjects.get_Item(j)
        # 检查是否为段落,图片通常嵌套在段落中
        if obj.DocumentObjectType == DocumentObjectType.Paragraph:
            para = obj if isinstance(obj, Paragraph) else None
            for k in range(para.ChildObjects.Count):
                child = para.ChildObjects.get_Item(k)
                if child.DocumentObjectType == DocumentObjectType.Picture:
                    picture = child if isinstance(child, DocPicture) else None
                    # 获取图片二进制数据并保存
                    image_bytes = picture.ImageBytes
                    image_path = os.path.join(outputDir, f"Image-{image_index}.png")
                    with open(image_path, 'wb') as img_file:
                        img_file.write(image_bytes)
                    image_index += 1
                    print(f"已保存图片: {image_path}")

document.Close()

这段脚本会遍历所有文本框,并在每个段落内部查找 Picture 类型对象。找到后,通过 ImageBytes 取出原始字节流,再写入本地文件。示例里统一保存为 Image-{image_index}.png,可以避免文件重名。

保存图片时要注意什么

ImageBytes 返回的是原始图片字节数据。示例代码默认按 PNG 扩展名输出;如果原始内容来自 JPEG 或其他格式,你可以根据实际需求调整扩展名和命名规则。

实际处理时的三个细节

文字和图片混排,最好一次遍历完成

很多文档里的文本框并不是只放一种内容,而是段落、表格、图片混合出现。更稳妥的做法,是在同一轮遍历中同时处理文本和图片:发现段落就提取文字,同时继续检查段落内部是否有图片对象。这样可以减少重复扫描。

展示文本框内容抽取时通用遍历、直接表格读取与递归处理的适用场景对比图
三种处理策略如何选把三类常见处理策略放在一张图里,便于判断不同文档结构该选哪种写法。

遇到嵌套文本框,要递归处理

Word 支持文本框嵌套,也就是一个文本框里还可能包含另一个 TextBox。如果子对象中出现 DocumentObjectType.TextBox,就需要继续对它的 Body 进行递归遍历,否则深层内容会被漏掉。

统一编码和换行,避免后处理出错

文本输出建议统一使用 encoding='utf-8',以避免中文乱码。换行符方面,Windows 常见的是 \r\n,Linux 和 macOS 通常使用 \n;如果提取结果还要导入别的系统,最好提前统一格式。

总结:按对象模型遍历,才能完整拿到文本框内容

处理 Word 文本框的关键,在于不要把它当成普通正文,而要通过 TextBox、Body.ChildObjects、Body.Tables 和 DocPicture 这些对象入口来读。通用遍历适合混合内容和不确定结构的文档;直接读 Body.Tables 适合模板固定的场景;图片提取则要重点关注段落内的 Picture 子对象。

把这套思路理顺后,文本框里的文字、表格和图片都可以纳入自动化处理流程,适用于文档归档、批量迁移、内容分析以及结构化抽取等任务。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表