开发者

利用Python实现读取Word文档里的Excel附件

开发者 https://www.devze.com 2022-12-17 09:19 出处:网络 作者: alitrack
目录解压缩Microsoft OLE2 文件分析与提取分析安装提取再次使用 file 分析完整代码如下使用正确的后缀保存附件安装获取后缀安装获取后缀正确的文件名群里有人提出这么一个需求:每天都会传过来一份 Wphpord 文档,里
目录
  • 解压缩
  • Microsoft OLE2 文件分析与提取
    • 分析
    • 安装
    • 提取
    • 再次使用 file 分析
  • 完整代码如下
    • 使用正确的后缀保存附件
      • 安装
      • 获取后缀
      • 安装
      • 获取后缀
    • 正确的文件名

      群里有人提出这么一个需求:每天都会传过来一份 Wphpord 文档,里面有多个 Excel 附件,需要把 Excel 内容读取出来。

      第一反应是使用python-docx[1], 经测试,不支持附件提取。 

      然后想 docx 本质就是一个 zip 格式的压缩包,直接当做 zip 包提取吧。

      利用Python实现读取Word文档里的Excel附件

      红色圈住的部分就是今天的主角,三个 ole 附件。

      解压缩

      这样问题就变成了从 zip 里提取三个附件,代码如下:

      #zipfile为python自带包
      fromzipfileimportZipFile
      withZipFile("test.docx"python,"r")aszip:
      forentryinzip.infolist():
      ifnotentry.filename.startswith("word/embeddings/"):
      continue
      zip.extract(enPegRcLHSLEtry.filename)
      

      得到三个 ole 文件。

      这段代码等价于下面的 unzip 命令行

      unziptest.docxword/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 程序分析,得到

      fileword/embeddings/oleObject1.bin
      #返回
      word/embeddings/oleObject1.bin:CompositeDocumentFileV2Document,Cannotreadsectioninfo
      

      这是一个 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 防病毒隔离文件等。

      安装

      pipinstallolefile
      

      提取

      importolefile
      f="word/embeddings/oleObject1.bin"
      ifolefile.isOleFile(f):
      witholefile.OleFileIO(f)asole:
      print(ole.listdir())
      #返回[['\x01Ole'],['\x03ObjInfo'],['package']]
      #经分析只有package里放着我们需要的信息
      bin_data=ole.openstream("package").read()
      fn=f.replace("word/embeddings/","")
      withopen(fn,"wb")asoutput_file:
      output_file.write(bin_data)
      

      再次使用 file 分析

      fileoleObject1.bin
      #返回
      oleObject1.bin:MicrosoftExcel2007+
      

      是我们想要的 Excel 文件。

      完整代码如下

      importolefile
      fromzipfileimportZipFile
      defget_ole(filename):
      withZipFile(filename,"r")aszip:
      forentryinzip.infolist():
      ifnotentry.filename.startswith("word/ph开发者_JAV培训pembeddings/"):
      continue
      withzip.open(entry.filename)asf:
      ifnotolefile.isOleFile(f):
      continue
      witholefile.OleFileIO(f)asole:
      bin_data=ole.openstream("package").read()
      fn=entry.filename.replace("word/embeddings/","")
      #如果想直接读取,可以把下面两行代码换成需要的代码。
      withopen(fn,"wb")asoutput_file:
      output_file.write(bin_data)
      if__name__=='__main__':
      get_ole("/Users/steven/temp/test.docx")
      

      使用正确的后缀保存附件

      我想保存的时候使用正确后缀,怎么办?使用filetype[3]获得正确的后缀。

      安装

      pipinstallgit+https://github.com/h2non/filetype.py
      

      最新版本支持 Office 文档识别

      获取后缀

      importfiletype
      ext=filetype.guess_extension("oleObject1.bin")
      print(ext)
      #返回
      xlsx
      

      如果碰到 filetype 无法识别的,就需要php考虑 python-magic 或者 file 了。

      python-magic[4]是 libmagic 文件类型标识库的 Python 接口。libmagic通过根据预定义的文件类型列表检查文件类型的头文件来识别文件类型。Unix 命令文件file就是依赖该库来实现文件类型判断。

      安装

      Windows 推荐安装方法

      pip install python-magic-bin
      

      linux 和MACOS还需要额外安装libmagic

      获取后缀

      importmagic
      m=magic.Magic(extension=True)
      ext=m.from_file("oleObject1.bin")
      print(ext)
      #返回
      xlsx
      

      正确的文件名

      附件的原始名字是以图片的形式存在,emf 格式, 如果需要获取原始文件名字,需要 OCR 了, 同时还需要找到对应关系,这里就不展开了。

      该方法稍作修改,同样对Excel和PPT里的附件有效。

      到此这篇关于利用Python实现读取Word文档里的Excel附件的文章就介绍到这了,更多相关Python读取Word中Excel附件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号