Word 文档中的表格经常用于保存统计数据、项目清单、检测记录和业务报表。如果只是偶尔处理一两个文件,可以直接复制表格内容;但当文档包含多个表格,或者需要批量提取大量 Word 文件中的数据时,手动操作就比较低效。
通过 Python,可以按照文档、节、表格、行和单元格的层级读取 Word 表格,并将提取的数据继续用于统计分析、数据库导入,或者保存为 CSV 等结构化文件。
本文介绍如何使用 Python 读取 Word 表格数据、提取文档中的所有表格,以及批量处理多个 Word 文件。
要运行下面的代码示例,需要先安装 Word 处理所需的 Python 模块:
pip install Spire.Doc如果只需要读取文档中的某一个表格,可以先获取表格对象,再依次遍历其中的行和单元格。
下面的示例读取 Word 文档第一个节中的第一个表格,并将表格内容保存到二维列表中:
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 的结构类似于:
[
["姓名", "部门", "职位"],
["张三", "研发部", "开发工程师"],
["李四", "测试部", "测试工程师"]
]得到二维数据后,可以继续进行筛选、统计、数据库写入或文件导出。
一个 Word 文档可能包含多个节,每个节中又可能包含多个表格。
如果需要完整提取文档中的表格,应该依次遍历所有节中的 Tables 集合,而不是只读取第一个表格。
下面的示例将每个 Word 表格分别保存为一个 CSV 文件:
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 文档包含三个表格,运行后会得到:
ExtractedTables/
├── table_1.csv
├── table_2.csv
└── table_3.csv这里使用 utf-8-sig 编码保存 CSV,主要是为了减少包含中文内容的文件在常用表格软件中直接打开时出现乱码的情况。
前面的示例使用空格连接单元格中的多个段落:
" ".join(paragraphs)例如,Word 单元格原本包含:
产品名称
产品型号提取后会得到:
产品名称 产品型号如果需要保留原有的分行关系,可以改为:
"\n".join(paragraphs)这样导出到 CSV 后,多个段落仍然会保留在同一个单元格中,只是以换行符分隔。
具体采用哪种方式,取决于后续如何使用这些数据。如果只是用于数据库导入或数据分析,合并为空格通常更方便;如果希望尽量保留原有内容结构,可以使用换行符。
如果一个目录中包含大量 Word 文档,可以将提取过程封装成函数,然后批量处理 .doc 和 .docx 文件。
下面的示例为每个 Word 文档创建一个独立目录,并将其中的所有表格分别保存为 CSV:
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} 个表格"
)假设输入目录中包含:
WordFiles/
├── report.docx
├── inventory.docx
└── records.doc处理后会按照文档名称分别保存:
ExtractedTables/
├── report/
│ ├── table_1.csv
│ └── table_2.csv
├── inventory/
│ └── table_1.csv
└── records/
├── table_1.csv
└── table_2.csv这种方式可以避免不同 Word 文档中的表格文件相互覆盖,也更方便后续按照原文档进行分类处理。
Word 表格与 CSV 这样的二维数据并不是完全对应的,因此提取时有几个问题需要注意。
情况 | 处理方式 |
|---|---|
一个单元格包含多个段落 | 使用空格或换行符连接 |
单元格为空 | 保留空字符串,避免影响列的位置 |
文档包含多个节 | 遍历所有 Sections |
每个节包含多个表格 | 遍历每个节的 Tables |
文档包含合并单元格 | 导出后检查数据对应关系 |
需要处理多个 Word 文件 | 为每个文档建立独立输出目录 |
其中,合并单元格尤其值得注意。
Word 可以在横向或纵向合并多个单元格,而 CSV 本身没有“合并单元格”的概念。因此,将 Word 表格转换为纯二维数据之后,原有的合并关系无法直接保留。
如果后续需要将数据导入数据库或用于统计分析,通常还需要根据具体表格结构决定如何填充这些空缺位置。
使用 Python 提取 Word 表格,本质上是按照文档结构依次访问节、表格、行和单元格,再读取每个单元格中的段落文本。
如果只需要一个表格,可以直接获取指定的 Table 对象;如果文档中包含多个表格,则可以遍历所有节中的 Tables 集合,并将每个表格分别保存为 CSV。
对于批量文档,可以进一步将提取逻辑封装成函数,实现多个 Word 文件的自动读取和分类保存。需要注意的是,Word 中的合并单元格、段落换行等结构在转换为二维数据时可能需要额外处理,应根据数据的最终用途决定具体的转换方式。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。