利用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


猜你喜欢
- 1.11 – 添加缎带修饰网页局部模块中右上角的蓝色缎带修饰是这个网站界面设计中的一个亮点,只要合理的运用CSS、PNG透明图片和绝对定位属
- 如下所示:import osos.system()os.popen().read().strip()#上面2种方法 是python 执行终端
- 首先要把php_iconv.dll和inconv.dll COPY到c:\winnt\system32下,直接上代码:<?define
- 条形码和二维码#引入所需要的基本包from reportlab.pdfgen import canvasfrom reportlab.gra
- 在北美,人们对于 PostgreSQL 的热情不断升温。随着 PostgreSQL 的发展, PostgreSQL 8.x 已经从技术上超越
- 但是我们可以换一种方法解决这个问题。下面就来分析下解决办法。对text或ntext类型的数据在查询中不能进行字符串操作。这时用得最多的是把t
- 快速回顾一下RabbitMQ服务器的安装:sudo apt-get install rabbitmq-serverPython使用Rabbi
- 临时对象池 pool 是啥?sync.Pool 给了一大段注释来说明 pool 是啥,我们看看这段都说了些什么。临时对象池是一些可以分别存储
- 中间件中间件是放在客户端和服务端的中间。 当你的客户端对某个接口发起一个请求,但是在到达接口2之前,这里是有一层中间件的处理。一般
- 今天我们实现疲劳检测。 如果眼睛已经闭上了一段时间,我们会认为他们开始打瞌睡并发出警报来唤醒他们并引起他们的注意。我们测试一段视频来展示效果
- 3. 迭代器3.1. 迭代器(Iterator)概述迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都
- python 2.7.11django 1.8.4错误内容:related Field has invalid lookup: iconta
- 所谓贪婪匹配就是匹配重复字符是尽可能多的匹配,比如:"aaaaa".match(/a+/); //["aaaa
- 1. goland配置Dockerfile项目中新建Dockerfile文件配置Dockerfile在项目中新建Dockerfile 文件,
- 在Python类中规定,函数的第一个参数是实例对象本身,并且约定俗成,把其名字写为self。其作用相当于java中的this,表示当前类的对
- torch.argmax()函数解析1. 官网链接torch.argmax(),如下图所示:2. torch.argmax(input)函数
- 这份数据集来源于Kaggle,数据集有12500只猫和12500只狗。在这里简单介绍下整体思路处理数据设计神经网络进行训练测试1. 数据处理
- Django视图函数执行,不在主线程中,直接loop = asyncio.new_event_loop() # 不能loop = async
- SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML, 数据定义语言DDL,数据控制语言DCL。其中用于定义数据的结构,比如 创建
- python中基本数据类型和其他的语言占用的内存空间大小有很大差别import sysa = 100b = Truec = 100Ld =