欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Python開(kāi)發(fā)批量提取Excel圖片的小工具

 更新時(shí)間:2025年03月19日 15:00:27   作者:很菜的小jiang  
這篇文章主要為大家詳細(xì)介紹了如何使用Python中的openpyxl庫(kù)開(kāi)發(fā)一個(gè)小工具,可以實(shí)現(xiàn)批量提取Excel圖片,有需要的小伙伴可以參考一下

目前有一個(gè)需求,就是批量讀取當(dāng)前目錄下所有文件夾里的Excel文件,去獲取出Excel文件中的圖片,并根據(jù)圖片對(duì)應(yīng)的行去獲取某列的值作為命名方式進(jìn)行命名,并統(tǒng)一保存在一個(gè)新的文件夾里面。

自己花了幾個(gè)小時(shí)寫(xiě)了一個(gè)小工具出來(lái),利用的是openpyxl這個(gè)庫(kù),其他庫(kù)用了提取效果不太好,這個(gè)提取效果挺不錯(cuò)的。以下代碼要根據(jù)實(shí)際需求,將“貨品編碼”改成你對(duì)應(yīng)需要的值。如果你不需要命名規(guī)則,則直接去掉都行。

第一個(gè)版本,針對(duì)于不規(guī)則分布圖片的Excel,進(jìn)行每個(gè)單元格進(jìn)行遍歷,比較費(fèi)時(shí):

import os
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
from openpyxl_image_loader import SheetImageLoader
from openpyxl.utils.cell import get_column_letter
from PIL import Image
 
# 創(chuàng)建文件夾
def create_folder():
    if not os.path.exists('images'):
        os.makedirs('images')
    print("成功創(chuàng)建/更新文件夾!")
 
# 獲取當(dāng)前目錄下的文件夾
def get_folders(directory):
    folders = []
    for entry in os.scandir(directory):
        if entry.is_dir():
            folders.append(entry.name)
    print("成功獲取當(dāng)前目錄的文件夾!")
    return folders
 
# 提取圖片
def extract_images():
    # 創(chuàng)建存放文件夾
    create_folder()
    # 獲取當(dāng)前目錄下的文件夾
    folders = get_folders('.')
    i = 1
    num = 1
    # 遍歷當(dāng)前目錄下的文件夾
    for folder in folders:
        print(f"正在遍歷第{i}個(gè)文件夾{folder}......")
        # 進(jìn)行提取圖片
        num = extract_images_from_excel(folder, num)
        i += 1
 
# 進(jìn)行提取圖片
def extract_images_from_excel(folder, num):
    # 遍歷當(dāng)前文件夾內(nèi)的所有文件
    for entry in os.scandir('.\\'+folder):
        # 如果當(dāng)前對(duì)象是文件且后綴是xlsx
        if entry.is_file() and entry.name.endswith('.xlsx'):
            print(f'{folder}下的Excel文件路徑為:{entry.path}')
            # 打開(kāi)當(dāng)前文件
            wb = load_workbook(entry.path)
            # 獲取當(dāng)前xlsx的所有Sheet表
            worksheets = wb.worksheets
            # 遍歷xlsx中每一個(gè)Sheet
            for ws in worksheets:
                # 獲取當(dāng)前列名為貨品編碼的列序號(hào)
                code_index = ''
                for column in ws.iter_cols():
                    if column[0].value == "貨品編碼":
                        code_index = column[0].column
                # 創(chuàng)建圖片加載對(duì)象
                image_loader = SheetImageLoader(ws)
                # 每一行進(jìn)行遍歷,獲取行序號(hào)和該行數(shù)據(jù)
                for row_index, row in enumerate(ws.rows, start=1):
                    # 每一列進(jìn)行遍歷
                    for column_index in range(1, len(row) + 1):
                        # 獲取列序號(hào)
                        column_letter = get_column_letter(column_index)
                        # 如果當(dāng)前單元格是圖片
                        if image_loader.image_in(f'{column_letter}{row_index}'):
                            # 獲取圖片
                            image = image_loader.get(f'{column_letter}{row_index}')
                            # 獲取圖片格式
                            image_type = image.format
                            # 獲取當(dāng)前行的貨品編碼列的值
                            code = ws.cell(row=(row_index), column=code_index).internal_value
                            # 保存圖片(保存命名為 序號(hào)_貨品編碼)
                            print(f'正在提取單元格{column_letter}{row_index + 1}的圖片......')
                            image.save(f"./images/[code]_{num}.{image_type}")
                            # 序號(hào)遞增
                            num += 1
            # 關(guān)閉文件對(duì)象
            wb.close()
    return num
 
 
