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,再按“行 → 单元格 → 段落”的层次继续展开。

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。

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









