使用 Python 提取 Word 文档中的表格数据

Word 文档中的表格经常用于保存统计数据、项目清单、检测记录和业务报表。如果只是偶尔处理一两个文件,可以直接复制表格内容;但当文档包含多个表格,或者需要批量提取大量 Word 文件中的数据时,手动操作就比较低效。

通过 Python,可以按照文档、节、表格、行和单元格的层级读取 Word 表格,并将提取的数据继续用于统计分析、数据库导入,或者保存为 CSV 等结构化文件。

本文介绍如何使用 Python 读取 Word 表格数据、提取文档中的所有表格,以及批量处理多个 Word 文件。

环境设置

要运行下面的代码示例,需要先安装 Word 处理所需的 Python 模块:

bash 复制代码
pip install Spire.Doc

使用 Python 读取 Word 表格数据

如果只需要读取文档中的某一个表格,可以先获取表格对象,再依次遍历其中的行和单元格。

下面的示例读取 Word 文档第一个节中的第一个表格,并将表格内容保存到二维列表中:

python 复制代码
from spire.doc import *
from spire.doc.common import *

input_file = "input.docx"

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

# 获取第一个节
section = document.Sections.get_Item(0)

# 获取第一个表格
table = section.Tables.get_Item(0)

table_data = []

# 遍历表格中的行
for r in range(table.Rows.Count):
    row = table.Rows.get_Item(r)
    row_data = []

    # 遍历当前行中的单元格
    for c in range(row.Cells.Count):
        cell = row.Cells.get_Item(c)

        # 一个单元格中可能包含多个段落
        paragraphs = []

        for p in range(cell.Paragraphs.Count):
            text = cell.Paragraphs.get_Item(p).Text.strip()

            if text:
                paragraphs.append(text)

        # 合并单元格中的段落文本
        row_data.append(" ".join(paragraphs))

    table_data.append(row_data)

# 输出表格数据
for row in table_data:
    print(row)

document.Close()

Word 单元格中并不一定只有一段文字,因此代码没有直接读取某一个段落,而是遍历 cell.Paragraphs,再将同一单元格中的多个段落合并。

提取完成后,table_data 的结构类似于:

python 复制代码
[
    ["姓名", "部门", "职位"],
    ["张三", "研发部", "开发工程师"],
    ["李四", "测试部", "测试工程师"]
]

得到二维数据后,可以继续进行筛选、统计、数据库写入或文件导出。

将 Word 中的所有表格提取为 CSV

一个 Word 文档可能包含多个节,每个节中又可能包含多个表格。

如果需要完整提取文档中的表格,应该依次遍历所有节中的 Tables 集合,而不是只读取第一个表格。

下面的示例将每个 Word 表格分别保存为一个 CSV 文件:

python 复制代码
import csv
import os
from spire.doc import *
from spire.doc.common import *

input_file = "input.docx"
output_folder = "ExtractedTables"

# 创建输出目录
os.makedirs(output_folder, exist_ok=True)

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

table_number = 0

# 遍历文档中的所有节
for s in range(document.Sections.Count):
    section = document.Sections.get_Item(s)

    # 遍历当前节中的所有表格
    for t in range(section.Tables.Count):
        table = section.Tables.get_Item(t)
        table_number += 1

        output_file = os.path.join(
            output_folder,
            f"table_{table_number}.csv"
        )

        with open(
            output_file,
            "w",
            newline="",
            encoding="utf-8-sig"
        ) as csv_file:

            writer = csv.writer(csv_file)

            # 遍历表格中的行
            for r in range(table.Rows.Count):
                row = table.Rows.get_Item(r)
                row_data = []

                # 遍历行中的单元格
                for c in range(row.Cells.Count):
                    cell = row.Cells.get_Item(c)
                    paragraphs = []

                    for p in range(cell.Paragraphs.Count):
                        text = cell.Paragraphs.get_Item(p).Text.strip()

                        if text:
                            paragraphs.append(text)

                    row_data.append(" ".join(paragraphs))

                writer.writerow(row_data)

document.Close()

print(f"共提取 {table_number} 个表格。")

例如,一个 Word 文档包含三个表格,运行后会得到:

text 复制代码
ExtractedTables/
├── table_1.csv
├── table_2.csv
└── table_3.csv

这里使用 utf-8-sig 编码保存 CSV,主要是为了减少包含中文内容的文件在常用表格软件中直接打开时出现乱码的情况。

保留单元格中的换行

前面的示例使用空格连接单元格中的多个段落:

python 复制代码
" ".join(paragraphs)

例如,Word 单元格原本包含:

text 复制代码
产品名称
产品型号

提取后会得到:

text 复制代码
产品名称 产品型号

如果需要保留原有的分行关系,可以改为:

python 复制代码
"\n".join(paragraphs)

这样导出到 CSV 后,多个段落仍然会保留在同一个单元格中,只是以换行符分隔。

具体采用哪种方式,取决于后续如何使用这些数据。如果只是用于数据库导入或数据分析,合并为空格通常更方便;如果希望尽量保留原有内容结构,可以使用换行符。

批量提取多个 Word 文件中的表格

如果一个目录中包含大量 Word 文档,可以将提取过程封装成函数,然后批量处理 .doc 和 .docx 文件。