if __name__ == '__main__':
    print("此版本是針對(duì)于圖片分布不規(guī)則的情況,提取圖片速度尚且較慢")
    print("開(kāi)始提取......")
    # 提取圖片
    extract_images()
    print("提取完成!")

第二個(gè)版本,針對(duì)于某一列統(tǒng)一分布圖片的Excel,只會(huì)進(jìn)行有圖片那一列的遍歷,比較快速:

import os
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
from openpyxl_image_loader import SheetImageLoader
from openpyxl.utils.cell import get_column_letter
from PIL import Image
 
# 創(chuàng)建文件夾
def create_folder():
    if not os.path.exists('images'):
        os.makedirs('images')
    print("成功創(chuàng)建/更新文件夾!")
 
# 獲取當(dāng)前目錄下的文件夾
def get_folders(directory):
    folders = []
    for entry in os.scandir(directory):
        if entry.is_dir():
            folders.append(entry.name)
    print("成功獲取當(dāng)前目錄的文件夾!")
    return folders
 
# 提取圖片
def extract_images():
    # 創(chuàng)建存放文件夾
    create_folder()
    # 獲取當(dāng)前目錄下的文件夾
    folders = get_folders('.')
    i = 1
    num = 1
    # 遍歷當(dāng)前目錄下的文件夾
    for folder in folders:
        print(f"正在遍歷第{i}個(gè)文件夾{folder}......")
        # 進(jìn)行提取圖片
        num = extract_images_from_excel(folder, num)
        i += 1
 
# 進(jìn)行提取圖片
def extract_images_from_excel(folder, num):
    # 遍歷當(dāng)前文件夾內(nèi)的所有文件
    for entry in os.scandir('.\\'+folder):
        # 如果當(dāng)前對(duì)象是文件且后綴是xlsx或者xls
        if entry.is_file() and (entry.name.endswith('.xlsx') or entry.name.endswith('.xls')):
            print(f'{folder}下的Excel文件路徑為:{entry.path}')
            # 打開(kāi)當(dāng)前文件
            wb = load_workbook(entry.path)
            # 獲取當(dāng)前xlsx的所有Sheet表
            worksheets = wb.worksheets
            # 遍歷xlsx中每一個(gè)Sheet
            for ws in worksheets:
                # 獲取當(dāng)前列名為貨品編碼的列序號(hào)
                code_index = ''
                for column in ws.iter_cols():
                    if column[0].value == "貨品編碼":
                        code_index = column[0].column
                # 創(chuàng)建圖片加載對(duì)象
                image_loader = SheetImageLoader(ws)
                # 記錄第一次遍歷的標(biāo)志
                img_sign_index = ''
                # 每一行進(jìn)行遍歷,獲取行序號(hào)和該行數(shù)據(jù)
                for row_index, row in enumerate(ws.rows, start=1):
                    # 只有第一次才會(huì)進(jìn)行每列遍歷,去找到圖片所在的列
                    if img_sign_index == '':
                        # 每一列進(jìn)行遍歷
                        for column_index in range(1, len(row) + 1):
                            # 獲取列序號(hào)
                            column_letter = get_column_letter(column_index)
                            if image_loader.image_in(f'{column_letter}{row_index}'):
                                # 獲取對(duì)應(yīng)圖片的列序號(hào)
                                img_sign_index = column_letter
                                break
                    # 如果不為空,則證明有圖片,反之直接跳過(guò)
                    if img_sign_index != '':
                        # 后面遍歷直接去找圖片所在的列
                        image = image_loader.get(f'{img_sign_index}{row_index}')
                        # 獲取圖片格式
                        image_type = image.format
                        # 獲取當(dāng)前行的貨品編碼列的值
                        code = ws.cell(row=(row_index), column=code_index).internal_value
                        # 保存圖片(保存命名為 序號(hào)_貨品編碼)
                        print(f'正在提取單元格{img_sign_index}{row_index + 1}的圖片......')
                        image.save(f"./images/{num}_[code].{image_type}")
                        # 序號(hào)遞增
                        num += 1
 
            # 關(guān)閉文件對(duì)象
            wb.close()
    return num
 
 
