1. 程式人生 > 實用技巧 >老闆又出難題,氣得我寫了個自動化軟體

老闆又出難題,氣得我寫了個自動化軟體

此文轉載自:https://blog.csdn.net/zhuxiao5/article/details/112418631


作者:小小明,Pandas資料處理專家,致力於幫助無數資料從業者解決資料處理難題

編輯:朱小五,一隻不務正業的資料狗

日常工作中,領導要求你將一份 Word 文件中的圖片儲存到一個資料夾內,你可能會一邊內心崩潰,一邊開始一張張的 另存為

但假如領導要求你將幾百個word文件中的圖片全部都拷貝出來,你是不是打算離職不幹了?

就比如下面這些word文件中的圖片,你能否快速的把所有圖片都拷貝出來呢?

如果老朋友們看過這篇文章《老闆讓我從Word中複製出1000張圖片?》的話,就應該知道怎麼做了。

不過,上次分享的這種方法還是有缺陷的:把word文件用壓縮檔案開啟,逐個解壓的話依然會耗時較長時間,另外裡面摻雜了doc格式的word文件,你還需將這些03版本的word文件另存為docx格式。

今天,將給大家展示一下全新版本!!!

寫個程式,十秒內全部給你轉換完畢,並把圖片都提取出來,還能批量從真實修改圖片格式,而不是簡單的修改一下副檔名。

(文末附帶exe可執行程式)

下面開始展示

doc格式批量轉為docx

python提供了win32com模組,其中的SaveAs方法可以代替人手批量將檔案另存為我們需要的格式。

win32com包含在pypiwin32模組中,只需安裝pypiwin32模組即可:

pipinstallpypiwin32

下面的程式碼將指定目錄下的doc檔案轉換為docx格式,並放在該目錄的temp_dir下面:

fromwin32comimportclientaswc#匯入模組
frompathlibimportPath
importos
importshutil

doc_path=r"E:\tmp\答疑整理"
temp_dir="temp"
ifos.path.exists(f"{doc_path}/{temp_dir}"):
shutil.rmtree(f"{doc_path}/{temp_dir}")
os.mkdir(f"{doc_path}/{temp_dir}")

word=wc.Dispatch("Word.Application")#開啟word應用程式
try:
forfilenameinPath(doc_path).glob("*.doc"):
file=str(filename)
dest_name=str(filename.parent/f"{temp_dir}"/str(filename.name))+"x"
print(file,dest_name)
doc=word.Documents.Open(file)#開啟word檔案
doc.SaveAs(dest_name,12)#另存為字尾為".docx"的檔案,其中引數12指docx檔案
finally:
word.Quit()

執行結果:

轉換得到的檔案:

批量提取docx文件的圖片

docx文件其實也是一個zip壓縮包,所以我們可以通過zip包解壓它,下面的程式碼將解壓每個docx文件中的圖片,我將其移動到臨時目錄下的imgs目錄下:

importitertools
fromzipfileimportZipFile
importshutil

ifos.path.exists(f"{doc_path}/{temp_dir}/imgs"):
shutil.rmtree(f"{doc_path}/{temp_dir}/imgs")
os.makedirs(f"{doc_path}/{temp_dir}/imgs")

