小言_互联网的博客

老板又出难题,气得我写了个自动化软件

250人阅读  评论(0)

作者:小小明

编辑:朱小五

1024G_Python、数据分析学习资源,免费送(点击)

日常工作中,领导要求你将一份 Word 文档中的图片存储到一个文件夹内,你可能会一边内心崩溃,一边开始一张张的 另存为

但假如领导要求你将几百个word文档中的图片全部都拷贝出来,你是不是打算离职不干了?

就比如下面这些word文档中的图片,你能否快速的把所有图片都拷贝出来呢?

如果老朋友们看过这篇文章《老板让我从Word中复制出1000张图片?》的话,就应该知道怎么做了。

不过,上次分享的这种方法还是有缺陷的:把word文档用压缩文件打开,逐个解压的话依然会耗时较长时间,另外里面掺杂了doc格式的word文档,你还需将这些03版本的word文档另存为docx格式。

今天,将给大家展示一下全新版本!!!

写个程序,十秒内全部给你转换完毕,并把图片都提取出来,还能批量从真实修改图片格式,而不是简单的修改一下扩展名。

(文末附带exe可执行程序)

下面开始展示

doc格式批量转为docx

python提供了win32com模块,其中的SaveAs方法可以代替人手批量将文件另存为我们需要的格式。

win32com包含在pypiwin32模块中,只需安装pypiwin32模块即可:

pip install pypiwin32

下面的代码将指定目录下的doc文件转换为docx格式,并放在该目录的temp_dir下面:


   
  1. from win32com  import client as wc  # 导入模块
  2. from pathlib  import Path
  3. import os
  4. import shutil
  5. doc_path = r "E:\tmp\答疑整理"
  6. temp_dir =  "temp"
  7. if os.path.exists(f "{doc_path}/{temp_dir}"):
  8.     shutil.rmtree(f "{doc_path}/{temp_dir}")
  9. os.mkdir(f "{doc_path}/{temp_dir}")
  10. word = wc.Dispatch( "Word.Application")  # 打开word应用程序
  11. try:
  12.      for filename in Path(doc_path).glob( "*.doc"):
  13.         file = str(filename)
  14.         dest_name = str(filename.parent/f "{temp_dir}"/str(filename.name))+ "x"
  15.          print(file, dest_name)
  16.         doc = word.Documents.Open(file)  # 打开word文件
  17.         doc.SaveAs(dest_name,  12)  # 另存为后缀为 ".docx"的文件,其中参数 12指docx文件
  18. finally:
  19.     word.Quit()

运行结果:

转换得到的文件:

批量提取docx文档的图片

