利用Python实现读取Word文档里的Excel附件
作者:alitrack 发布时间:2022-01-21 11:28:18
群里有人提出这么一个需求:每天都会传过来一份 Word 文档,里面有多个 Excel 附件,需要把 Excel 内容读取出来。
第一反应是使用python-docx[1], 经测试,不支持附件提取。
然后想 docx 本质就是一个 zip 格式的压缩包,直接当做 zip 包提取吧。
红色圈住的部分就是今天的主角,三个 ole 附件。
解压缩
这样问题就变成了从 zip 里提取三个附件,代码如下:
#zipfile为python自带包
from zipfile import ZipFile
with ZipFile("test.docx", "r") as zip:
for entry in zip.infolist():
if not entry.filename.startswith("word/embeddings/"):
continue
zip.extract(entry.filename)
得到三个 ole 文件。
这段代码等价于下面的 unzip 命令行
unzip test.docx word/embeddings/*
#返回
Archive: test.docx
creating: word/embeddings/
inflating: word/embeddings/oleObject1.bin
inflating: word/embeddings/oleObject2.bin
inflating: word/embeddings/oleObject3.bin
Microsoft OLE2 文件分析与提取
分析
文件提取好后, 使用 file 程序分析,得到
file word/embeddings/oleObject1.bin
#返回
word/embeddings/oleObject1.bin: Composite Document File V2 Document, Cannot read section info
这是一个 Microsoft OLE2 文件,不是我们想要的 Excel,需要进一步分析提取,有请olefile
登场。
olefile[2](原名 OleFileIO_PL)是一个 Python 包,用于解析、读写 Microsoft OLE2 文件(也称为 Structured Storage、Compound File Binary Format 或 Compound Document File Format),例如 Microsoft Office 97-2003 文档,MS Office 中的 vbaProject.bin 2007+ 文件、Image Composer 和 FlashPix 文件、Outlook MSG 文件、StickyNotes、多种 Microscopy 文件格式、McAfee 防病毒隔离文件等。
安装
pip install olefile
提取
import olefile
f = "word/embeddings/oleObject1.bin"
if olefile.isOleFile(f):
with olefile.OleFileIO(f) as ole:
print(ole.listdir())
#返回[['\x01Ole'], ['\x03ObjInfo'], ['package']]
# 经分析只有package里放着我们需要的信息
bin_data = ole.openstream("package").read()
fn = f.replace("word/embeddings/","")
with open(fn, "wb") as output_file:
output_file.write(bin_data)
再次使用 file 分析
file oleObject1.bin
#返回
oleObject1.bin: Microsoft Excel 2007+
是我们想要的 Excel 文件。
完整代码如下
import olefile
from zipfile import ZipFile
def get_ole(filename):
with ZipFile(filename, "r") as zip:
for entry in zip.infolist():
if not entry.filename.startswith("word/embeddings/"):
continue
with zip.open(entry.filename) as f:
if not olefile.isOleFile(f):
continue
with olefile.OleFileIO(f) as ole:
bin_data = ole.openstream("package").read()
fn = entry.filename.replace("word/embeddings/","")
#如果想直接读取,可以把下面两行代码换成需要的代码。
with open(fn, "wb") as output_file:
output_file.write(bin_data)
if __name__ == '__main__':
get_ole("/Users/steven/temp/test.docx")
使用正确的后缀保存附件
我想保存的时候使用正确后缀,怎么办?使用filetype[3]获得正确的后缀。
安装
pip install git+https://github.com/h2non/filetype.py
最新版本支持 Office 文档识别
获取后缀
import filetype
ext = filetype.guess_extension("oleObject1.bin")
print(ext)
#返回
xlsx
如果碰到 filetype 无法识别的,就需要考虑 python-magic 或者 file 了。
python-magic[4]是 libmagic 文件类型标识库的 Python 接口。libmagic
通过根据预定义的文件类型列表检查文件类型的头文件来识别文件类型。Unix 命令文件file
就是依赖该库来实现文件类型判断。
安装
Windows 推荐安装方法
pip install python-magic-bin
Linux 和macOS还需要额外安装libmagic
获取后缀
import magic
m = magic.Magic(extension=True)
ext = m.from_file("oleObject1.bin")
print(ext)
#返回
xlsx
正确的文件名
附件的原始名字是以图片的形式存在,emf 格式, 如果需要获取原始文件名字,需要 OCR 了, 同时还需要找到对应关系,这里就不展开了。
该方法稍作修改,同样对Excel和PPT里的附件有效。
来源:https://mp.weixin.qq.com/s/mLvUYQeLFQYq58tyAgV0tA
猜你喜欢
- 简单介绍下功能吧:使用了ASP的一个对象ServerVariables(服务器环境变量),通过这个环境变量可以获取到真正的下载地址再通过一些
- 转自微信公众号:机器学习社区,经作者授权转载时间序列分析是数据科学中一个非常重要的领域,它主要包含统计分析、检测变化点、异常检测和预测未来趋
- 继承与threading.Thread实现有返回值的子类MyThread,废话不多说,大家直接看代码import threadingclas
- 1.--区分大小写select * from a where a=’AbCdE’ collate C
- 关于数据库的逻辑设计,是一个很广泛的问题。本文主要针对开发应用中遇到在MS SQL Server上进行表设计时,对表的主键设计应注意的问题以
- 嵌套SELECT语句也叫子查询,形如:SELECT name FROM bbc WHERE region = (SELECT region
- 本文要实现的功能是:根据下拉列表的选项将数据库中对应的内容显示在页面,选定要排除的选项后,提交剩余的选项到数据库。为了方便前后台交互,利用了
- Response是负责将信息传递给用户的对象,它可动态地响应客户端的请求,并将动态生成的响应结果返回给客户端浏览器。 一,Resp
- 想查找mac下python的site-packages目录,如果用网上搜的安装目录之类的去找,进去每一层很多都是软链接形式存在,比较浪费时间
- 本文实例讲述了python复制文件的方法。分享给大家供大家参考。具体分析如下:这里涉及Python复制文件在实际操作方案中的实际应用以及Py
- 阅读上一章:Chapter 13 为文字指定样式Chapter 14 图片替换随着更多设计师与开发者开始使用标准(特别是CSS),每天都会有
- 今天有朋友问到如下一则案例,ORA-01114,ORA-27067以及OSD-04026错误同时出现:*** ACTION NAME:()
- 本文实例讲述了JS实现仿新浪微博发布内容为空时提示功能。分享给大家供大家参考。具体如下:这里使用JavaScript模拟新浪微博的一个功能,
- 最近在使用Python的过程中,发现网上很少提到在使用post方式时,怎么传一个数组作为参数的示例,此处根据自己的实践经验,给出相关示例:单
- <?php /*============================文件说明===========================
- 下面这段代码是兼容IE的图片切换代码,请问各位老鸟如何兼容FF,或者有相类似无按钮无数字兼容FF的图片切换代码?<!DOCTYPE h
- 用户管理是绝大部分Web网站都需要解决的问题。用户管理涉及到用户注册和登录。用户注册相对简单,我们可以先通过API把用户注册这个功能实现了:
- 自从HTML5能为我们的新网页带来更高效洁净的代码而得到更多的关注,然而唯一能让IE识别那些新元素(如<article>)的途径
- ORA-00600:internal error code,arguments:[num],[?],[?],[?],[?]产生原因:这种错误
- 看到别人用td和table标签模拟的办法: 设置table的上、左padding