i=1
forfilenameinitertools.chain(Path(doc_path).glob("*.docx"),(Path(doc_path)/temp_dir).glob("*.docx")):
print(filename)
withZipFile(filename)aszip_file:
fornamesinzip_file.namelist():
ifnames.startswith("word/media/image"):
zip_file.extract(names,doc_path)
os.rename(f"{doc_path}/{names}",
f"{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
print("\t",names,f"{i}{names[names.find('.'):]}")
i+=1
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安裝:

pipinstallpillow

直接修改副檔名並不能真實的修改圖片格式,通過pillow庫我們即可將圖片批量真實的轉換為jpg格式:

fromPILimportImage

ifnotos.path.exists(f"{doc_path}/imgs"):
os.mkdir(f"{doc_path}/imgs")

forfilenameinPath(f"{doc_path}/{temp_dir}/imgs").glob("*"):
file=str(filename)
withImage.open(file)asim:
im.convert('RGB').save(
f"{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg",'jpeg')

轉換後:

完整程式碼

#!/usr/bin/envpython3
#-*-coding:utf-8-*-
#建立時間:2020/12/25 21:46
__author__='xiaoxiaoming'

importitertools
importos
importshutil
frompathlibimportPath
fromzipfileimportZipFile

fromPILimportImage
fromwin32comimportclientaswc#匯入模組


defword_img_extract(doc_path,temp_dir):
ifos.path.exists(f"{doc_path}/{temp_dir}"):
shutil.rmtree(f"{doc_path}/{temp_dir}")
os.mkdir(f"{doc_path}/{temp_dir}")

word=wc.Dispatch("Word.Application")#開啟word應用程式
try:
forfilenameinPath(doc_path).glob("*.doc"):
file=str(filename)
dest_name=str(filename.parent/f"{temp_dir}"/str(filename.name))+"x"
print(file,dest_name)
doc=word.Documents.Open(file)#開啟word檔案
doc.SaveAs(dest_name,12)#另存為字尾為".docx"的檔案,其中引數12指docx檔案
finally:
word.Quit()

ifos.path.exists(f"{doc_path}/{temp_dir}/imgs"):
shutil.rmtree(f"{doc_path}/{temp_dir}/imgs")
os.makedirs(f"{doc_path}/{temp_dir}/imgs")

i=1
forfilenameinitertools.chain(Path(doc_path).glob("*.docx"),(Path(doc_path)/temp_dir).glob("*.docx")):
print(filename)
withZipFile(filename)aszip_file:
fornamesinzip_file.namelist():
ifnames.startswith("word/media/image"):
zip_file.extract(names,doc_path)
os.rename(f"{doc_path}/{names}",
f"{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
print("\t",names,f"{i}{names[names.find('.'):]}")
i+=1
shutil.rmtree(f"{doc_path}/word")

ifnotos.path.exists(f"{doc_path}/imgs"):
os.mkdir(f"{doc_path}/imgs")

forfilenameinPath(f"{doc_path}/{temp_dir}/imgs").glob("*"):
file=str(filename)
withImage.open(file)asim:
im.convert('RGB').save(
f"{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg",'jpeg')


if__name__=='__main__':
doc_path=r"E:\tmp\答疑整理"
temp_dir="temp"
word_img_extract(doc_path,temp_dir)

最終全部執行完成耗時7s:

GUI圖形化工具開發

下面使用PySimpleGUI開發一個圖形化工具,使用以下命令安裝該庫:

pipinstallPySimpleGUI

如果是下載速度慢的可以用下面的清華映象地址下載:

pipinstallPySimpleGUI-ihttps://pypi.tuna.tsinghua.edu.cn/simple

以下是完整程式碼:

importPySimpleGUIassg

fromword_img_extractimportword_img_extract

sg.change_look_and_feel("GreenMono")

layout=[
[
sg.Text("請輸入word文件所在的目錄:"),
sg.In(size=(25,1),enable_events=True,key="-FOLDER-"),
sg.FolderBrowse('瀏覽'),
],[
sg.Button('開始抽取',enable_events=True,key="抽取"),
sg.Text(size=(40,1),key="-TOUT-")
]
]
window=sg.Window('word文件圖片抽取系統',layout)
whileTrue:
event,values=window.read()
ifeventin(None,):
break#相當於關閉介面
elifevent=="抽取":
ifvalues["-FOLDER-"]:
window["-TOUT-"].update("準備抽取!!!")
sg.popup('抽取期間程式將處於假死狀態,請稍等片刻,提取完成後會彈出提示!!!\n點選ok後開始抽取!!!')
window["-TOUT-"].update("正在抽取中...")
word_img_extract(values["-FOLDER-"])
window["-TOUT-"].update("抽取完畢!!!")
sg.popup('抽取完畢!!!')
else:
sg.popup('請先輸入word文件所在的路徑!!!')
print(f'Event:{event},values:{values}')
window.close()

執行效果:

打包exe

建立並激活虛擬環境:

condacreate-nguipython=3.6
condaactivategui

注意:建立虛擬環境和啟用環境並不是必須,只是為了精簡環境,可以跳過

安裝打包所用的包:

pipinstallPySimpleGUI
pipinstallpillow
pipinstallpywin32
pipinstallpyinstaller

執行以下命令進行打包:

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

常用引數說明:

  • -F 表示生成單個可執行檔案

  • -w 表示去掉控制檯視窗,這在GUI介面時非常有用。不過如果是命令列程式的話那就把這個選項刪除吧!

  • -p 表示你自己自定義需要載入的類路徑,一般情況下用不到

  • -i 表示可執行檔案的圖示

打包結果:

帶上-w引數打包,可以去掉控制檯:

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

給GUI加入進度條

改造處理程式,藉助生成器反饋程式的處理進度,完整程式碼如下:

importitertools
importos
importshutil
frompathlibimportPath
fromzipfileimportZipFile

fromPILimportImage
fromwin32comimportclientaswc#匯入模組

defword_img_extract(doc_path,temp_dir="temp"):
ifos.path.exists(f"{doc_path}/{temp_dir}"):
shutil.rmtree(f"{doc_path}/{temp_dir}")
os.mkdir(f"{doc_path}/{temp_dir}")

word=wc.Dispatch("Word.Application")#開啟word應用程式
try:
files=list(Path(doc_path).glob("*.doc"))
iflen(files)==0:
raiseException("當前目錄中沒有word文件")
fori,filenameinenumerate(files,1):
file=str(filename)
dest_name=str(filename.parent/f"{temp_dir}"/str(filename.name))+"x"
#print(file,dest_name)
doc=word.Documents.Open(file)#開啟word檔案
doc.SaveAs(dest_name,12)#另存為字尾為".docx"的檔案,其中引數12指docx檔案
yield"word doc格式轉docx格式:",i*1000//len(files)
finally:
word.Quit()

ifos.path.exists(f"{doc_path}/{temp_dir}/imgs"):
shutil.rmtree(f"{doc_path}/{temp_dir}/imgs")
os.makedirs(f"{doc_path}/{temp_dir}/imgs")

i=1
files=list(itertools.chain(Path(doc_path).glob("*.docx"),(Path(doc_path)/temp_dir).glob("*.docx")))
forj,filenameinenumerate(files,1):
#print(filename)
withZipFile(filename)aszip_file:
fornamesinzip_file.namelist():
ifnames.startswith("word/media/image"):
zip_file.extract(names,doc_path)
os.rename(f"{doc_path}/{names}",
f"{doc_path}/{temp_dir}/imgs/{i}{names[names.find('.'):]}")
#print("\t",names,f"{i}{names[names.find('.'):]}")
i+=1
yield"word提取圖片:",j*1000//len(files)
shutil.rmtree(f"{doc_path}/word")

ifnotos.path.exists(f"{doc_path}/imgs"):
os.mkdir(f"{doc_path}/imgs")

files=list(Path(f"{doc_path}/{temp_dir}/imgs").glob("*"))
fori,filenameinenumerate(files,1):
file=str(filename)
withImage.open(file)asim:
im.convert('RGB').save(
f"{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg",'jpeg')
yield"圖片轉換為jpg格式:",i*1000//len(files)


if__name__=='__main__':
doc_path=r"E:\tmp\答疑整理"
formsg,iinword_img_extract(doc_path):
print(f"\r{msg}{i}",end="")

GUI程式的最終完整程式碼:

importPySimpleGUIassg

fromword_img_extractimportword_img_extract

sg.change_look_and_feel("GreenMono")

layout=[
[
sg.Text("請輸入word文件所在的目錄:"),
sg.In(size=(25,1),enable_events=True,key="-FOLDER-"),
sg.FolderBrowse('瀏覽'),
],[
sg.Button('開始抽取',enable_events=True,key="抽取"),
sg.Text(text_color="red",size=(47,2),key="error"),
],[
sg.Text("準備:",size=(20,1),key="-TOUT-"),
sg.ProgressBar(1000,orientation='h',size=(35,20),key='progressbar')
]
]
window=sg.Window('word文件圖片抽取系統',layout)
whileTrue:
event,values=window.read()
ifeventin(None,):
break#相當於關閉介面
elifevent=="抽取":
ifvalues["-FOLDER-"]:
window["error"].update("")
try:
formsg,iinword_img_extract(values["-FOLDER-"]):
window["-TOUT-"].update(msg)
window['progressbar'].UpdateBar(i)
window["-TOUT-"].update('抽取完畢!!!')
exceptExceptionase:
window["error"].update(str(e))
else:
sg.popup('請先輸入word文件所在的路徑!!!')
window.close()

重新打包:

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

執行效果:

exe下載

如果有小夥伴對程式碼不感興趣,想直接使用打包好的exe軟體,掃碼關注「快學Python」(非本號)後臺回覆“0109” ,獲取完整程式碼:

後臺回覆“ 0109”獲取完整程式碼

凹凸福利

????《Python高手修煉之道:資料處理與機器學習實戰》Python資料分析視覺化程式設計入門零基礎從入門到精通Python的Numpy、Matplotlib、Pandas、SciPy、Scikit-Learn工具包,提供了完整可驗證的程式碼。點選下圖可看詳情/購買!????

感謝人民郵電出版社支援!週日統一兌換!後臺回覆“讀書會”進群,獲取最新書籍資訊!後臺“左下菜單欄”輕鬆賺幣,免費包郵帶回家!