一、编写目的
最近由于工作上的需要,需要使用python完成doc文档格式数据的读取和修改工作,但通过查阅相关资料,直接对doc文档进行读取和修改没有相关的依赖(主要为doc文件为较早的windows系统支持格式),需要将doc文件转换为.docx格式,为什么是docx格式?
-
.docx
是 xml 格式,通常无编码问题,但若从其他格式转换可能出错。 - python-docx依赖库可以直接对docx文档格式进行操作,但无法对doc格式进行操作。
那么问题就转变为如何将doc格式转换为.docx格式的问题,有下面的解决方法:
- 如果你在windows系统上且安装有microsoft word 可以使用pywin32调用word提供的com口进行格式转换。
那如果就不想花钱或者安装word,或者我使用的是其它系统(如linux系统)又该如何转换doc格式到.docx格式呢?
这里也找到了相关的软件支持:libreoffice。它提供了和word几乎相同的功能,但其为免费开源的,并且可以通过命令行进行调用,最重要的可以多系统支持。
本篇文章就是记录使用libreoffice+python-docx完成doc文档内表格的转换和修改的。
二、环境准备
1、安装libreoffice
如果是windows系统可以官网下载libreoffice的.exe安装包,然后就是不断地下一步即可。
如果是linux系统可以通过下面的命令进行安装:
ubuntu/debian:
sudo apt update && sudo apt install libreoffice
fedora:
sudo dnf install libreoffice
opensuse:
sudo zypper install libreoffice
安装完成后,可以在命令行中进行版本验证:
soffice --version
如果输出下述内容则表明安装成功:
libreoffice 25.2.3.2 bbb074479178df812d175f709636b368952c2ce3
2、安装python-docx
在已有的python环境下安装python-docx可以使用以下命令:
pip install python-docx
三、代码实现
1、转换成docx
根据上面的步骤,先进行doc到docx的转换,我们可以使用以下命令进行转换:
soffice --headless --convert-to <目标格式> <输入文件> [--outdir <输出目录>]
当然这里需要再python中进行命令行的调用,直接上代码:
import os import subprocess import re def convert_doc_to_docx(doc_path, output_dir, soffice_path=none): """ 使用 libreoffice 将 .doc 转换为 .docx :param doc_path: .doc 文件路径 :param output_dir: 输出目录(默认当前目录) :param soffice_path: libreoffice 的 soffice.exe 完整路径(可选) :return: 转换后的 .docx 文件路径 """ if not doc_path.lower().endswith('.doc'): raise valueerror("输入文件必须是 .doc 格式") # 确保输出目录存在 os.makedirs(output_dir, exist_ok=true) # 构造输出路径 base_name = os.path.splitext(os.path.basename(doc_path))[0] docx_path = os.path.join(output_dir, f"{base_name}.docx") # 检查 libreoffice 是否安装 if soffice_path is none: try: # 尝试调用 soffice 命令 subprocess.run(["soffice", "--version"], check=true, stdout=subprocess.pipe, stderr=subprocess.pipe) soffice_cmd = ["soffice"] except filenotfounderror: raise runtimeerror("libreoffice 未安装或未添加到系统 path 中。请确保 libreoffice 已正确安装并在 path 中,或提供 soffice.exe 的完整路径。") else: soffice_cmd = [soffice_path] # 使用 libreoffice 转换 try: subprocess.run( soffice_cmd + ["--headless","--nodefault","--nologo", "--convert-to", "docx", "--outdir", output_dir, doc_path], check=true, stdout=subprocess.pipe, stderr=subprocess.pipe ) if not os.path.exists(docx_path): raise runtimeerror(f"转换失败,未找到输出文件: {docx_path}") return docx_path except subprocess.calledprocesserror as e: error_msg = f"转换失败: {e.stderr.decode()}" raise runtimeerror(error_msg)
在上面的代码中先进行libreoffice环境是否安装的检测,然后调用命令行进行目标文件的转换,转换完成的文件放到output_dir目录下。
2、读取和修改
转换成docx文件后就可以使用python-docx依赖对数据进行操作了,下面的python代码实现了docx文档内表格的读取:
from docx import document def read_docx_tables(docx_path): """ 使用 python-docx 读取 .docx 文件中的表格 :param docx_path: .docx 文件路径 :return: 表格数据列表(每行是一个列表) """ try: doc = document(docx_path) except exception as e: raise runtimeerror(f"无法读取 .docx 文件: {e}") tables_data = [] for i, table in enumerate(doc.tables): print(f"\n表格 {i + 1}:") table_data = [] for row_idx, row in enumerate(table.rows): row_data = [cell.text.strip() for cell in row.cells] # 清理单元格中的特殊字符 row_data = [clean_text(cell) for cell in row_data] table_data.append(row_data) print(row_data) tables_data.append(table_data) return tables_data
修改起来也是非常方便的,只需要在更新row.cells[索引].text后,执行一下doc.save(docx_path)的操作,代码如下:
from docx import document def modify_docx_tables(docx_path, output_path=none, modify_func=none): """ 仅修改 .docx 文件中的表格数据(不读取原有数据) :param docx_path: 输入的 .docx 文件路径 :param output_path: 输出的 .docx 文件路径(如果为 none,则覆盖原文件) :param modify_func: 修改表格数据的函数(接收 table 并直接修改) """ if output_path is none: output_path = docx_path # 默认覆盖原文件 try: doc = document(docx_path) except exception as e: raise runtimeerror(f"无法读取 .docx 文件: {e}") for i, table in enumerate(doc.tables): print(f"\n修改表格 {i + 1}:") """ 示例修改函数:将所有单元格内容改为 "modified" """ for row in table.rows: for cell in row.cells: cell.text = "modified" # 直接修改单元格内容 # 保存修改后的文档 doc.save(output_path) print(f"\n表格数据已修改并保存到: {output_path}")
四、总结
上面就是对doc格式的文档表格的读取和修改操作的全部内容了,虽然doc文件格式比较落后,但不可避免的有些公司可能有些比较古老的系统,在日常生产中就使用到doc文件格式,如果你有这方面的需求,希望这篇文章能帮助到你。
以上就是python提取word表格数据的详细教程的详细内容,更多关于python提取word表格数据的资料请关注代码网其它相关文章!
发表评论