关于带隐藏区域的EXCELL表格用python循环截图方法
# coding:utf-8import 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会对页面上的复杂对象进行“延迟处理”,即在以某种方式访问对象之前不会对其进行渲染。
# 另一种方法是循环遍历对象。如果是这种情况,那么它是Excel的CopyPicture实现的一个错误,它不会在尝试复制之前强制复制对象。当复制方法发现目标范围的渲染尚未就绪时,它只会抛出错误而不是强制渲染范围。
# 反复实践,在截图时相应几个地方停顿一秒能大幅减少截图错误发生
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 hasno 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')# 延保每日通报表二级截图 目前用这段代码,循环截图目前100%正确,完美运行! 这段代码截图在家里独显电脑上截图同一表格,同一区域保存的图片有300K,非常清晰,而在单位一个集成显卡电脑上保存只100K(和家里电脑同一WIN10系统,同一pycharm版本,所有模块版本一致,CPU级别差不多),发到微信上有点模糊,不知道原因,请高手指点并修改! 显卡的话是分辨率不一样么 xedeno 发表于 2021-5-20 14:59
显卡的话是分辨率不一样么
分辨率完全一样,所以没搞懂原因! if hidden_flag:
ws.Rows(rows_hidden).EntireRow.Hidden = False
time.sleep(3)# 补充,这里漏了一个停顿,否则还有可能发生截图错误的发生
img = ImageGrab.grabclipboard()# 获取剪贴板的图片数据
追记
页:
[1]