简介:本文详细介绍如何使用Python的python-docx库高效识别Word文档中的表格文字,涵盖基础表格遍历、复杂结构处理、数据清洗及实用技巧,适合开发者及企业用户快速掌握表格文字提取方法。
python-docx是Python操作Word文档的核心库,支持.docx格式的读写。通过pip安装:
pip install python-docx
验证安装:
from docx import Documentprint("python-docx安装成功")
Word表格由table对象构成,每个表格包含rows(行集合),每行包含cells(单元格集合)。单元格可包含文本、段落、甚至嵌套表格。
场景:文档仅含一个表格,需提取所有单元格文字。
from docx import Documentdoc = Document("single_table.docx")table = doc.tables[0] # 获取第一个表格for row in table.rows:for cell in row.cells:print(cell.text.strip()) # 输出单元格文本并去除首尾空格
关键点:
doc.tables返回文档中所有表格的列表row.cells返回行中所有单元格的列表cell.text获取单元格文本,可能包含换行符场景:文档含多个表格,需按索引或条件提取。
doc = Document("multi_tables.docx")# 按索引提取第二个表格if len(doc.tables) > 1:target_table = doc.tables[1]for row in target_table.rows:print([cell.text for cell in row.cells])# 遍历所有表格(示例:提取含"总计"的表格)for i, table in enumerate(doc.tables):for row in table.rows:if any("总计" in cell.text for cell in row.cells):print(f"找到含'总计'的表格,索引为{i}")
场景:表格含合并单元格、跨行/列单元格。
def extract_merged_table(doc_path):doc = Document(doc_path)for table in doc.tables:for row_idx, row in enumerate(table.rows):row_data = []for cell in row.cells:# 处理合并单元格:通过单元格位置判断是否重复# 实际项目中需结合表格结构分析text = cell.text.strip()row_data.append(text if text else "(空)")print(f"行{row_idx+1}: {row_data}")extract_merged_table("complex_table.docx")
策略:
cell.text可能为空,需结合上下文推断场景:提取的文本含多余空格、换行符或需类型转换。
def clean_table_text(text):# 去除多余空格和换行符cleaned = " ".join(text.split())# 尝试转换为数值(示例)try:return float(cleaned) if "." in cleaned else int(cleaned)except ValueError:return cleaneddoc = Document("data_table.docx")table_data = []for row in doc.tables[0].rows:cleaned_row = [clean_table_text(cell.text) for cell in row.cells]table_data.append(cleaned_row)print("清洗后的表格数据:")for row in table_data:print(row)
场景:处理大型文档(含数百个表格或单元格)。
# 方法1:按需加载表格(避免一次性加载所有文档)def extract_tables_by_range(doc_path, start_idx, end_idx):doc = Document(doc_path)return doc.tables[start_idx:end_idx]# 方法2:使用生成器逐行处理(减少内存占用)def row_generator(table):for row in table.rows:yield [cell.text for cell in row.cells]doc = Document("large_doc.docx")for table in doc.tables[:3]: # 仅处理前3个表格for row_data in row_generator(table):print(row_data)
场景:文档损坏、表格格式异常或权限问题。
try:doc = Document("protected.docx") # 可能因密码保护失败except Exception as e:print(f"文档加载失败: {str(e)}")# 尝试备用文档或提示用户# 处理表格访问越界doc = Document("short_doc.docx")if doc.tables:try:print(doc.tables[0].cell(0, 0).text) # 显式访问单元格except IndexError:print("表格为空或索引超出范围")else:print("文档不含表格")
场景:批量处理合同、报表中的表格数据。
import osfrom docx import Documentdef batch_extract_tables(folder_path, output_csv):import csvwith open(output_csv, "w", newline="", encoding="utf-8") as f:writer = csv.writer(f)writer.writerow(["文件名", "表格索引", "行号", "单元格内容"]) # 写入表头for filename in os.listdir(folder_path):if filename.endswith(".docx"):doc_path = os.path.join(folder_path, filename)try:doc = Document(doc_path)for table_idx, table in enumerate(doc.tables):for row_idx, row in enumerate(table.rows):for cell_idx, cell in enumerate(row.cells):writer.writerow([filename, table_idx, row_idx, cell.text.strip()])except Exception as e:print(f"处理{filename}时出错: {str(e)}")batch_extract_tables("docs_folder", "output_tables.csv")
场景:确保提取的表格数据符合预期格式(如日期、金额)。
import refrom datetime import datetimedef validate_table_data(table_data):errors = []date_pattern = re.compile(r"\d{4}-\d{2}-\d{2}") # 简单日期正则for row in table_data:for i, cell in enumerate(row):if i == 2: # 假设第3列应为日期if not date_pattern.match(cell):errors.append(f"行{row.index(cell)+1}的日期格式无效: {cell}")elif i == 3: # 假设第4列应为数字try:float(cell)except ValueError:errors.append(f"行{row.index(cell)+1}的数值无效: {cell}")return errors# 示例使用(需先提取表格数据为二维列表)table_data = [["A", "B", "2023-01-01", "100"], ["C", "D", "invalid", "200"]]errors = validate_table_data(table_data)if errors:print("数据验证错误:")for err in errors:print(f"- {err}")else:print("所有数据验证通过")
doc.tables、row.cells逐级访问cell.text获取原始文本,需后续清洗通过本文,开发者可系统掌握python-docx识别表格文字的方法,从基础操作到企业级应用均能覆盖。实际项目中,建议结合具体需求调整代码,并添加充分的日志与错误处理机制。