Python 批量导出word文档中的图片、嵌入式文件

需求

学生试卷中的题目有要提交截图的,也有要提交文件的,为了方便学生考试,允许单独交或者嵌入Word中提交,那么事后如何整理学生的答案?单独提交的比较方便,直接扫描文件名匹配名字后放入指定文件夹即可。但是嵌入到Word中的图片和文件怎么提取出来呢?

现有如下需求:提取出一个Word文档中所有的图片(png、jpg)和嵌入的文件(任意格式)放入到指定的文件夹。

解决

docx是一个压缩包,解压缩后图片一般都放在文档名.docx\word\media\目录下:

而嵌入式文件一般都放在文档名.docx\word\embeddings\目录下:

经过询问度娘,发现提取图片比较简单,直接使用docx库中的Document.part.rels{k:v.target_ref}找到文件的相对路径,用Document.part.rels{k:v.target_part.blob}读出文件内容。简单判断一下路径和文件后缀是不是我们需要的media下的png文件和embeddings下的bin文件,是的话写入到新文件中即可:

提取图片

安装python-docx库

pip install python-docx

提取

import osfrom docx import Document  # pip install python-docxis_debug = Trueif __name__ == '__main__':# 需要导出的Word文档路径target_file = r'paper\HBase试题.docx'# 导出文件所在目录output_dir = r'paper\output'# 加载Word文档doc = Document(target_file)# 遍历Word包中的所有文件dict_rel = doc.part.rels# r_id:文件身份码,rel:文件对象for r_id, rel in dict_rel.items():if not ( # 如果文件不是在media或者embeddings中的,直接跳过str(rel.target_ref).startswith('media')or str(rel.target_ref).startswith('embeddings')):continue# 如果文件不是我们想要的后缀,也直接跳过file_suffix = str(rel.target_ref).split('.')[-1:][0]if file_suffix.lower() not in ['png', 'jpg', 'bin']:continue# 如果输出目录不存在,创建if not os.path.exists(output_dir):os.makedirs(output_dir)# 构建导出文件的名字和路径file_name = r_id + '_' + str(rel.target_ref).replace('/', '_')file_path = os.path.join(output_dir,file_name)# 将二进制数据写入到新位置的文件中with open(file_path, "wb") as f:f.write(rel.target_part.blob)# 打印结果if is_debug:print('导出文件成功:', file_name)

运行结果:

可以看到,图片都能正常导出,但是学生嵌入的JAVA文件并没有导出,或者说导出的是bin文件,没有完全导出。

提取嵌入式文件

再次询问度娘发现,这种其实也是zip压缩包,但是不能直接提取出,它有个更专业的名字,叫ole文件,我们之前的doc、xls、ppt等没有带x的上古文档文件都是这种格式。那如何提取出文件呢?度娘告诉我有个叫oletools的项目可以,于是下载下来浅浅地分析了下,发现确实可以!

oletools项目地址:https://github.com/decalage2/oletools

或者gitee上别人转存的地址:https://gitee.com/yunqimg/oletools

我是用的gitee上的版本,因为github打不开 QwQ

经相关文档介绍,项目下的oletools-master\oletools\oleobj.py就可以提取这种bin后缀的ole文件,简单试一下,在oleobj.py所在目录下打开命令行,把刚刚提取出的rId12_embeddings_oleObject1.bin文件复制到oleobj.py所在目录,执行如下命令:

注意: 在此之前我执行了一下安装oletools的命令,如果不安装可能会出错:pip install oletools,或者说oleobj.py依赖olefile:pip install olefile,在安装oletools时顺便安装了olefile。

python oleobj.py rId12_embeddings_oleObject1.bin

成功导出

Microsoft Windows [版本 10.0.22000.708]
(c) Microsoft Corporation。保留所有权利。D:\Minuy\Downloads\oletools-master\oletools-master\oletools>python oleobj.py rId12_embeddings_oleObject1.bin
oleobj 0.56 - http://decalage.info/oletools
THIS IS WORK IN PROGRESS - Check updates regularly!
Please report any issue at https://github.com/decalage2/oletools/issues-------------------------------------------------------------------------------
File: 'rId12_embeddings_oleObject1.bin'
extract file embedded in OLE object from stream '\x01Ole10Native':
Parsing OLE Package
Filename = "Boos.java"
Source path = "D:\111\´ó20´óÊý¾Ý Àî¾üÁé\Boos.java"
Temp path = "C:\Users\ADMINI~1\AppData\Local\Temp\Boos.java"
saving to file rId12_embeddings_oleObject1.bin_Boos.javaD:\Minuy\Downloads\oletools-master\oletools-master\oletools>

