吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2665|回复: 6
收起左侧

[Python 转载] 关于带隐藏区域的EXCELL表格用python循环截图方法

  [复制链接]
棋行天下黄 发表于 2021-5-20 13:59
# coding:utf-8
import time
from win32com.client import Dispatch
from PIL import ImageGrab   
from PIL import Image
from ctypes import windll  # 导入剪切板模块

def excel_catch_screen(filename, sheetname, screen_area, hidden_flag, rows_hidden, new_shape_name):
    try:
        """(r"E:\每日报表\延销售日进度通报.xlsx", "各门店日销售", "A1:J10",True,"3:34",'YB001')"""
        print(new_shape_name + "截图程序开始运行")
        # 清空剪切板,保证截图时剪切板不至于空间已满,无法保存,
        if windll.user32.OpenClipboard(None):  # 打开剪切板
            windll.user32.EmptyClipboard()  # 清空剪切板
            windll.user32.CloseClipboard()  # 关闭剪切板
        excel = Dispatch('Excel.Application')
        excel.Quit()  # 非常重要,这是反复实践得来的,先退出excell进程,否则极易粘贴截图出错,重复执行时容易死循环!
        excel.Visible = True  # 可视化
        excel.DisplayAlerts = False  # 是否显示警告
        wb = excel.Workbooks.Open(filename)  # 打开excel
        ws = wb.Sheets(sheetname)  # 选择sheet
        # 似乎有理由认为,在缓慢或负载很重的计算机上,Excel会对页面上的复杂对象进行延迟处理,即在以某种方式访问对象之前不会对其进行渲染。
        # 另一种方法是循环遍历对象。如果是这种情况,那么它是ExcelCopyPicture实现的一个错误,它不会在尝试复制之前强制复制对象。当复制方法发现目标范围的渲染尚未就绪时,它只会抛出错误而不是强制渲染范围。
        # 反复实践,在截图时相应几个地方停顿一秒能大幅减少截图错误发生
        time.sleep(1)
        ws.Select()  # 页面实际切换必须用.Select(),如果.select无效,不会变化,切记!!
        if hidden_flag:
            ws.Rows(rows_hidden).EntireRow.Hidden = True  # 如果需要隐藏,则表格隐藏区域进行隐藏

        time.sleep(1)
        ws.Range(screen_area).CopyPicture()  # 复制图片区域
        ws.Cells(1, 1).Select()  # 复制图片区域
        time.sleep(2)
        ws.Paste()  # 粘贴 ws.Paste(ws.Range('A1'))  # 将图片移动到具体位置
        excel.Selection.ShapeRange.Name = new_shape_name  # 将刚刚选择的Shape重命名,避免与已有图片混淆
        # time.sleep(3)

        ws.Shapes(new_shape_name).Copy()  # 选择图片
        if hidden_flag:
            ws.Rows(rows_hidden).EntireRow.Hidden = False
        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
        img_name = new_shape_name + ".png"
        # Pycharm 2020版本实验保存JPG格式会报cannot write mode RGBA as JPEG错误,故保存为png
        # Pycharm 2020版本之前的2019版本可以直接保存为JPG
        time.sleep(2)
        # Pycharm 2020以后的版本直接保存为PNG在发送图片在微信上时图片背景会是黑色
        im = img.convert("RGBA")
        x, y = im.size
        print(im.size)
        p = Image.new('RGBA', im.size, (255, 255, 255))
        p.paste(im, (0, 0, x, y), im)
        time.sleep(1)
        p.save('E:\\每日报表\\' + img_name)
        # 以上是解决Pycharm 2020以后的版本直接保存为PNG在发送图片在微信上时图片背景会是黑色的问题
        print(new_shape_name + "已成功实现截图")
        wb.Close(SaveChanges=0)  # 关闭工作薄,不保存
        # excel.Application.Quit  # 退出excel一定不要用这
        excel.Quit()  # 退出excel用这,多次运行时截图不能保存需要此语句
    except Exception as e:
        print(e)
        # 必须要加入此异常,如果不加入sleep停顿,不先退出excell进程,在多次截图情况下,有三分之一的概率发生错误,甚至死循环
        # 捕捉到的错误为'NoneType object has  no attribute save'
        # VBA截图各种代码下,多次循环截图都有偶尔截图保存为空白的情况,反复实践,用python截图这个程序最完善
        # (-2147352567, '发生意外。', (0, 'Microsoft Excel', 'Microsoft Excel 无法粘贴数据。', 'xlmain11.chm', 0, -2146827284), None)
        # 如出现上面这句错误,可能由于各种循环,当文件读写速度较快的时候,上一个Excel未关闭,下一个就打开,导致出现以上问题
        time.sleep(1)
        return excel_catch_screen(filename, sheetname, screen_area, hidden_flag, rows_hidden, new_shape_name)
        # 截图失败重新截图
   
filename = r"E:\每日报表\延保及销售日进度通报.xlsx"
sheetname = '各门店日销售'
excel_catch_screen(filename, sheetname, "A1:U41", False, "3:41", 'YB001')  # 延保每日通报表一级截图
excel_catch_screen(filename, sheetname, "A1:U106", True, "3:41", 'YB002')  # 延保每日通报表二级截图
excel_catch_screen(filename, sheetname, "A1:U191", True, "3:106", 'YB003')  # 延保每日通报表二级截图

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 棋行天下黄 发表于 2021-5-20 14:07
目前用这段代码,循环截图目前100%正确,完美运行!
 楼主| 棋行天下黄 发表于 2021-5-20 14:36
这段代码截图在家里独显电脑上截图同一表格,同一区域保存的图片有300K,非常清晰,而在单位一个集成显卡电脑上保存只100K(和家里电脑同一WIN10系统,同一pycharm版本,所有模块版本一致,CPU级别差不多),发到微信上有点模糊,不知道原因,请高手指点并修改!
xedeno 发表于 2021-5-20 14:59
 楼主| 棋行天下黄 发表于 2021-5-20 15:06
xedeno 发表于 2021-5-20 14:59
显卡的话是分辨率不一样么

分辨率完全一样,所以没搞懂原因!
头像被屏蔽
dongse 发表于 2021-5-20 15:48
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| 棋行天下黄 发表于 2021-5-21 15:58
if hidden_flag:
            ws.Rows(rows_hidden).EntireRow.Hidden = False
time.sleep(3)  # 补充,这里漏了一个停顿,否则还有可能发生截图错误的发生
        img = ImageGrab.grabclipboard()  # 获取剪贴板的图片数据
追记
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 16:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表