docx文档其实也是一个zip压缩包,所以我们可以通过zip包解压它,下面的代码将解压每个docx文档中的图片,我将其移动到临时目录下的imgs目录下:


   
  1. import itertools
  2. from zipfile  import ZipFile
  3. import shutil
  4. if os.path.exists(f "{doc_path}/{temp_dir}/imgs"):
  5.     shutil.rmtree(f "{doc_path}/{temp_dir}/imgs")
  6. os.makedirs(f "{doc_path}/{temp_dir}/imgs")
  7. i =  1
  8. for filename in itertools.chain(Path(doc_path).glob( "*.docx"), (Path(doc_path)/temp_dir).glob( "*.docx")):
  9.      print(filename)
  10.     with ZipFile(filename) as zip_file:
  11.          for names in zip_file.namelist():
  12.              if names.startswith( "word/media/image"):
  13.                 zip_file.extract(names, doc_path)
  14.                 os.rename(f "{doc_path}/{names}",
  15.                           f "{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
  16.                  print( "\t", names, f "{i}{names[names.find('.'):]}")
  17.                 i +=  1
  18. shutil.rmtree(f "{doc_path}/word")

打印结果:

提取结果:

批量图片格式转换

PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却非常简单易用。

由于PIL仅支持到Python 2.7,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。

如果安装了Anaconda,Pillow就已经可用了。否则,需要在命令行下通过pip安装:

pip install pillow

直接修改文件扩展名并不能真实的修改图片格式,通过pillow库我们即可将图片批量真实的转换为jpg格式:


   
  1. from PIL  import Image
  2. if not os.path.exists(f "{doc_path}/imgs"):
  3.     os.mkdir(f "{doc_path}/imgs")
  4. for filename in Path(f "{doc_path}/{temp_dir}/imgs").glob( "*"):
  5.     file = str(filename)
  6.     with Image.open(file) as im:
  7.         im.convert( 'RGB').save(
  8.             f "{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg"'jpeg')

转换后:

完整代码


   
  1. #!/usr/bin/env python3
  2. # -*- coding: utf -8 -*-
  3. # 创建时间: 2020/ 12/ 25 21: 46
  4. __author__ =  'xiaoxiaoming'
  5. import itertools
  6. import os
  7. import shutil
  8. from pathlib  import Path
  9. from zipfile  import ZipFile
  10. from PIL  import Image
  11. from win32com  import client as wc  # 导入模块
  12. def word_img_extract(doc_path, temp_dir):
  13.      if os.path.exists(f "{doc_path}/{temp_dir}"):
  14.         shutil.rmtree(f "{doc_path}/{temp_dir}")
  15.     os.mkdir(f "{doc_path}/{temp_dir}")
  16.     word = wc.Dispatch( "Word.Application")  # 打开word应用程序
  17.     try:
  18.          for filename in Path(doc_path).glob( "*.doc"):
  19.             file = str(filename)
  20.             dest_name = str(filename.parent / f "{temp_dir}" / str(filename.name)) +  "x"
  21.              print(file, dest_name)
  22.             doc = word.Documents.Open(file)  # 打开word文件
  23.             doc.SaveAs(dest_name,  12)  # 另存为后缀为 ".docx"的文件,其中参数 12指docx文件
  24.     finally:
  25.         word.Quit()
  26.      if os.path.exists(f "{doc_path}/{temp_dir}/imgs"):
  27.         shutil.rmtree(f "{doc_path}/{temp_dir}/imgs")
  28.     os.makedirs(f "{doc_path}/{temp_dir}/imgs")
  29.     i =  1
  30.      for filename in itertools.chain(Path(doc_path).glob( "*.docx"), (Path(doc_path) / temp_dir).glob( "*.docx")):
  31.          print(filename)
  32.         with ZipFile(filename) as zip_file:
  33.              for names in zip_file.namelist():
  34.                  if names.startswith( "word/media/image"):
  35.                     zip_file.extract(names, doc_path)
  36.                     os.rename(f "{doc_path}/{names}",
  37.                               f "{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
  38.                      print( "\t", names, f "{i}{names[names.find('.'):]}")
  39.                     i +=  1
  40.     shutil.rmtree(f "{doc_path}/word")
  41.      if not os.path.exists(f "{doc_path}/imgs"):
  42.         os.mkdir(f "{doc_path}/imgs")
  43.      for filename in Path(f "{doc_path}/{temp_dir}/imgs").glob( "*"):
  44.         file = str(filename)
  45.         with Image.open(file) as im:
  46.             im.convert( 'RGB').save(
  47.                 f "{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg"'jpeg')
  48. if __name__ ==  '__main__':
  49.     doc_path = r "E:\tmp\答疑整理"
  50.     temp_dir =  "temp"
  51.     word_img_extract(doc_path, temp_dir)

最终全部执行完成耗时7s:

GUI图形化工具开发

下面使用PySimpleGUI开发一个图形化工具,使用以下命令安装该库:

pip install PySimpleGUI

如果是下载速度慢的可以用下面的清华镜像地址下载:

pip install PySimpleGUI -i https://pypi.tuna.tsinghua.edu.cn/simple

以下是完整代码:


   
  1. import PySimpleGUI as sg
  2. from word_img_extract  import word_img_extract
  3. sg.change_look_and_feel( "GreenMono")
  4. layout = [
  5.     [
  6.         sg.Text( "请输入word文档所在的目录:"),
  7.         sg.In(size=( 251), enable_events=True, key= "-FOLDER-"),
  8.         sg.FolderBrowse( '浏览'),
  9.     ], [
  10.         sg.Button( '开始抽取', enable_events=True, key= "抽取"),
  11.         sg.Text(size=( 401), key= "-TOUT-")
  12.     ]
  13. ]
  14. window = sg.Window( 'word文档图片抽取系统', layout)
  15. while True:
  16.     event, values = window.read()
  17.      if event in (None,):
  18.          break  # 相当于关闭界面
  19.     elif event ==  "抽取":
  20.          if values[ "-FOLDER-"]:
  21.             window[ "-TOUT-"].update( "准备抽取!!!")
  22.             sg.popup( '抽取期间程序将处于假死状态,请稍等片刻,提取完成后会弹出提示!!!\n点击ok后开始抽取!!!')
  23.             window[ "-TOUT-"].update( "正在抽取中...")
  24.             word_img_extract(values[ "-FOLDER-"])
  25.             window[ "-TOUT-"].update( "抽取完毕!!!")
  26.             sg.popup( '抽取完毕!!!')
  27.          else:
  28.             sg.popup( '请先输入word文档所在的路径!!!')
  29.      print(f 'Event: {event}, values: {values}')
  30. window. close()

运行效果:

打包exe

创建并激活虚拟环境:


   
  1. conda create -n gui python= 3.6
  2. conda activate gui

注意:创建虚拟环境和激活环境并不是必须,只是为了精简环境,可以跳过

安装打包所用的包:


   
  1. pip install PySimpleGUI
  2. pip install pillow
  3. pip install pywin32
  4. pip install pyinstaller

执行以下命令进行打包:

pyinstaller -F --icon=C:\Users\Think\Pictures\ico\ooopic_1467046829.ico word_img_extract_GUI.py

常用参数说明:

  • -F 表示生成单个可执行文件

  • -w 表示去掉控制台窗口,这在GUI界面时非常有用。不过如果是命令行程序的话那就把这个选项删除吧!

  • -p 表示你自己自定义需要加载的类路径,一般情况下用不到

  • -i 表示可执行文件的图标

打包结果:

带上-w参数打包,可以去掉控制台:

pyinstaller -wF --icon=C:\Users\Think\Pictures\ico\ooopic_1467046829.ico word_img_extract_GUI.py

给GUI加入进度条

改造处理程序,借助生成器反馈程序的处理进度,完整代码如下:


   
  1. import itertools
  2. import os
  3. import shutil
  4. from pathlib  import Path
  5. from zipfile  import ZipFile
  6. from PIL  import Image
  7. from win32com  import client as wc  # 导入模块
  8. def word_img_extract(doc_path, temp_dir= "temp"):
  9.      if os.path.exists(f "{doc_path}/{temp_dir}"):
  10.         shutil.rmtree(f "{doc_path}/{temp_dir}")
  11.     os.mkdir(f "{doc_path}/{temp_dir}")
  12.     word = wc.Dispatch( "Word.Application")  # 打开word应用程序
  13.     try:
  14.         files = list(Path(doc_path).glob( "*.doc"))
  15.          if  len(files) ==  0:
  16.             raise Exception( "当前目录中没有word文档")
  17.          for i, filename in enumerate(files,  1):
  18.             file = str(filename)
  19.             dest_name = str(filename.parent / f "{temp_dir}" / str(filename.name)) +  "x"
  20.             #  print(file, dest_name)
  21.             doc = word.Documents.Open(file)  # 打开word文件
  22.             doc.SaveAs(dest_name,  12)  # 另存为后缀为 ".docx"的文件,其中参数 12指docx文件
  23.             yield  "word doc格式转docx格式:", i *  1000  // len(files)
  24.     finally:
  25.         word.Quit()
  26.      if os.path.exists(f "{doc_path}/{temp_dir}/imgs"):
  27.         shutil.rmtree(f "{doc_path}/{temp_dir}/imgs")
  28.     os.makedirs(f "{doc_path}/{temp_dir}/imgs")
  29.     i =  1
  30.     files = list(itertools.chain(Path(doc_path).glob( "*.docx"), (Path(doc_path) / temp_dir).glob( "*.docx")))
  31.      for j, filename in enumerate(files,  1):
  32.         #  print(filename)
  33.         with ZipFile(filename) as zip_file:
  34.              for names in zip_file.namelist():
  35.                  if names.startswith( "word/media/image"):
  36.                     zip_file.extract(names, doc_path)
  37.                     os.rename(f "{doc_path}/{names}",
  38.                               f "{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
  39.                     #  print( "\t", names, f "{i}{names[names.find('.'):]}")
  40.                     i +=  1
  41.         yield  "word提取图片:", j *  1000  // len(files)
  42.     shutil.rmtree(f "{doc_path}/word")
  43.      if not os.path.exists(f "{doc_path}/imgs"):
  44.         os.mkdir(f "{doc_path}/imgs")
  45.     files = list(Path(f "{doc_path}/{temp_dir}/imgs").glob( "*"))
  46.      for i, filename in enumerate(files,  1):
  47.         file = str(filename)
  48.         with Image.open(file) as im:
  49.             im.convert( 'RGB').save(
  50.                 f "{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg"'jpeg')
  51.         yield  "图片转换为jpg格式:", i *  1000  // len(files)
  52. if __name__ ==  '__main__':
  53.     doc_path = r "E:\tmp\答疑整理"
  54.      for msg, i in word_img_extract(doc_path):
  55.          print(f "\r {msg}{i}", end= "")

GUI程序的最终完整代码:


   
  1. import PySimpleGUI as sg
  2. from word_img_extract  import word_img_extract
  3. sg.change_look_and_feel( "GreenMono")
  4. layout = [
  5.     [
  6.         sg.Text( "请输入word文档所在的目录:"),
  7.         sg.In(size=( 251), enable_events=True, key= "-FOLDER-"),
  8.         sg.FolderBrowse( '浏览'),
  9.     ], [
  10.         sg.Button( '开始抽取', enable_events=True, key= "抽取"),
  11.         sg.Text(text_color= "red", size=( 472), key= "error"),
  12.     ], [
  13.         sg.Text( "准备:", size=( 201), key= "-TOUT-"),
  14.         sg.ProgressBar( 1000, orientation= 'h', size=( 3520), key= 'progressbar')
  15.     ]
  16. ]
  17. window = sg.Window( 'word文档图片抽取系统', layout)
  18. while True:
  19.     event, values = window.read()
  20.      if event in (None,):
  21.          break  # 相当于关闭界面
  22.     elif event ==  "抽取":
  23.          if values[ "-FOLDER-"]:
  24.             window[ "error"].update( "")
  25.             try:
  26.                  for msg, i in word_img_extract(values[ "-FOLDER-"]):
  27.                     window[ "-TOUT-"].update(msg)
  28.                     window[ 'progressbar'].UpdateBar(i)
  29.                 window[ "-TOUT-"].update( '抽取完毕!!!')
  30.             except Exception as e:
  31.                 window[ "error"].update(str(e))
  32.          else:
  33.             sg.popup( '请先输入word文档所在的路径!!!')
  34. window. close()

重新打包:

pyinstaller -wF --icon=C:\Users\Think\Pictures\ico\ooopic_1467046829.ico word_img_extract_GUI.py

1024G_Python、数据分析学习资源,免费送(点击)

运行效果:

exe下载

如果有小伙伴对代码不感兴趣,想直接使用打包好的exe软件,扫码关注「快学Python」(非本号)后台回复“0109” ,获取完整代码:

后台回复“ 0109”获取完整代码

 

1024G_Python、数据分析学习资源,免费送(点击)


转载:https://blog.csdn.net/zhuxiao5/article/details/112418631
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场