写在最前面
批量读取docx文件中的excel表格格式数据
代码思路
:
docx库只能操作docx文件,因此批量处理doc文件,将其保存为docx文件
然后读取docx文件中的excel表格格式数据
递归保存所有文件
原文发布时间:2023-09-20 17:06:22
原文质量分太低,因此进行完善更新
对原代码进行解释说明,方便根据需要进行调整,以适应不同的文件结构和数据提取需求。希望这篇文章对你有所帮助!
参考:番茄跑了的《Python自动办公(五)批量提取word信息至excel》
这篇博客很有意思,感兴趣的朋友可以去看看!
原文
代码展示
import os import pandas as pd from docx import Document from win32com import client as wc import numpy as np # 读取docx文件中的excel表格格式数据 def read_word_table(file_path): doc = Document(file_path) tables = [] for table in doc.tables: data = [] keys = None for i, row in enumerate(table.rows): text = [cell.text for cell in row.cells] if i == 0: keys = text else: data.append(text) if keys: df = pd.DataFrame(data, columns=keys) tables.append(df) # print(tables) return tables # 将doc文件转换为docx文件,因为docx库只能操作docx文件 def doc2docx(doc_files): word = wc.Dispatch("Word.Application") # 打开word应用程序 for doc_file in doc_files: # print(doc_file) doc = word.Documents.Open(doc_file) # 打开word文件 doc.SaveAs("{}x".format(doc_file), 12) # 另存为后缀为".docx"的文件,其中参数12指docx文件 doc.Close() # 关闭原来word文件 word.Quit() # 批量处理doc文件,将其保存为docx文件 def transform(directory_path): file_paths = [] # 递归保存所有文件 for root, dirs, files in os.walk(directory_path): for file in files: # 判断当前目录是否为二级目录 if root.count(os.sep) - directory_path.count(os.sep) == 1: if "推荐" in file.lower() and file.lower().endswith('.doc'): file_path = os.path.join(root, file) # print(file_path) file_paths.append(file_path) doc2docx(file_paths) print("全部doc文件转docx完成") # 删除字符串值末尾的空行 def remove_trailing_empty_lines(value): if isinstance(value, str): return value.rstrip() return value # 遍历DataFrame中的每个元素,并对字符串值应用remove_trailing_empty_lines函数来删除末尾的空行 def remove_trailing_spaces(df): return df.applymap(remove_trailing_empty_lines) def main(directory_path, output_file): all_tables = [] # 递归保存所有文件 for root, dirs, files in os.walk(directory_path): for file in files: # 判断当前目录是否为二级目录 if root.count(os.sep) - directory_path.count(os.sep) == 1: # file.lower().startswith('附件1:推荐社会责任根植项目汇总表') if "推荐" in file.lower() and file.lower().endswith('.docx'): file_path = os.path.join(root, file) print(file_path) tables = read_word_table(file_path) all_tables.extend(tables) print(type(tables),type(all_tables)) if all_tables: all_data = pd.concat(all_tables, ignore_index=False) # 删除excel文件中的重复行 all_data.drop_duplicates(inplace=True) # 删除所有值的末尾空格 all_data = all_data.applymap(lambda x: x.strip() if isinstance(x, str) else x) # 调用删除函数,删除所有值的末尾空格和空行 cleaned_df = remove_trailing_spaces(all_data) all_data["项目名称"] = all_data["项目名称"].replace(['\n',' '],'') all_data.to_excel(output_file, index=False) print("Excel文件汇总完成!") else: print("目录下没有符合条件的Word文件。") if __name__ == "__main__": # directory_path = "D:\\电网材料\\2022根植项目" # 替换为包含Word文件的目录路径 # output_file = "2022output.xlsx" # 输出Excel文件的路径和名称 # directory_path = "D:\\电网材料\\2021根植项目" # 替换为包含Word文件的目录路径 # output_file = "2021output.xlsx" # 输出Excel文件的路径和名称 directory_path = "D:\\电网材料\\2020根植项目" # 替换为包含Word文件的目录路径 output_file = "2020output.xlsx" # 输出Excel文件的路径和名称 transform(directory_path) main(directory_path, output_file)
遇到的问题
就这个问题,chatgpt给我道歉了一下午。。。最后发现是docx文件中的表格不规范,太不容易了害
最终解决:
根据pycharm里面的控制台运行,然后在变量台中找到all_tables属性,检查一下是哪个docx文件的表格读取有问题
我的是表格不连续导致的,即应该是一个完整的表格,但那个docx文件中存在多个分节的表格。
完善
批量读取docx文件中的Excel表格格式数据
在日常工作和研究中,我们经常会遇到需要从不同文档中提取数据的需求。有时候,这些数据嵌套在Word文档中的Excel表格中,而且需要大量处理。本文将介绍如何使用Python编写一个脚本,批量读取包含Excel表格的.docx文件,并将数据提取到一个Excel文件中。
背景
我们需要处理一批Word文档,这些文档中包含了各种Excel表格,这些表格中包含了有用的数据。我们的任务是批量读取这些.docx文件中的Excel表格,并将这些数据整理到一个统一的Excel文件中。
工具准备
为了实现这个任务,我们需要使用以下工具和库:
- Python:我们将使用Python编写脚本来自动化这个任务。
pandas
库:用于处理和操作数据。python-docx
库:用于读取.docx文件中的文本和表格数据。pywin32
库:用于将.doc文件转换为.docx文件,因为python-docx库只能操作.docx文件。
实现步骤
下面是实现批量读取.docx文件中的Excel表格数据的步骤:
步骤 1:将.doc文件转换为.docx文件
由于python-docx
库只能操作.docx文件,我们需要将.doc文件转换为.docx文件。这一步需要使用pywin32
库。我们定义了一个函数doc2docx
来完成这一任务。
def doc2docx(doc_files): word = wc.Dispatch("Word.Application") # 打开Word应用程序 for doc_file in doc_files: doc = word.Documents.Open(doc_file) # 打开.doc文件 doc.SaveAs("{}x".format(doc_file), 12) # 另存为后缀为".docx"的文件 doc.Close() # 关闭原.doc文件 word.Quit()
解读步骤1的关键点:
- 导入
win32com.client
库并将其命名为wc
:这是pywin32
库的一部分,用于与Windows COM(Component Object Model)对象进行交互,其中包括Microsoft Office应用程序。 - 创建与Word应用程序的连接:通过
wc.Dispatch("Word.Application")
,我们创建了一个与Word应用程序的连接,以便操作Word文档。 - 循环遍历传递给
doc2docx
函数的.doc
文件列表(doc_files
):这个函数接受一个.doc
文件的列表,可以将多个文件一次转换为.docx
。 - 打开原始的
.doc
文件:使用word.Documents.Open(doc_file)
,我们打开传递给函数的每个.doc
文件。 - 另存为
.docx
格式:通过doc.SaveAs("{}x".format(doc_file), FileFormat=12)
,我们将打开的.doc
文件另存为后缀为.docx
的文件,并且FileFormat=12
表示.docx
文件格式。 - 关闭原始的
.doc
文件:使用doc.Close()
,我们关闭原始的.doc
文件,以便继续处理下一个文件。 - 退出Word应用程序:最后,使用
word.Quit()
,我们退出Word应用程序,以确保不会占用额外的系统资源。
这个函数执行后,将得到一个.docx
文件的副本,可以使用python-docx
库进行进一步的处理和编辑。这是将.doc
文件转换为.docx
文件的关键步骤,以便后续处理文档内容。
步骤 2:批量处理.doc文件
接下来,我们定义了一个函数transform
来批量处理.doc文件。这个函数将递归查找目录中的.doc文件,将它们转换为.docx文件。
def transform(directory_path): file_paths = [] for root, dirs, files in os.walk(directory_path): for file in files: if root.count(os.sep) - directory_path.count(os.sep) == 1: if "推荐" in file.lower() and file.lower().endswith('.doc'): file_path = os.path.join(root, file) file_paths.append(file_path) doc2docx(file_paths) print("全部.doc文件转.docx完成")
解读步骤2的关键点:
- 导入
os
库:我们使用os
库来操作文件系统,以便查找目录中的文件。 - 定义一个空列表
file_paths
:这个列表将用于存储需要转换的.doc
文件的文件路径。 - 递归查找目录中的文件:使用
os.walk(directory_path)
,我们递归遍历指定目录(directory_path
)下的所有文件和子目录。os.walk
返回一个生成器,它生成每个文件的根目录、子目录和文件名。 - 筛选需要转换的文件:我们通过检查文件名中是否包含"推荐"和文件扩展名是否为
.doc
,来筛选需要转换的文件。这是一个示例条件,您可以根据实际情况进行修改。 - 构建文件路径并添加到
file_paths
列表:对于每个满足条件的文件,我们使用os.path.join(root, file)
构建文件的完整路径,并将其添加到file_paths
列表中。 - 调用
doc2docx
函数:我们使用之前定义的doc2docx
函数来批量转换.doc
文件为.docx
文件。 - 打印完成消息:最后,我们打印一条消息,指示所有
.doc
文件的批量转换已完成。
这个transform
函数使您能够方便地批量处理目录中的.doc
文件,将它们转换为.docx
格式,以便后续处理和编辑。
步骤 3:读取.docx文件中的Excel表格数据
现在,我们定义了一个函数read_word_table
来读取.docx文件中的Excel表格数据。这个函数使用python-docx
库来解析.docx文件中的表格,将它们转化为pandas
的DataFrame对象。
def read_word_table(file_path): doc = Document(file_path) tables = [] for table in doc.tables: data = [] keys = None for i, row in enumerate(table.rows): text = [cell.text for cell in row.cells] if i == 0: keys = text else: data.append(text) if keys: df = pd.DataFrame(data, columns=keys) tables.append(df) return tables
步骤 4:主函数
最后,我们定义了一个主函数main
,它将执行上述步骤,从.docx文件中提取Excel表格数据,并将它们汇总到一个Excel文件中。
import pandas as pd def main(directory_path, output_file): all_tables = [] # 存储从.docx文件中提取的Excel表格数据列表 # 遍历指定目录中的文件 for root, dirs, files in os.walk(directory_path): for file in files: if root.count(os.sep) - directory_path.count(os.sep) == 1: # 通过检查文件名中是否包含"推荐",以及文件扩展名是否为.docx,来筛选需要处理的文件 if "推荐" in file.lower() and file.lower().endswith('.docx'): file_path = os.path.join(root, file) tables = read_word_table(file_path) # 使用之前定义的函数读取表格数据 all_tables.extend(tables) if all_tables: # 合并所有表格数据并去重 all_data = pd.concat(all_tables, ignore_index=False) all_data.drop_duplicates(inplace=True) # 去除字符串列中的首尾空格 all_data = all_data.applymap(lambda x: x.strip() if isinstance(x, str) else x) # 移除尾随空格的函数已在之前定义 cleaned_df = remove_trailing_spaces(all_data) # 对特定列进行字符串处理,例如,去除列"项目名称"中的换行符和空格 all_data["项目名称"] = all_data["项目名称"].replace(['\n',' '],'') # 将汇总后的数据保存到Excel文件 all_data.to_excel(output_file, index=False) print("Excel文件汇总完成!") else: print("目录下没有符合条件的Word文件。")
解读步骤4的关键点:
- 导入
pandas
库:我们使用pandas
库来处理Excel表格数据和创建Excel文件。 - 定义一个空列表
all_tables
:这个列表将用于存储从.docx
文件中提取的Excel表格数据。 - 遍历指定目录中的文件:使用
os.walk(directory_path)
,我们递归遍历指定目录下的所有文件和子目录,筛选出需要处理的.docx
文件。 - 读取表格数据:使用之前定义的函数
read_word_table(file_path)
,我们读取每个.docx
文件中的Excel表格数据,并将它们添加到all_tables
列表中。 - 合并表格数据并去重:如果存在表格数据,我们将所有表格数据合并成一个数据框(
all_data
),并去除重复行。 - 字符串处理:我们对数据框中的字符串列进行处理,例如,去除首尾空格和特定字符。
- 保存到Excel文件:最后,我们使用
to_excel
方法将处理后的数据保存到指定的Excel文件。 - 打印完成消息:程序执行完毕后,我们打印一条消息,指示Excel文件的汇总已完成。
这个main
函数是整个处理过程的核心,它将目录中的所有符合条件的.docx
文件中的Excel表格数据提取、清理并汇总到一个Excel文件中。这使得数据处理更加高效和自动化。
使用示例
在主函数中,我们需要提供包含.docx文件的目录路径和输出Excel文件的路径和名称。然后,执行transform
函数将.doc文件转换为.docx文件,最后执行main
函数将数据提取到Excel文件中。
if __name__ == "__main__": directory_path = "D:\\电网材料\\2020根植项目" # 替换为包含Word文件的目录路径 output_file = "2020output.xlsx" # 输出Excel文件的路径和名称 transform(directory_path) main(directory_path, output_file)
这样,我们就可以批量处理.docx文件中的Excel表格数据,并将它们整理到一个Excel文件中。这个脚本可以根据需要进行调整,以适应不同的文件结构和数据提取需求。希望这篇文章对你有所帮助!