python实现Excel指定区域截图

方法一:xlwings

import os.path
import uuid
from io import BytesIO
from typing import Union

import xlwings as xw
from PIL import ImageGrab


def excel_grab(excel_path, sheet_name: Union[str, int] = 0, cell_area=None, pic_path=None, visible=False, saved=True):
    """
    Excel指定区域截图
    :param excel_path: Excel文件路径
    :param sheet_name: 工作表名称或索引,0即第一张工作表
    :param cell_area: 截图区域,默认None。'A2:N17', 不指定时获取有内容的区域截图
    :param pic_path: 截图文件路径,png格式
    :param visible: 截图时是否打开显示Excel
    :param saved: 是否将截图保存到本地
    :return: png路径 或 图片的bytes
    """
    app = xw.App(visible=visible, add_book=False)
    wb = app.books.open(excel_path)
    if isinstance(sheet_name, str):
        sheet = wb.sheets(sheet_name)
    else:
        sheet = wb.sheets[sheet_name]
    if cell_area:
        pic_area = sheet[cell_area]
    else:
        pic_area = sheet.used_range  # 获取有内容的range
    try:
        pic_area.api.CopyPicture()  # 复制图片区域
        sheet.api.Paste()
        pic = sheet.pictures[0]  # 当前图片
        pic.api.Copy()
        pic.delete()  # 删除sheet上的图片
    except Exception as e:
        return f'区域【{cell_area}】截图失败,错误:{e}'
    finally:
        wb.close()
        app.quit()
        app = None

    try:
        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
    except Exception as e:
        return f'区域【{cell_area}】从剪贴板获取截图失败,错误:{e}'
    if saved:
        if not pic_path:
            pic_path = f'{os.path.splitext(excel_path)[0]}_{uuid.uuid4().hex[:10]}.png'
        img.save(pic_path)
    else:
        f = BytesIO()
        img.save(f, 'png')
        img_data = f.getvalue()
        f.close()
    return pic_path if saved else img_data

方法二:win32com

import os.path
import uuid
from io import BytesIO
from typing import Union

from PIL import ImageGrab
from win32com.client import Dispatch


def print_excel(excel_path, sheet_name: Union[str, int] = 1, screen_area=None, pic_path=None, visible=False, saved=True):
    """
    Excel指定区域截图
    :param excel_path: Excel文件路径
    :param sheet_name: 工作表名称,或索引,1即第一个工作表
    :param screen_area: 截图区域,默认None。'A2:N17', 不指定时获取有内容的区域截图
    :param pic_path: 截图保存路径
    :param visible: 截图时是否打开显示Excel
    :param saved: 是否将截图保存到本地
    :return: 截图路径或截图的bytes
    """
    excel = Dispatch("Excel.Application")  # 启动excel,WPS使用Ket.Application或et.Application
    excel.Visible = visible  # 可视化
    excel.DisplayAlerts = False  # 是否显示警告

    wb = excel.Workbooks.Open(excel_path)  # 打开excel
    if isinstance(sheet_name, str):
        ws = wb.Sheets(sheet_name)
    else:
        ws = wb.Sheets[sheet_name]

    try:
        # 复制图片区域
        if screen_area:
            ws.Range(screen_area).CopyPicture()
        else:
            ws.UsedRange.CopyPicture()
        ws.Paste()  # 粘贴
        ws.Shapes(excel.Selection.ShapeRange.Name).Copy()  # 选择图片

        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
        if saved:
            if not pic_path:
                pic_path = f'{os.path.splitext(excel_path)[0]}_{uuid.uuid4().hex[:10]}.png'
            img.save(pic_path)
        else:
            f = BytesIO()
            img.save(f, 'png')
            img_data = f.getvalue()
            f.close()
    except Exception as e:
        print(f'区域【{screen_area}】截图失败,错误:{e}')
    finally:
        wb.Close(False)  # 不保存关闭工作薄
        excel.Quit()
        return pic_path if saved else img_data
posted @ 2023-12-04 13:29  cnblogs用户  阅读(2081)  评论(0编辑  收藏  举报