Python通过xlwings自动化Excel-持续更新

一.自动化脚本注意事项

背景:pyautogui基于坐标(x,y)或点击图片进行相关操作,分辨率不同会使坐标(x,y)发生偏移或图像不被识别,导致脚本无法正常使用,注意事项如下。

  • 为保证自动化程序正常运行,尽可能关闭不相关的应用程序窗口。

  • 为保证在指定窗口执行,用getWindowsWithTitle()获取窗口句柄,并 activate()将窗口置顶。

  • 为保证窗口的位置坐标(x,y)不会更改,建议在相同的屏幕分辨率设备上运行脚本。

  • 为保证按钮和菜单的位置不发生变化,建议每次maximize()最大化需要操作的应用程序窗口。

  • 为保证程序在就绪后进行操作,建议每执行一步操作都加入适当的等待时间。

  • 点击按钮或菜单,locateOnScreen()不依赖于坐标(X,Y),更稳定。

  • 尽量用热键hotkey()或者keyDown('tab')键代替点击Click(),比坐标(x,y)更稳定更可靠。

二.鼠标相关-pyautogui

a.获取显示屏的尺寸

Python通过xlwings自动化Excel-持续更新_第1张图片

#引入pyautogui的包,取别名为pg
import pyautogui as pg

#获取屏幕尺寸
wSize = pg.size()
# 屏幕的宽
print(wSize[0])
print(wSize.width)
# 屏幕高
print(wSize[1])
print(wSize.height)

执行结果

Python通过xlwings自动化Excel-持续更新_第2张图片

b.获取鼠标位置

通过pyautogui工具获取坐标(X,Y)

#启动pyautogui自带的工具
import pyautogui as pg
pg.mouseInfo()

当鼠标移动到需要点击的按钮或者菜单上,实时看到坐标(X,Y)等信息。

Python通过xlwings自动化Excel-持续更新_第3张图片

通过图表获取坐标(X,Y)

Python通过xlwings自动化Excel-持续更新_第4张图片

截取全部刷新按钮,保存到桌面命名为refreshbtn.jpg。

import pyautogui as pg 
try:
    b = pg.locateOnScreen(r'C:\Users\mypc\Desktop\refreshbtn.jpg')
    pg.click((b.left, b.top, b.width, b.height))
except:
    print('未找到图片。')
import pyautogui as pg 
try:
    pg.click(r'C:\Users\mypc\Desktop\refreshbtn.jpg')
except:
    print('未找到图片。')

通过跨界键,点击“全部刷新”

先点击键盘的ALT键,查看快捷键,如图,快捷键为 Y4

键盘先点击ALT键,再点击Y键,再点击数字4,会显示全部刷新按钮的快捷键盘为R

根据上述的实际操作步骤,模拟创建点击代码。加入Sleep休眠代码,是防止python程序运行太快,excel还没有准备好下一步响应,程序就运行结束。因为hotkey('ALT','Y','4'),hotkey('ALT+Y+4')未找到如何实现点击到二级菜单的快捷键的用法,所以示例代码使用了press函数。

import pyautogui as pg
#依次点击ALT
pg.press('ALT')
time.sleep(2)
#依次点击Y
pg.press('Y')
time.sleep(2)
#选择Analysis
#依次点击4
pg.press('4')
time.sleep(2)
#点击全部刷新
#依次点击R
pg.press('R')

运行效果图,正常点击“全部刷新”按钮。

Python通过xlwings自动化Excel-持续更新_第5张图片

c.获取窗口信息

遍历窗口进行查找

import pyautogui as pg
#获取所有打开的应用窗口
windows = pg.getAllWindows()
#如果当前没有窗口打开,提示异常
if len(windows) == 0:
    raise Exception("窗口未找到")
#遍历窗口
for window in windows:
    #窗口的名字包含关键字时,打印到屏幕上
    if "要找的窗口的名字" in window.title:
        print(window.title)

根据窗口的标题查找窗口

