Python 实现 提取 Excel文件中的图像文件

flyfish

递归多层遍历:自动扫描指定顶层文件夹下所有层级子目录中的 .xlsx 文件,支持无限深度的文件夹嵌套。
批量提取 JPG 图片:利用 xlsx 本质为压缩包的特性,直接读取内置媒体资源,筛选提取 JPG/JPEG 格式图片。

import os
import zipfile
from pathlib import Path

def extract_images_from_xlsx(excel_file_path, output_root, start_folder):
    """
    从单个xlsx文件中提取JPG格式图片,每个Excel对应独立文件夹
    :param excel_file_path: 单个xlsx文件的完整路径
    :param output_root: 图片输出的根目录
    :param start_folder: 扫描的顶层文件夹,用于计算相对路径
    :return: 本次提取的图片数量
    """
    # 计算Excel文件相对于顶层目录的路径
    relative_path = os.path.relpath(os.path.dirname(excel_file_path), start=start_folder)
    # 获取Excel文件名(不含后缀),作为独立文件夹名
    excel_name = os.path.splitext(os.path.basename(excel_file_path))[0]
    # 拼接最终输出路径:输出根目录/原目录结构/Excel同名文件夹
    output_folder = os.path.join(output_root, relative_path, excel_name)
    Path(output_folder).mkdir(parents=True, exist_ok=True)

    try:
        with zipfile.ZipFile(excel_file_path, 'r') as zip_ref:
            all_files = zip_ref.namelist()
            # 筛选xlsx内置的媒体资源
            image_files = [f for f in all_files if f.startswith("xl/media/")]
            count = 0

            for img_file in image_files:
                # 仅提取JPG/JPEG格式图片
                if img_file.lower().endswith((".jpg", ".jpeg")):
                    img_data = zip_ref.read(img_file)
                    img_name = os.path.basename(img_file)
                    save_path = os.path.join(output_folder, img_name)

                    with open(save_path, "wb") as f:
                        f.write(img_data)
                    count += 1

            if count > 0:
                print(f"提取完成:{excel_file_path},共 {count} 张图片")
            return count

    except Exception as e:
        print(f"处理失败:{excel_file_path},错误:{str(e)}")
        return 0

def scan_all_xlsx_in_folder(root_folder):
    """
    递归遍历所有层级子目录,批量处理xlsx文件
    :param root_folder: 待扫描的顶层文件夹路径
    """
    total_files = 0
    total_images = 0
    output_root = "all_extracted_images"

    print(f"开始扫描文件夹:{root_folder}\n")

    # 递归遍历所有子文件夹
    for dirpath, _, filenames in os.walk(root_folder):
        for filename in filenames:
            if filename.lower().endswith(".xlsx"):
                excel_path = os.path.join(dirpath, filename)
                img_count = extract_images_from_xlsx(excel_path, output_root, root_folder)
                total_files += 1
                total_images += img_count

    print("\n全部处理完成")
    print(f"扫描到xlsx文件:{total_files} 个")
    print(f"累计提取JPG图片:{total_images} 张")
    print(f"图片保存路径:{os.path.abspath(output_root)}")

if __name__ == "__main__":
    # 在此配置需要扫描的顶层文件夹路径
    START_FOLDER = r"文件夹路径"
    scan_all_xlsx_in_folder(START_FOLDER)

更多推荐