下面的示例为每个 Word 文档创建一个独立目录,并将其中的所有表格分别保存为 CSV:

python 复制代码
import csv
import os
from spire.doc import *
from spire.doc.common import *


def extract_tables(word_file, output_folder):

    os.makedirs(output_folder, exist_ok=True)

    document = Document()
    document.LoadFromFile(word_file)

    table_number = 0

    for s in range(document.Sections.Count):
        section = document.Sections.get_Item(s)

        for t in range(section.Tables.Count):
            table = section.Tables.get_Item(t)
            table_number += 1

            output_file = os.path.join(
                output_folder,
                f"table_{table_number}.csv"
            )

            with open(
                output_file,
                "w",
                newline="",
                encoding="utf-8-sig"
            ) as csv_file:

                writer = csv.writer(csv_file)

                for r in range(table.Rows.Count):
                    row = table.Rows.get_Item(r)
                    row_data = []

                    for c in range(row.Cells.Count):
                        cell = row.Cells.get_Item(c)
                        paragraphs = []

                        for p in range(cell.Paragraphs.Count):
                            text = (
                                cell.Paragraphs
                                .get_Item(p)
                                .Text
                                .strip()
                            )

                            if text:
                                paragraphs.append(text)

                        row_data.append(
                            " ".join(paragraphs)
                        )

                    writer.writerow(row_data)

    document.Close()

    return table_number


input_folder = "WordFiles"
output_folder = "ExtractedTables"

for file_name in os.listdir(input_folder):

    if not file_name.lower().endswith((".doc", ".docx")):
        continue

    input_file = os.path.join(
        input_folder,
        file_name
    )

    document_name = os.path.splitext(file_name)[0]

    document_output = os.path.join(
        output_folder,
        document_name
    )

    count = extract_tables(
        input_file,
        document_output
    )

    print(
        f"{file_name}:提取 {count} 个表格"
    )

假设输入目录中包含:

text 复制代码
WordFiles/
├── report.docx
├── inventory.docx
└── records.doc

处理后会按照文档名称分别保存:

text 复制代码
ExtractedTables/
├── report/
│   ├── table_1.csv
│   └── table_2.csv
├── inventory/
│   └── table_1.csv
└── records/
    ├── table_1.csv
    └── table_2.csv

这种方式可以避免不同 Word 文档中的表格文件相互覆盖,也更方便后续按照原文档进行分类处理。

提取 Word 表格时需要注意什么

Word 表格与 CSV 这样的二维数据并不是完全对应的,因此提取时有几个问题需要注意。

情况 处理方式
一个单元格包含多个段落 使用空格或换行符连接
单元格为空 保留空字符串,避免影响列的位置
文档包含多个节 遍历所有 Sections
每个节包含多个表格 遍历每个节的 Tables
文档包含合并单元格 导出后检查数据对应关系
需要处理多个 Word 文件 为每个文档建立独立输出目录

其中,合并单元格尤其值得注意。

Word 可以在横向或纵向合并多个单元格,而 CSV 本身没有"合并单元格"的概念。因此,将 Word 表格转换为纯二维数据之后,原有的合并关系无法直接保留。

如果后续需要将数据导入数据库或用于统计分析,通常还需要根据具体表格结构决定如何填充这些空缺位置。

总结

使用 Python 提取 Word 表格,本质上是按照文档结构依次访问节、表格、行和单元格,再读取每个单元格中的段落文本。

如果只需要一个表格,可以直接获取指定的 Table 对象;如果文档中包含多个表格,则可以遍历所有节中的 Tables 集合,并将每个表格分别保存为 CSV。

对于批量文档,可以进一步将提取逻辑封装成函数,实现多个 Word 文件的自动读取和分类保存。需要注意的是,Word 中的合并单元格、段落换行等结构在转换为二维数据时可能需要额外处理,应根据数据的最终用途决定具体的转换方式。

相关推荐
梯度下降者30 分钟前
我校学子斩获 2025 全国高新技术竞赛 Python 赛道全国一等奖
python·教育·竞赛·信息技术·人才培养
小小张说故事38 分钟前
Python 的 memoryview 为什么能零拷贝:拆开 buffer protocol、cast 和那道 BufferError
python
Hvitur1 小时前
Java - Lambda
java·开发语言·python
2601_967980112 小时前
win10如何把python加入环境变量
python·win10·安装教程·命令行·环境变量
锋行天下9 小时前
langgraph 后端发自定义数据,前端接收方法概括
人工智能·python
benchmark_cc11 小时前
用 QuantDash 读取单只股票五档盘口:抽样、缺失值检查与复现记录
python·数据分析·pandas·量化交易·股票数据·quantdash
曲径海盗12 小时前
【Python 学习第 55 天】列表基础
python·学习笔记·编程入门
专注仿真12 小时前
知识问答模型用到的算法集详解及代码实例
python·算法·代码·大模型训练·控制算法
jyOverQ12 小时前
我写了一个 CSDN Markdown 图片助手:告别本地图片逐张上传
python·工具·csdn
刘马想放假15 小时前
CANviz 使用指南|Linux 安装、DBC 解码、实时曲线与 J1939 实战
linux·python·websocket