import pyautogui as pg 
windows = pg.getWindowsWithTitle('my.xlsx - Excel')
if len(windows) == 0:
    raise Exception("窗口未找到")
print(windows[0])

#最大化窗口
windows[0].maximize()
#取消最大化
windows[0].restore()
#最小化窗口
windows[0].minimize()
#取消最小化
windows[0].restore()
#关闭窗口
windows[0].close()

d.操作键盘

Python通过xlwings自动化Excel-持续更新_第6张图片
import pyautogui as pg 
#点击客户端的文本框
pg.click(854,504)
#输入80
pg.write('80')
#按一次Tab键,移动到用户
pg.keyDown('tab')
#输入用户名user
pg.write('user')
#按一次Tab键,移动到密码
pg.keyDown('tab')
#输入密码password
pg.write('password')

运行后效果图

Python通过xlwings自动化Excel-持续更新_第7张图片

e.Excel加载完成判断

1.通过光标状态判断完成

数据在加载过程中,光标会一直转圈显示忙碌。可以判断当前光标的图片是否为圆圈。

import win32gui, win32ui

while True:
       # 等待2秒
        time.sleep(2)  
       # 获取光标信息
        curinfo = win32gui.GetCursorInfo()  
       # 异常回避:如果光标消失,继续循环
        if (curinfo[1] == 0):
            continue
        # 获取光标图像信息
        iamgeinfo = win32gui.GetIconInfo(curinfo[1]) 
        # 获取bitmap信息
        bminfo = win32gui.GetObject(iamgeinfo[3]) 
        # 
        gdc = win32gui.GetDC(0)  
        # 创造DC对象
        hdc = win32ui.CreateDCFromHandle(gdc)  
        # 创建一个新位图
        hbmp = win32ui.CreateBitmap()  
        hbmp.CreateCompatibleBitmap(hdc, bminfo.bmWidth, bminfo.bmHeight)  
        hdc = hdc.CreateCompatibleDC() 
        hdc.SelectObject(hbmp) 
        win32gui.DrawIconEx(hdc.GetHandleOutput(), 0, 0, ci[1], bm.bmWidth, bm.bmHeight, 0, None, 2)  
        bitmapbits = hbmp.GetBitmapBits(True)
        # busy 加载中图片的二进制内容
        loadbitmap = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x10\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x18\xc5{"b\xe5\x8e\'\x99\xef\x95)\xc3\xef\x95)\xc3\xef\x95)\xc3\xef\x95)\xc3\xe5\x8e\'\x99\xc5{"b\x00\x00\x00\x18\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x14\xbbt S\xf1\x96*\xe2\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf1\x96*\xe2\xbbt S\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x15\xe0\x8b\'\x8b\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe0\x8b\'\x8b\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xec\xa3&\xa8\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe0\x8b\'\x8b\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xde\xa0#~\xff\xcc%\xff\xfb\xb8\'\xff\xf4\x9a*\xff\xf3\x97*\xff\xf3\x97*\xff\xf2\x96*\xf1\xe9\x90(\xa7\xe2\x8c\'\x8a\xe2\x8c\'\x8a\xe9\x90(\xa7\xf2\x96*\xf1\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xbbt S\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xfe\xc5&\xfb\xff\xcc%\xff\xff\xcc%\xff\xfd\xc1&\xff\xf4\x9a*\xff\xeb\x92)\xb6`<\x11(\x00\x00\x00\x10\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x10`<\x11(\xeb\x92)\xb6\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf1\x96*\xe2\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xe1\xa0#\x89\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xf9\xba&\xe4\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x18\xeb\x92)\xb6\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xc5{"b\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\xf7\xb8&\xd3\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xfe\xc9%\xfe\x90g\x165\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05`<\x11(\xf2\x96*\xf1\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe5\x8e\'\x99\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xfc\xc0&\xf0\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xf9\xbb&\xde\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\xe9\x90(\xa7\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xef\x95)\xc3\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xfd\xc3&\xf7\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xf5\xb5&\xc5\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xe2\x8c\'\x8a\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xef\x95)\xc3\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xfd\xc3&\xf7\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xf5\xb5&\xc5\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xe2\x8c\'\x8a\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xef\x95)\xc3\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xfc\xc0&\xf0\xff\xcc%\xff\xff\xcc%\xff\xff\xcc%\xff\xfa\xbe&\xe4\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\xe9\x90(\xa7\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xef\x95)\xc3\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\xf7\xb8&\xd3\xff\xcc%\xff\xfe\xc5&\xff\xfa\xb4\'\xff\xf5\xa0)\xf4`<\x11(\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05`<\x11(\xf2\x96*\xf1\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe5\x8e\'\x99\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xdb\x99#\x80\xf7\xa7(\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xeb\x92)\xb6\x00\x00\x00\x18\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x18\xeb\x92)\xb6\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xc5{"b\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xf1\x96*\xe2\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xeb\x92)\xb6`<\x11(\x00\x00\x00\x10\x00\x00\x00\r\x00\x00\x00\r\x00\x00\x00\x10`<\x11(\xeb\x92)\xb6\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf1\x96*\xe2\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xbbt S\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf2\x96*\xf1\xe9\x90(\xa7\xe2\x8c\'\x8a\xe2\x8c\'\x8a\xe9\x90(\xa7\xf2\x96*\xf1\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xbbt S\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xe0\x8b\'\x8b\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe0\x8b\'\x8b\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x15\xe0\x8b\'\x8b\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xe0\x8b\'\x8b\x00\x00\x00\x15\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x14\xbbt S\xf1\x96*\xe2\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf3\x97*\xff\xf1\x96*\xe2\xbbt S\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x18\xc5{"b\xe5\x8e\'\x99\xef\x95)\xc3\xef\x95)\xc3\xef\x95)\xc3\xef\x95)\xc3\xe5\x8e\'\x99\xc5{"b\x00\x00\x00\x18\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x10\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
       
        if bitmapbits != loadbitmap:
            # 资源释放
            win32gui.ReleaseDC(0, gdc)  # 释放上下文 参数(窗口句柄,上下文句柄)
            hdc.DeleteDC()
            win32gui.DeleteObject(hbmp.GetHandle())
            #print("Load is finish...")
            time.sleep(2)
            break
        # else:
        #     print(time.localtime())
        #hbmp.SaveBitmapFile(hdc, 'scre99t.bmp')  # 将位图保存为图片,注意这里只能放dc
        # 资源释放
        win32gui.ReleaseDC(0, gdc)  # 释放上下文 参数(窗口句柄,上下文句柄)
        hdc.DeleteDC()
        win32gui.DeleteObject(hbmp.GetHandle())

注意:加载过程中,光标会变化,会变成Cross十字架,会消失,存在一定的不稳定性,需要多运行几次。

2. 通过菜单图标的颜色判断

数据加载前后,某些应用程序icon按钮的状态会变化,由不可使用变为可以使用,可以通过这个变化做为数据加载结束的判断。

灰色图片为加载前,取名start.png

亮色图片为加载后,取名stop.png

 while True:
        time.sleep(2)
        xyps = pg.locateOnScreen(os.environ['USERPROFILE'] + r'\Desktop\{}'.format("stop.png"))
        # 如果坐标为None,继续循环等待,否则结束循环
        if xyps == None:
            continue
        else:
            time.sleep(2)
            break

注意:在不同的分辨率屏幕上,参照的图片需要重新获取。当CPU高负荷运行,程序会出现无响应,此时该方法因为无法获取应用程序的图像,该方法失效。

3. 当无法找到以上1和2的参照标准时,用timesleep设置足够长的等待时间

time.sleep(希望等待的时间)

f.Excel另存为操作

def saveExcelAs():
    #打开另存为窗口    
    pg.hotkey('fn', 'f12')
    time.sleep(3)
    # 删除默认的文件名
    pg.press("delete")
    time.sleep(2)
    # 把文件名放入剪切板(因为 pyautogui.write不支持输入中文,通过复制黏贴的方法来替换实现)
    pyperclip.copy(“mysaveasfile.xlsx”)
    # 黏贴另存为的文件名
    pg.hotkey('ctrl', 'v')
    time.sleep(2)
    # 保存
    pg.hotkey('alt', 's')
    time.sleep(8)
    # 关闭Excel窗口
    pg.hotkey('alt', 'f4')

三.邮件发送

需要将生成的Excel通过邮件发给相关人员

from email.utils import formataddr

def sendMail():
    pathName = os.environ['USERPROFILE'] + r"\Desktop\{}{}".format(“savefilename”,".xlsx")

    mail_msg = """
     

(Confidential)

{}

测试邮件。请查收附件。

------------------------------------------------------

发送频度:每月,第一周

------------------------------------------------------

以上,谢谢!

""" sender = '[email protected]' to_receivers = ['[email protected]','[email protected]'] cc_receivers = ['[email protected]','[email protected]'] receiver = to_receivers + cc_receivers #本例邮件正文的参数,通过string.format实现 mail_msg = mail_msg.format(“XX经理,您好”) message = MIMEMultipart() message.attach(MIMEText(mail_msg, 'html', 'utf-8')) att1 = MIMEText(open(pathName, 'rb').read(), 'base64', 'utf-8') att1["Content-Type"] = 'application/octet-stream' att1.add_header('Content-Disposition', 'attachment', filename = savefilename + '.xlsx') message.attach(att1) message['From'] = formataddr((测试者', sender)) message['To'] = ",".join(to_receivers) message['Cc'] = ",".join(cc_receivers) subject = '{}' subject = subject.format(“测试邮件”) message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP('192.168.XX.XX') smtpObj.sendmail(sender, receiver, message.as_string()) print("邮件发送成功") except smtplib.SMTPException: print("Error: 无法发送邮件")

需要的邮件地址,如果变动来自文件,将收件人称呼和收件人地址保存到appconfig.txt文件

' [email protected], ' [email protected]
' [email protected], ' [email protected]
赵经理,钱经理
  f = open(os.environ['USERPROFILE'] + r'\Desktop\appconfig.txt', 'r', encoding='UTF-8')
    datalist = f.readlines()
    #读取第一行的邮件地址
    maillist = datalist[0].rstrip('\n')
    #将字符串以逗号分割并保存到数组中
    to_receivers = maillist.split(',')
    #将字符串以逗号分割并保存到数组中
    cc_maillist = datalist[1].rstrip('\n')
    cc_receivers = cc_maillist.split(',')
    receiver = to_receivers + cc_receivers
    # 获取邮件正文中收件人名称
    mail_msg = mail_msg.format(datalist[2].rstrip('\n'),last_month.strftime("%Y"), last_month.strftime("%m"))
    f.close()

四.其他

a.Python实现获取上个月的日期

from datetime import datetime, timedelta
#获取当前时间
today = datetime.today()
#获得当月第一天
firstday = today.replace(day=1)
#获得上个月时间
last_month = firstday - timedelta(days=1)
#格式化日期 202301->2301
new_date = last_month.strftime("%Y.%m")
#转为日期格式为string字符串格式
new_comdate = datetime.strptime(new_date, "%Y.%m")

#日期比较
difdays = (new_comdate - old_date).days

b.Python实现Excel断开外部链接

Excel的操作采用xlwings既支持xls也支持xlsx,还支持批注修改,Range带格式拷贝,综合性比openpyxl(不支持xls),xlrd(只读,不支持xlsx),xlwt(只写),xlutils方便。

Python通过xlwings自动化Excel-持续更新_第8张图片

关键点,可以通过Excel 宏录制的方式获知断开外部的接口和调用方式。

Python通过xlwings自动化Excel-持续更新_第9张图片
ActiveWorkbook.BreakLink Name:= _
"C:\Users\Desktop\daily report\orignal\PSI-全社 (Form).xlsx", Type:= _
xlExcelLinks

接口名:BreakLink

参数1:Name

参数2:Type

改写成Python语言,完整版

xls转xlsx或者反之,可以通过SaveAs中的参数实现

# 断开链接
def breakLinkAndCopytoServer(wbName):

    # 获取excel的link地址
    linkPath = os.environ['USERPROFILE'] + r"\Desktop\PSI-全社 (Form).xlsx"

    # 打开引用外部链接的文件
    origFname = os.environ['USERPROFILE'] + r"\Desktop\orignal\XXX.xlsx"
    excel = win32.gencache.EnsureDispatch('Excel.Application')

    # 以更新的方式打开 
    wb = excel.Workbooks.Open(origFname, UpdateLinks=True)

    # 更新所有Link
    wb.RefreshAll()
    # 断开外部Link
    # xlExcelLinks的值为1
    wb.BreakLink(Name=linkPath, Type=1)

    # 重命名另存子表
    newpath = os.environ['USERPROFILE'] + r"\Desktop\orignal\XXX-new.xlsx"
    # 51:表示另存为 .xlsx 
    # 56:表示另存为 .xls
    wb.SaveAs(newpath, FileFormat=51) 

    # 关闭子表
    wb.Close()
    # 退出Excel应用
    excel.Application.Quit()

c.Python实现Excel的Range复制(带单元格式)

import xlwings as xw

def copyrefSheet(wb_ref, copyrange, dstsheet):
    # 通过Sheet的位置获取第Sheet对象
    src_sheet = wb_ref.sheets[0]
    # 根据参数,复制A:S列的内容到剪贴板
    src_sheet.range(copyrange).copy()
    
    # 通过Sheet的名字获取Sheet对象
    dst_sheet = workbook.sheets[dstsheet]
    # 将剪贴板的内容拷贝到目标SHeet的A:S列
    dst_sheet.range(copyrange).paste()

    # 为了避免执行过程中跳出如下对话框,中断程序,任意复制一个单元格的内容,达到类似清空剪贴板的目的
    dst_sheet.range("A1").copy()

# 调用函数
app = xw.App(visible=False, add_book=False)
wb_refClass = app.books.open("C:\Desktop\xxx.xlsx")
copyrefSheet(wb_refClass, 'A:S', '目标Sheet名字')
Python通过xlwings自动化Excel-持续更新_第10张图片

d.Python实现Excel的Column列的值复制(不带单元格式)

def copyDsttoSrc(sheetName):
    # 指定列所在的Sheet
    sheet = workbook.sheets[sheetName]
    # 获取最大有效行数
    max_rows = sheet.used_range.last_cell.row
    i = 0
    # 进行值的复制
    for src, dst in zip(sheet['AD:AD'], sheet['AI:AI']):
        if i > max_rows:
            break
        else:
            dst.value = src.value
        i = i + 1

 copyDsttoSrc("目标Sheet的名字")

e.Python实现Excel的批注更新

# 批注内容:下期达成率=下半年实际工作日(82)/下半年总工作日(121)
# 更新内容:下期达成率=下半年实际工作日(83)/下半年总工作日(121)
# 希望将Comment中的82/121 更新为 83/121,实现代码如下
def updateComment(sheetName, dstRange):
    sheet = workbook.sheets[sheetName]
    cellAG2 = sheet.range(dstRange)
    oldAG2 = cellAG2.formula_array
    # 获取 82/121的82,并实现82+1,变成83
    arAG2 = oldAG2.split("/", 1)
    intAG2 = int(arAG2[0][1:]) + 1

    beforeVal = arAG2[0][1:]
    afterVal = str(intAG2)
    # 获取单元格的批注
    oldComment = cellAG2.api.Comment.Text()
    # 替换批准中的内容
    newCommnet = oldComment.replace(beforeVal, afterVal)
    # 更新单元格的批注
    cellAG2.api.Comment.Text(newCommnet)

你可能感兴趣的:(python,pycharm,自动化)