if __name__ == '__main__':
    print("此版本是針對(duì)于圖片集中分布在一列的情況,能更快提取圖片出來(lái)")
    print("開(kāi)始提取......")
    # 提取圖片
    extract_images()
    print("提取完成!")

第三個(gè)版本更新

此版本不是遍歷單元格,是直接找圖片,再鎖定圖片的中心行位置去找相應(yīng)的貨品編碼,效率更高,而且不會(huì)因?yàn)閳D片位于單元格邊緣存在識(shí)別不到的問(wèn)題。

import os
 
from openpyxl import load_workbook
import os
from openpyxl_image_loader import SheetImageLoader
from openpyxl.utils.cell import get_column_letter
 
# 創(chuàng)建文件夾
def create_folder():
    if not os.path.exists('images'):
        os.makedirs('images')
    print("成功創(chuàng)建/更新文件夾!")
 
# 獲取當(dāng)前目錄下的文件夾
def get_folders(directory):
    folders = []
    for entry in os.scandir(directory):
        if entry.is_dir():
            folders.append(entry.name)
    print("成功獲取當(dāng)前目錄的文件夾!")
    return folders
 
# 提取圖片
def extract_images():
    # 創(chuàng)建存放文件夾
    create_folder()
    # 獲取當(dāng)前目錄下的文件夾
    folders = get_folders('.')
    i = 1
    num = 1
    # 遍歷當(dāng)前目錄下的文件夾
    for folder in folders:
        print(f"正在遍歷第{i}個(gè)文件夾{folder}......")
        # 進(jìn)行提取圖片
        num = extract_images_from_excel(folder, num)
        i += 1
 
# 進(jìn)行提取圖片
def extract_images_from_excel(folder, num):
    # 遍歷當(dāng)前文件夾內(nèi)的所有文件
    for entry in os.scandir('.\\'+folder):
        # 如果當(dāng)前對(duì)象是文件且后綴是xlsx或者xls
        if entry.is_file() and entry.name.endswith('.xlsx'):
            print(f'{folder}下的Excel文件路徑為:{entry.path}')
            # 打開(kāi)當(dāng)前文件
            wb = load_workbook(entry.path)
            # 遍歷每一個(gè)Sheet
            for sheet_name in wb.sheetnames:
                sheet = wb[sheet_name]
                image_loader = SheetImageLoader(sheet)
                # 獲取當(dāng)前列名為貨品編碼的列序號(hào)
                code_index = ''
                for column in sheet.iter_cols():
                    if column[0].value == "貨品編碼":
                        code_index = column[0].column
                # 遍歷Sheet中的所有圖片
                for image in sheet._images:
                    # 獲取圖片中心行數(shù),判斷貨品編碼是哪一個(gè)
                    row_index = (int(((image.anchor._from.row + 1) + (image.anchor.to.row + 1)) / 2))
                    # 獲取當(dāng)前行的貨品編碼列的值(取中間值)
                    code = sheet.cell(row=row_index, column=code_index).value
                    # 獲取圖片格式
                    img_format = image.format
                    # 重新將圖片獲取出來(lái)(因?yàn)楂@取下標(biāo)這個(gè)image沒(méi)有存儲(chǔ)方法),直接通過(guò)定位左上角坐標(biāo)將圖片取出來(lái)
                    img = image_loader.get(f'{get_column_letter(image.anchor._from.col + 1)}{image.anchor._from.row + 1}')
                    # 保存圖片
                    print(f'正在提取貨品編碼為[code]的圖片{image}......')
                    img.save(f'./images/{num}_[code].{img_format}')
                    # 序號(hào)遞增
                    num += 1
 
            # 關(guān)閉文件對(duì)象
            wb.close()
    return num
 
