網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
群里有人提出這么一個(gè)需求:每天都會(huì)傳過(guò)來(lái)一份 Word 文檔,里面有多個(gè) Excel 附件,需要把 Excel 內(nèi)容讀取出來(lái)。
第一反應(yīng)是使用python-docx[1], 經(jīng)測(cè)試,不支持附件提取。?
然后想 docx 本質(zhì)就是一個(gè) zip 格式的壓縮包,直接當(dāng)做 zip 包提取吧。
紅色圈住的部分就是今天的主角,三個(gè) ole 附件。
解壓縮
這樣問(wèn)題就變成了從 zip 里提取三個(gè)附件,代碼如下:
#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)
得到三個(gè) ole 文件。
這段代碼等價(jià)于下面的 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
這是一個(gè) Microsoft OLE2 文件,不是我們想要的 Excel,需要進(jìn)一步分析提取,有請(qǐng)olefile
登場(chǎng)。
olefile[2](原名 OleFileIO_PL)是一個(gè) 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']] ????#?經(jīng)分析只有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")
使用正確的后綴保存附件
我想保存的時(shí)候使用正確后綴,怎么辦?使用filetype[3]獲得正確的后綴。
安裝
pip?install?git+https://github.com/h2non/filetype.py
最新版本支持 Office 文檔識(shí)別
獲取后綴
import?filetype ext?=?filetype.guess_extension("oleObject1.bin") print(ext) #返回 xlsx
如果碰到 filetype 無(wú)法識(shí)別的,就需要考慮 python-magic 或者 file 了。
python-magic[4]是 libmagic 文件類型標(biāo)識(shí)庫(kù)的 Python 接口。libmagic
通過(guò)根據(jù)預(yù)定義的文件類型列表檢查文件類型的頭文件來(lái)識(shí)別文件類型。Unix 命令文件file
就是依賴該庫(kù)來(lái)實(shí)現(xiàn)文件類型判斷。
安裝
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 了, 同時(shí)還需要找到對(duì)應(yīng)關(guān)系,這里就不展開了。
該方法稍作修改,同樣對(duì)Excel和PPT里的附件有效。
原文鏈接:https://mp.weixin.qq.com/s/mLvUYQeLFQYq58tyAgV0tA
相關(guān)推薦
- 2022-07-13 File類的基本運(yùn)用、查找、刪除
- 2022-04-18 后端接口返回一個(gè)圖片地址,前端h5,pc瀏覽器,下載圖片文件,而不是預(yù)覽
- 2024-01-29 深入了解 Spring BeanPostProcessor 的應(yīng)用
- 2022-03-14 關(guān)于VS+QT5應(yīng)用程序換圖標(biāo)的解決方案_C 語(yǔ)言
- 2022-03-22 聚合函數(shù)和group?by的關(guān)系(理解group by 和聚合函數(shù))
- 2022-04-20 Python設(shè)計(jì)模式創(chuàng)建型原型模式_python
- 2022-12-26 python如何修改圖像的分辨率_python
- 2023-05-22 PyTorch小功能之TensorDataset解讀_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支