引言
在文档处理中,我们经常需要将Word文档中的内容转换成其他格式,如Excel,以便更好地进行数据分析和报告。针对这一需求,我编写了一个Python脚本,能够批量处理指定目录下的Word文档,将其内容结构化并转换为Excel文件。
功能概述
这个脚本的主要功能包括:
- 批量读取Word文档:自动检索指定目录下的所有Word文档(.docx格式)。
- 内容抽取和组织:根据Word文档中的标题层级(Heading),抽取和组织内容。
- 关键信息提取:自动从Word文档的文件名中提取关键信息,作为Excel表格中的一级节点名称。
- 结构化DataFrame创建:将抽取的信息转化为DataFrame,包含一级至四级节点及其对应内容。
- Excel文件保存:将每个Word文档转换得到的DataFrame保存为同名的Excel文件,位于原始Word文档所在的同一目录。
使用方法
- 准备文档:确保所有待处理的Word文档位于同一目录下,并且每个文档中要有定义好的标题样式(一级标题、二级标题等)。
- 指定目录:修改脚本中的
batch_process_word_to_excel
函数中的directory
参数,指定Word文档所在目录。 - 运行脚本:执行脚本,等待处理完成。脚本将在指定目录下生成对应的Excel文件,文件名与原Word文档一致,但扩展名为’.xlsx’。
代码解析
以下是脚本的完整代码,包含了所需的库和函数定义:
# -*- coding: utf-8 -*-
"""
此Python脚本旨在自动化处理目录下所有的Word文档(.docx),将其内容结构化并转换为Excel文件(.xlsx)。
主要功能:
1. 批量读取指定目录下的所有Word文档。
2. 对每个Word文档,根据文档内的标题层级(Heading)结构,抽取和组织内容。
3. 自动从Word文档的文件名中提取关键信息作为Excel表格中的一级节点名称,特别关注“分册”和“细则”之间的文本。
4. 将抽取的信息转化为结构化的DataFrame,其中包含一级至四级节点及其对应内容。具体转换规则如下:
填充说明:
1.word文件名为一级标题,作为Excel中的一级节点;
2.word中的一级标题作为Excel中的二级节点,一级标题和当前一级标题下的第一个二级标题之间的正文内容作为Excel的二级内容;
3.word中的二级标题作为Excel中的三级节点,二级标题和当前二级标题下的第一个三级标题之间的正文内容作为Excel的三级内容;
4.word中的三级标题作为Excel中的四级节点,三级标题和当前三级标题下的第一个四级标题之间的正文内容作为Excel的四级内容;
5. 将每个Word文档转换得到的DataFrame保存为同名的Excel文件,位于原始Word文档所在的同一目录。
使用方法:
- 确保所有待处理的Word文档位于同一目录下。并且,每个word中要有样式:一级标题、二级标题、三级标题等
- 修改'batch_process_word_to_excel'函数中的'directory'参数,指定Word文档所在目录。
- 运行脚本,脚本将在指定目录下生成对应的Excel文件,文件名与原Word文档一致,但扩展名为'.xlsx'。
依赖库:
- os: 提供与操作系统交互的功能,如文件和目录操作。
- docx: 用于读取Word文档的库。
- pandas: 用于数据处理和分析的库,创建DataFrame和保存Excel文件。
注意事项:
- 代码假设Word文档中的标题层级不超过四级。
- 一级节点名称的提取逻辑基于文件名中包含“分册”和“细则”的特定格式。
- 如需处理不同层级或文件命名规则,需相应调整代码逻辑。
"""
import os
import docx
import pandas as pd
def extract_title_from_filename(filename):
# 分割文件名找到"分册"和"细则"
parts = filename.split('分册')
if len(parts) > 1:
title_part = parts[1].split('细则')[0]
return title_part.strip() # 去除前后空格
else:
return filename # 如果没有找到"分册"或"细则",返回原文件名
def process_word_to_excel(file_path):
doc = docx.Document(file_path)
columns = ['一级节点', '二级节点', '二级内容', '三级节点', '三级内容', '四级节点', '四级内容']
df = pd.DataFrame(columns=columns)
# 获取Word文档的文件名,并从中提取一级节点名称
filename = os.path.basename(file_path)
word_file_name = extract_title_from_filename(filename)
current_level2 = ""
current_level3 = ""
current_level4 = ""
current_content = ""
last_level = 0
for paragraph in doc.paragraphs:
if paragraph.style.name.startswith('Heading'):
heading_level = int(paragraph.style.name[-1])
if heading_level <= last_level:
if current_level4:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'三级节点': [current_level3],
'四级节点': [current_level4],
'四级内容': [current_content]})
elif current_level3:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'三级节点': [current_level3],
'三级内容': [current_content]})
elif current_level2:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'二级内容': [current_content]})
df = pd.concat([df, new_row], ignore_index=True)
current_content = ""
if heading_level == 1:
current_level2 = paragraph.text
current_level3 = ""
current_level4 = ""
last_level = 1
elif heading_level == 2:
current_level3 = paragraph.text
current_level4 = ""
last_level = 2
elif heading_level == 3:
current_level4 = paragraph.text
last_level = 3
else:
current_content += paragraph.text + '\n'
if current_content:
if current_level4:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'三级节点': [current_level3],
'四级节点': [current_level4],
'四级内容': [current_content]})
elif current_level3:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'三级节点': [current_level3],
'三级内容': [current_content]})
elif current_level2:
new_row = pd.DataFrame({'一级节点': [word_file_name],
'二级节点': [current_level2],
'二级内容': [current_content]})
df = pd.concat([df, new_row], ignore_index=True)
return df
def batch_process_word_to_excel(directory):
for filename in os.listdir(directory):
if filename.endswith('.docx'):
file_path = os.path.join(directory, filename)
df = process_word_to_excel(file_path)
excel_filename = os.path.splitext(filename)[0] + '.xlsx'
excel_path = os.path.join(directory, excel_filename)
df.to_excel(excel_path, index=False)
print(f'Processed {filename} to {excel_filename}')
# 调用函数,指定目录
batch_process_word_to_excel('D:\\test')