导出的文件也能正常访问:

于是把oletools目录复制到工程项目下,稍微修改一下oleobj.py能让我的代码调用它,在oleobj.py中添加如下代码:

def export_main(ole_files, output_dir, log_leve=DEFAULT_LOG_LEVEL):ensure_stdout_handles_unicode()logging.basicConfig(level=LOG_LEVELS[log_leve], stream=sys.stdout,format='%(levelname)-8s %(message)s')# 启用日志模块log.setLevel(logging.NOTSET)any_err_stream = Falseany_err_dumping = Falseany_did_dump = Falsefor container, filename, data \in xglob.iter_files(ole_files,recursive=False,zip_password=None,zip_fname='*'):if container and filename.endswith('/'):continue# 输出文件夹err_stream, err_dumping, did_dump = \process_file(filename, data, output_dir)any_err_stream |= err_streamany_err_dumping |= err_dumpingany_did_dump |= did_dumpreturn_val = RETURN_NO_DUMPif any_did_dump:return_val += RETURN_DID_DUMPif any_err_stream:return_val += RETURN_ERR_STREAMif any_err_dumping:return_val += RETURN_ERR_DUMPreturn return_valdef export_ole_file(ole_files, output_dir, debug=False):debug_leve = 'critical'if debug:debug_leve = 'info'# 导出result = export_main(ole_files,output_dir,debug_leve)if result and debug:print('导出ole文件出错', ole_files)

在提取文件的代码后面加上如下调用:

if str(rel.target_ref).startswith('embeddings'):# 解压嵌入式文件export_ole_file([file_path], output_dir)

再次运行

成功导出嵌入到Word中的文件!

成功解决问题~

资源

oletools:https://gitee.com/yunqimg/oletools

本项目:https://gitcode.net/XiaoYuHaoAiMin/export_docx_media_file

本项目打包:https://download.csdn.net/download/XiaoYuHaoAiMin/85643779

参考文档

https://blog.csdn.net/culun797375/article/details/108840682 (手动提取)

https://github.com/decalage2/oletools (本次主角之一oletools的仓库)

https://gitee.com/yunqimg/oletools (oletools在gitee上的副本)

https://blog.csdn.net/u011420268/article/details/106402153 (插入附件,想参考其普通文件如何转ole的,但是好像没转ole格式)

https://blog.csdn.net/lly1122334/article/details/109669667 (python-docx的使用)

https://zhuanlan.zhihu.com/p/446557096(oletools教程)

https://blog.csdn.net/tixxxa/article/details/120429483 (导出附件Python实现,没用oletools,好像不行,有兴趣的同志可以研究下)

https://blog.csdn.net/Cody_Ren/article/details/103886098 (ole文件结构,发现oletools后放弃自己写了)

https://blog.csdn.net/m0_60574457/article/details/119279798 (oletools中文教程,好像是readme.md翻译过来的)