# v1.0:此版本是針對(duì)于圖片分布不規(guī)則的情況,提取圖片速度尚且較慢
# v1.1:此版本是針對(duì)于圖片集中分布在一列的情況,能更快提取圖片出來(lái)。
# v1.2:此版本解決圖片位于Excel邊界時(shí)存在的問(wèn)題,只要圖片中心行在這一行,就可以匹配相應(yīng)的國(guó)家編碼,同時(shí)不用去遍歷,直接獲取圖片。
if __name__ == '__main__':
    print("開(kāi)始提取......")
    # 提取圖片
    extract_images()
    print("提取完成!")

第四個(gè)版本:增加了圖片的壓縮,不需要壓縮的可以直接不調(diào)用壓縮犯法即可,增加了交互,聽(tīng)取了評(píng)論區(qū)大佬的意見(jiàn),現(xiàn)在可以提取同一單元格多張圖片。

import math
 
from openpyxl import load_workbook
import os
from PIL import Image
 
# 命名規(guī)則
good_code = ""
# 命名字典
name_dict = {}
# 圖片數(shù)量
img_num = 0
# 記錄哪些文件夾已經(jīng)被提取過(guò)了
folder_name_dict = {}
# 是否輸出提取文本
is_text = True
 
 
# 創(chuàng)建文件夾
def create_folder():
    if not os.path.exists('images'):
        os.makedirs('images')
    print("成功創(chuàng)建/更新images文件夾!")
 
 
# 提取圖片
def extract_images(stop):
    if stop:
        return
    global img_num
    global good_code
    folder = input("請(qǐng)輸入需要提取的文件夾名稱(chēng)(不輸入則遍歷當(dāng)前目錄下未提取過(guò)的所有文件夾):")
    good_code = input("請(qǐng)輸入命名規(guī)則對(duì)應(yīng)表格中的名字(不輸入則默認(rèn)為貨品編碼):")
    if good_code == "":
        good_code = "貨品編碼"
    if folder != '':
        # 查找指定文件夾
        extract_images_from_excel(folder)
    else:
        folders = []
        for entry in os.scandir('.'):
            if entry.is_dir():
                folders.append(entry.name)
        i = 1
        # 記錄可提取的文件夾的數(shù)量
        number = 0
        # 遍歷當(dāng)前目錄下的文件夾
        for folder in folders:
            if folder in folder_name_dict:
                continue
            print(f"正在遍歷第{i}個(gè)文件夾{folder}......")
            # 進(jìn)行提取圖片
            extract_images_from_excel(folder)
            number += 1
            i += 1
        if number == 0:
            print("沒(méi)有可供提取的文件夾了!")
            return
    is_success()
    img_num = 0
    status = input("\n是否繼續(xù)提?。ㄝ斎隮表示是,輸入其他則退出):")
    if status == "Y" or status == "y":
        extract_images(False)
    else:
        extract_images(True)
 
 
def is_success():
    if img_num == 0:
        if is_text:
            print(f'沒(méi)有提取到圖片!')
    else:
        print(f'成功提取{img_num}張圖片!')
        print("圖片提取完成,請(qǐng)到images文件夾中查看!")
 
 
