用Python拷貝word圖片到指定文件

2021-03-06 快學Python


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

編輯:朱小五,一隻不務正業的數據狗

日常工作中,領導要求你將一份 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下面:

from win32com import client as wc  # 導入模塊
from pathlib import Path
import os
import shutil

doc_path = r"E:\tmp\答疑整理"
temp_dir = "temp"
if os.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:
    for filename in Path(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目錄下:

import itertools
from zipfile import ZipFile
import shutil

if os.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
for filename in itertools.chain(Path(doc_path).glob("*.docx"), (Path(doc_path)/temp_dir).glob("*.docx")):
    print(filename)
    with ZipFile(filename) as zip_file:
        for names in zip_file.namelist():
            if names.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安裝:

pip install pillow

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

from PIL import Image

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

for filename in Path(f"{doc_path}/{temp_dir}/imgs").glob("*"):
    file = str(filename)
    with Image.open(file) as im:
        im.convert('RGB').save(
            f"{doc_path}/imgs/{filename.name[:filename.name.find('.')]}.jpg", 'jpeg')

轉換後:

完整代碼
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 創建時間:2020/12/25 21:46
__author__ = 'xiaoxiaoming'

import itertools
import os
import shutil
from pathlib import Path
from zipfile import ZipFile

from PIL import Image
from win32com import client as wc  # 導入模塊


def word_img_extract(doc_path, temp_dir):
    if os.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:
        for filename in Path(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()

    if os.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
    for filename in itertools.chain(Path(doc_path).glob("*.docx"), (Path(doc_path) / temp_dir).glob("*.docx")):
        print(filename)
        with ZipFile(filename) as zip_file:
            for names in zip_file.namelist():
                if names.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")

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

    for filename in Path(f"{doc_path}/{temp_dir}/imgs").glob("*"):
        file = str(filename)
        with Image.open(file) as im:
            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開發一個圖形化工具,使用以下命令安裝該庫:

pip install PySimpleGUI

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

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

以下是完整代碼:

import PySimpleGUI as sg

from word_img_extract import word_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)
while True:
    event, values = window.read()
    if event in (None,):
        break  # 相當於關閉界面
    elif event == "抽取":
        if values["-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

創建並激活虛擬環境:

conda create -n gui python=3.6
conda activate gui

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

安裝打包所用的包:

pip install PySimpleGUI
pip install pillow
pip install pywin32
pip install pyinstaller

執行以下命令進行打包:

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

常用參數說明:

-w 表示去掉控制臺窗口,這在GUI界面時非常有用。不過如果是命令行程序的話那就把這個選項刪除吧!-p 表示你自己自定義需要加載的類路徑,一般情況下用不到

打包結果:

帶上-w參數打包,可以去掉控制臺:

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

給GUI加入進度條

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

import itertools
import os
import shutil
from pathlib import Path
from zipfile import ZipFile

from PIL import Image
from win32com import client as wc  # 導入模塊

def word_img_extract(doc_path, temp_dir="temp"):
    if os.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"))
        if len(files) == 0:
            raise Exception("當前目錄中沒有word文檔")
        for i, filename in enumerate(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()

    if os.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")))
    for j, filename in enumerate(files, 1):
        # print(filename)
        with ZipFile(filename) as zip_file:
            for names in zip_file.namelist():
                if names.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")

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

    files = list(Path(f"{doc_path}/{temp_dir}/imgs").glob("*"))
    for i, filename in enumerate(files, 1):
        file = str(filename)
        with Image.open(file) as im:
            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\答疑整理"
    for msg, i in word_img_extract(doc_path):
        print(f"\r {msg}{i}", end="")

GUI程序的最終完整代碼:

import PySimpleGUI as sg

from word_img_extract import word_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)
while True:
    event, values = window.read()
    if event in (None,):
        break  # 相當於關閉界面
    elif event == "抽取":
        if values["-FOLDER-"]:
            window["error"].update("")
            try:
                for msg, i in word_img_extract(values["-FOLDER-"]):
                    window["-TOUT-"].update(msg)
                    window['progressbar'].UpdateBar(i)
                window["-TOUT-"].update('抽取完畢!!!')
            except Exception as e:
                window["error"].update(str(e))
        else:
            sg.popup('請先輸入word文檔所在的路徑!!!')
window.close()

重新打包:

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

運行效果:

exe下載

如果有小夥伴對代碼不感興趣,想直接使用打包好的exe軟體,掃碼關注「快學Python」後臺回復「0109」 ,獲取完整代碼:

相關焦點

  • Linux下文件或文件夾的複製(拷貝)
    前言在linux中,經常會用到文件或者文件夾的複製,要做到將一個文件複製到本機的另一個位置,就要學會使用linux的cp命令;如果是把一個文件複製到可以訪問的網絡機器的某個位置,那麼就要用到scp命令,scp代表遠程拷貝。
  • 用Wordcloud生成指定形狀的詞雲圖
    wordcloud是Python擴展庫中一種將詞語用圖片表達出來的一種形式,通過詞雲生成的圖片,我們可以更加直觀的看出某篇文章的故事梗概
  • 從PPT到Word,用Python輕鬆實現辦公自動化
    Excel,也講過如何將多個 Excel 表格匯總至 Word,今天繼續講解如何將文字從 PPT 中提取出來並寫入 Word,主要將涉及如何使用 python-pptx 和 python-docx 交互操作 word 和 ppt 文件!
  • 第105天: Python 操作 Word
    寫入 Word平時我們在操作 Word 寫文檔的時候,一般分為幾部分:標題、章節、段落、圖片、表格、引用以及項目符號編號等。下面我們就按這幾部分如何用 Python 操作來一一介紹。('如何使用 Python 創建 Word',0)# 保存文件doc1.save('word1.docx')這樣就完成了創建文檔和文章標題的操作,下面通過命令 python word_1.py 運行程序,會生成名為 word1.docx 的文檔,打開文章顯示如下圖所示:
  • 實例15:用Python批量轉換doc文件為docx文件
    "): #排除文件夾內的其它幹擾文件,只獲取".doc"後綴的word文件 files.append(path+file) files>>['C:\\Users\\dywei\\python\\python_excel\\Exp15.Convert doc to docx\\data\\公司001合同.doc', 'C:\\Users
  • 【Python基礎】python使用python-docx操作word
    1、python-docx庫介紹該模塊兒可以創建、修改Word(.docx)文件;python-docx使用官網:python-docx官網我們在安裝此模塊兒使用的是pip install python-docx,但是在導入的時候是import docx;2、Python讀取Word文檔內容注意:每進行一個操作,必須保存一下,否則等於白做;1)word文檔結構介紹在這裡插入圖片描述2)python-docx
  • python 實用程序 | PDF 轉 Word
    於是乎我就想到了利用 python 來寫個程序,把 pdf 轉成 word 文檔。秉承著不要重複造輪子的想法,我首先在網上搜索了下。果然已經有人寫好了,我們直接拿來用就行。['word_folder'] + '/' + file_name + '.docx' print('正在處理: ', file) result = executor.submit(pdf_to_word, pdf_file, word_file) tasks.append
  • Python辦公自動化|從Excel到Word
    在前幾天的文章中我們講解了如何從Word表格中提取指定數據並按照格式保存到Excel中,今天我們將再次以一位讀者提出的真實需求來講解如何
  • Python中如何拷貝一個文件
    # 文件的拷貝import osimport shutil# os system()拷貝
  • Python 自動化辦公—Word 文本操作命令
    之前介紹了一個Python包 openpyxl ,用於處理 Excel ;而對於 Word 文本時同樣也有對應的 Python庫 Python-docx,在日常辦公中,如果需要處理多個 word 文本,且操作步驟都是重複單調的,我想這個庫就可以幫到你在了解 Python-docx 常用函數之前,需要知道 在 Python-docx 各命令所對應 word 各部件,下圖所示
  • python讀寫文件
    今天我們就以這幾個需求為背景來看看python是如何讀寫文件的。基本概念介紹我們知道python中一切都是對象,「文件」也不例外。下面的實驗可以看出文件是名叫『_io.TextIOWrapper』的class。
  • Python實戰009:讀取Word文檔中的表格數據及表格合併問題解決
    我現在要解析的word文檔中主要是表格、字符串、圖片等信息,我們主要是要拿到表格中的數據。     處理這類文檔數據當然優先考慮Python啦,python解析word文件可以使用包docx。現在我們繼續測試Word文件中包含合併的單元格表格,如果還是用上面的方法那麼合併的單元格內容會重複顯示。比如這裡的物品購買明細會出現4次,合計會出現3次,143會出現2次。
  • 14-用Python 讀寫 Excel 文件
    最大支持行數為1048576行),人們開始轉向python和R這樣的分析工具了XlsxWriterxlrd&xlwt[2]OpenPyXL[3]Microsoft Excel API[4]介紹可以創建 Excel 2007 或更高版本的 XLSX 文件即 python-excel,含 xlrd、xlwt 和 xlutils 三大模塊,分別提供讀、寫和其他功能可以讀寫 Excel
  • 用Python讀寫Word文檔入門
    今天,我們就來了解一下用Python讀寫Word文檔。和純文本(比如txt)相比, .docx文件有很多種結構,這些結構在python-docx中用3種不同的類型來表示:最高一層是Document對象表示文檔,每個Document對象包含一個Paragraph 對象也就是段落組成的列表,而每個Paragraph對象則包含一個Run對象的列表,至於Run對象大家可以通過下面的段落Paragraph來了解。
  • 聊聊python 辦公自動化之 Word(中)
    from docx import Document# 源文件目錄self.word_path = '.Word 文檔中的圖片下載到本地,Word 文檔實際上也是一個壓縮文件,我們使用解壓工具後發現,文檔包含的圖片都放置在/word/media/ 目錄下提取文檔圖片有 2 種方法,分別是:解壓文檔文件,將對應目錄下的圖片拷貝出來使用 python-docx
  • Python 自動化辦公 — Word 文本操作命令
    之前介紹了一個Python包  openpyxl ,用於處理 Excel ;而對於 Word 文本時同樣也有對應的 Python庫 Python-docx,在日常辦公中,如果需要處理多個 word 文本,且操作步驟都是重複單調的,我想這個庫就可以幫到你在了解 Python-docx
  • 從PDF拷貝文字至Word,如何處理更高效?試試這2招!
    一般來說有幾種方式:將整個PDF文件通過工具轉換成word文件,此類工具如smallPDF、ilovePDF等在線網站。但它的問題在於因為無法保證100%的準確率,故需要校核轉換之後的準確率,這比轉換本身要花的精力多得多; 如果是針對掃描件或者圖片形式的PDF,要提取它們中的文字,無法用直接轉換的方式,而要用其它途徑,如圖像文字識別(亦稱光學文字識別)(Optical Character Recognition,OCR),其可將圖片中的字符翻譯成文字,是當前比較熱門的一種算法
  • 基於python的OpenCV庫應用,將圖片轉化為視頻文件,程序打包發布
    如果你使用過python的畫圖庫matplotlib就知道,它其實只能生成靜態的圖片,如果我們想將實驗結果保存以備後續的觀察、分析和使用,該軟體那將顯得力不從心,也比如自己有一組靜態的美景照片,那麼如果想轉化為視頻那應該怎麼辦呢,python來解決。
  • 使用 Python 操作 word文檔
    最近手頭有一個需求是對word文檔內容進行判斷,搜索到一個包感覺不錯,簡單記錄一下關鍵操作:python-docx能做什麼
  • 用Python玩轉PPT
    基本結構再看一下ppt結構組成,會較word複雜許多。當然這也跟ppt的高度自定義拓展性有關簡單來說,一個PPT文件為presentation,基本的結構為展示文件presentation-幻燈片頁slide-形狀shape組成,形狀就需要區分開,是包含文本的形狀還是不包含文本的形狀(純圖片等)。