【Python】批量导出word文档中的图片、嵌入式文件相关推荐

  1. python批量提取word文档中的图片(含图片格式转换和GUI)

    作者:小小明 文章目录 doc格式批量转为docx 批量提取docx文档的图片 批量图片格式转换 完整代码 GUI图形化工具开发 打包exe 给GUI加入进度条 日常工作中,领导要求你将一份 Word ...

  2. 使用Python批量提取Word文档中的图片

    1.导入需要的包 import zipfile import shuti 2.设置文档路径和图片路径 ,并用zipfile读取Word文件 doc_path = './a.docx' #在这里更换你想 ...

  3. 办公室小姐姐的福利!用Python批量提取word文档中的表格和图片内容

    点上方"菜鸟学Python",选择"星标" 第491篇原创干货,第一时间送达 最近有许多小伙伴想要一些自动化办公的福利小程序,今天就满足大家的需求.日常的办公过 ...

  4. ChatGPT搞砸了~,如何使用VBA导出Word文档中的图片

    今年大火的ChatGPT似乎无所不能,但是它的确不是万能的,咱们来试试. 提供的代码根本无法运行,继续问,换了个代码,非常不幸的是–还是不能用. Word VBA中并没有内置的方法可以直接导出图片,C ...

  5. Python批量修改Word文档中特定关键字的颜色

    关于Word文件的大致结构请参考使用Python写入docx文件并控制字体颜色 代码功能:读取docx文档中的文字,在尽量不影响原来字体样式的情况下,只把特定的文字都修改为红色. 表格中的文字请参考P ...

  6. 通过VBA导出word文档中的图片

    一.问题重述: 工作中,经常有同事把新闻的照片贴在word文档中发过来,需要把照片一张张的转存成图片. 二.原始方法: 在文档中的照片上,右键,图片另存为-- 把文档,按F12,另存为网页文件,然后在 ...

  7. 5导出word_妙招技法 | 教你如何快速导出Word文档中的图片

    关注[新精英充电站]能力提升看得见! 我们在翻阅一些比较好的Word文档时,经常想要将文档中用到的一些好的图片素材保留下来,但却苦于不知道怎么保存,最后只有无奈放弃. 其实,Word中提供有导出图片的 ...

  8. java poi在word文档中插入图片后文件无法打开

    错误情况 POI生成的word文档包含图片时用office打开失败,提示错误.但是用wps却可以打开. 原因分析 这是因为poi本身的问题,单纯的插入图片是不显示的,可以使用如下处理方式createP ...

  9. 怎么样才可批量导出word文档中的照片 不再一张一张的另存为!

    再也不用一个一个的另存为啦. 果然,重复的操作都可以用计算机来解决! 点击另存为,格式选为HTML. 可以直接保存到桌面. 点击保存之后: (图片内容不是重点.) 原来的.doc文件就变成了.html ...

最新文章

  1. elasticsearch 安装
  2. 你应该使用Java8 非阻塞异步API来优化你的系统了
  3. 树莓派应用实例3:环境光照强度测量
  4. 拍照时不会摆Pose怎么办?
  5. 那些 Linux 下好用的 小工具 收集
  6. 「禾连健康」轻松实现弹性降本20%以上,竟然是因为使用了它!
  7. Python 3.5.2 TypeError: a bytes-like object is required, not 'str’问题解决方案
  8. java实参将数据传递给形参的两种形式
  9. 一个简简单单检测http服务状态的脚本
  10. 自动生成getter,setter方法的插件lombok
  11. CF724G. Xor-matic Number of the Graph
  12. 应用百花齐放,呈现北浙苏沪粤五极格局丨2021年中国区块链产业发展报告产业应用篇...
  13. CC2530单片机开发--串口
  14. 阿里云国际版账户登录不上去什么原因?
  15. sir模型初始值_SIR模型简单了解(Susceptible Infected Recovered Model)
  16. vim 安装YouCompleteMe 插件
  17. c++ 线程进度条_AMD R9 5900X 跑分曝光,单线程性能大幅提升;天猫“官宣”苹果iPhone 12:暗示10月16日开启预定...
  18. obs直播软件 android,斗鱼游戏直播教程-OBS直播软件篇
  19. Linux虚拟机的远程三种链接,以及各自的上网方式
  20. 码刀客-pandas中将一张表中数据拆分成多个sheet_name

热门文章

  1. BERT通俗笔记:从Word2Vec/Transformer逐步理解到BERT
  2. oracle缓冲区闩锁类型,等待缓冲区闩锁时出现超时 -- 类型 4
  3. js中使用btoa和atob进行Base64的编码和解码
  4. 医学影像工作站程序ProDicom的说明
  5. php如何开发调色器,HTML5+Js制作的一款简易调色器
  6. uefi装完系统后无法引导_uefi模式怎么重装系统|uefi重装系统教程
  7. 音标、音节、音素、音符
  8. C语言中的找特殊数字问题
  9. 从人人网“死亡”看“级联”效应
  10. 堆晶结构_堆晶岩形成条件