# 進(jìn)行提取圖片
def extract_images_from_excel(folder):
    global img_num
    global is_text
    is_have_excel = False
    path = os.path.join('.', folder)
    if not os.path.exists(path):
        print(f'{folder}文件夾未找到!')
        return
    # 判斷文件夾是否已經(jīng)被提取過(guò)了
    if folder not in folder_name_dict:
        is_text = True
    else:
        print(f'{folder}文件夾已經(jīng)被提取過(guò)了!')
        is_text = False
        return
    try:
        # 遍歷當(dāng)前文件夾內(nèi)的所有文件
        for entry in os.scandir(path):
            # 如果當(dāng)前對(duì)象是文件且后綴是xlsx或者xls
            if entry.is_file() and entry.name.endswith('.xlsx'):
                is_have_excel = True
                print(f'{folder}下的Excel文件路徑為:{entry.path}')
                # 打開(kāi)當(dāng)前文件
                wb = load_workbook(entry.path)
                # 遍歷每一個(gè)Sheet
                for sheet_name in wb.sheetnames:
                    sheet = wb[sheet_name]
                    # 獲取當(dāng)前列名為貨品編碼的列序號(hào)
                    code_index = ""
                    for column in sheet.iter_cols():
                        if column[0].value == good_code:
                            code_index = column[0].column
                            break
                    if code_index == "":
                        print(f'列名{good_code}在{entry.path}的文件中不存在!')
                        break
                    else:
                        folder_name_dict[folder] = True
                    # 遍歷Sheet中的所有圖片
                    for image in sheet._images:
                        # 獲取圖片中心行數(shù),判斷貨品編碼是哪一個(gè)
                        row_index = (int(((image.anchor._from.row + 1) + (image.anchor.to.row + 1)) / 2))
                        # 獲取當(dāng)前行的貨品編碼列的值(取中間值)
                        code = ""
                        if code_index != "":
                            code = str(sheet.cell(row=row_index, column=code_index).value)
                        # 獲取圖片格式
                        img_format = image.format
                        # 這個(gè)if else只是命名規(guī)則,不重要
                        if code not in name_dict:
                            name_dict[code] = 1
                        else:
                            name_dict[code] = name_dict[code] + 1
                        save_path = f"./images/[code]-{name_dict[code]}.{img_format}"
                        # 保存
                        file = open(save_path, "wb")
                        file.write(image.ref.getvalue())
                        file.close()
                        # 壓縮圖片
                        compress_and_save_image(save_path)
                        img_num += 1
                    break
                # 關(guān)閉文件對(duì)象
                wb.close()
    except FileNotFoundError:
        # 處理文件未找到異常
        print(f'{folder}文件夾未找到!')
        extract_images(good_code)
    except Exception as e:
        # 處理其他異常
        print("提取圖片異常:", e)
    if not is_have_excel:
        print(f'{folder}文件夾內(nèi)未找到Excel文件!')
        folder_name_dict[folder] = True
 
 
# 壓縮圖片
def compress_and_save_image(image_path):
    # 打開(kāi)原始圖片
    original_image = Image.open(image_path)
    # 檢查文件大小,并根據(jù)需要進(jìn)行進(jìn)一步壓縮,壓縮到1M
    if os.path.getsize(image_path) > 1024 * 1024:
        size = os.path.getsize(image_path)
        # 壓縮到1mb需要壓縮的比例(百分比)
        quality = math.floor(((1024 * 1024) / size) * 100)
        original_image.save(image_path, optimize=True, quality=quality)
    original_image.close()
 
 
# v1.0:此版本是針對(duì)于圖片分布不規(guī)則的情況,提取圖片速度尚且較慢
# v1.1:此版本是針對(duì)于圖片集中分布在一列的情況,能更快提取圖片出來(lái)。
# v1.2:此版本解決圖片位于Excel邊界時(shí)存在的問(wèn)題,只要圖片中心行在這一行,就可以匹配相應(yīng)的國(guó)家編碼,同時(shí)不用去遍歷,直接獲取圖片。
# v1.3:此版本是讓用戶(hù)自己輸入指定的文件夾,增加異常交互。
# v1.4:此版本增加了對(duì)1MB以上圖片的壓縮,解決了多圖片在同一單元格的問(wèn)題。
if __name__ == '__main__':
    print("開(kāi)始提取......")
    # 創(chuàng)建存放文件夾
    create_folder()
    # 提取圖片
    extract_images(False)
    # 最后加入輸入語(yǔ)句,以阻塞程序的執(zhí)行
    input("按下任意鍵以關(guān)閉程序")

以上就是基于Python開(kāi)發(fā)批量提取Excel圖片的小工具的詳細(xì)內(nèi)容,更多關(guān)于Python提取Excel圖片的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • pandas數(shù)據(jù)聚合與分組運(yùn)算的實(shí)現(xiàn)

    pandas數(shù)據(jù)聚合與分組運(yùn)算的實(shí)現(xiàn)

    本文主要介紹了pandas數(shù)據(jù)聚合與分組運(yùn)算的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Python tkinter如何設(shè)置背景顏色

    Python tkinter如何設(shè)置背景顏色

    本文主要介紹了Python的tkinter庫(kù)中設(shè)置組件背景顏色的方法,主要通過(guò)使用bg選項(xiàng)和config方法來(lái)實(shí)現(xiàn),包括設(shè)置單個(gè)組件、窗口、按鈕、文本框以及整個(gè)應(yīng)用的背景顏色,同時(shí)也可以使用十六進(jìn)制顏色代碼進(jìn)行更精確的顏色控制
    2024-09-09
  • python實(shí)現(xiàn)多張圖片拼接成大圖

    python實(shí)現(xiàn)多張圖片拼接成大圖

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)多張圖片拼接成大圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 基于python不同開(kāi)根號(hào)的速度對(duì)比分析

    基于python不同開(kāi)根號(hào)的速度對(duì)比分析

    這篇文章主要介紹了基于python不同開(kāi)根號(hào)的速度對(duì)比分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • Transpose 數(shù)組行列轉(zhuǎn)置的限制方式

    Transpose 數(shù)組行列轉(zhuǎn)置的限制方式

    今天小編就為大家分享一篇Transpose 數(shù)組行列轉(zhuǎn)置的限制方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • 基于Python做一個(gè)簡(jiǎn)單的動(dòng)圖生成器

    基于Python做一個(gè)簡(jiǎn)單的動(dòng)圖生成器

    現(xiàn)在的年輕人都開(kāi)始每天保溫杯里泡枸杞,這怎么能行呢?于是懷揣著愉悅心情的想法,我開(kāi)始制作GIF動(dòng)圖生成器,這個(gè)小工具制作的目的是為了將多張圖片組合后生成一張動(dòng)態(tài)的GIF圖片,感興趣的可以嘗試一下
    2023-01-01
  • 容易被忽略的Python內(nèi)置類(lèi)型

    容易被忽略的Python內(nèi)置類(lèi)型

    這篇文章主要介紹了容易被忽略的Python內(nèi)置類(lèi)型,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2020-09-09
  • Django中實(shí)現(xiàn)點(diǎn)擊圖片鏈接強(qiáng)制直接下載的方法

    Django中實(shí)現(xiàn)點(diǎn)擊圖片鏈接強(qiáng)制直接下載的方法

    這篇文章主要介紹了Django中實(shí)現(xiàn)點(diǎn)擊圖片鏈接強(qiáng)制直接下載的方法,涉及Python操作圖片的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-05-05
  • 淺談Python的字典鍵名可以是哪些類(lèi)型

    淺談Python的字典鍵名可以是哪些類(lèi)型

    本文主要介紹了Python的字典鍵名可以是哪些類(lèi)型,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Python 操作 PostgreSQL 數(shù)據(jù)庫(kù)示例【連接、增刪改查等】

    Python 操作 PostgreSQL 數(shù)據(jù)庫(kù)示例【連接、增刪改查等】

    這篇文章主要介紹了Python 操作 PostgreSQL 數(shù)據(jù)庫(kù)的方法,結(jié)合實(shí)例形式分析了Python 連接PostgreSQL及增刪改查等相關(guān)操作技巧,需要的朋友可以參考下
    2020-04-04

最新評(píng)論