Python进阶之资源调用

第三方库应用

openpyxl(excel操作应用)

用途:读取和修改Excel文档,读写xltm、xltx、xlsm、xlsx等类型的文件,可以处理数据量较大的Excel文件。

第三方库文档:https://openpyxl.readthedocs.io/en/stable/usage.html
中文文档:https://www.osgeo.cn/openpyxl/index.html
其他相似库列表:http://www.python-excel.org/

openpyxl 与 xlrd/xlwt 的比较:
两者都是对于excel文件操作的模块,其主要区别在于:
写操作:
xlwt:针对Ecxec2007之前的版本(.xls),无法生成xlsx文件。
openpyxl:主要针对Excel2007之后的版本(.xlsx)。
读写速度:
xlrd/xlwt在读写方面的速度都要优于openpyxl。
文件大小:
xlrd/xlwt:对单个sheet不超过65535行。
openpyxl:对文件大小没有限制。

示例参考网站1:https://www.cnblogs.com/juno3550/p/13363847.html

获取workbook与sheet对象

创建新文件:

from openpyxl import Workbook

# 创建工作簿对象
wb = Workbook()

# 激活sheet;拿到当前文件对象中默认操作的一个sheet,如上次关闭文件时所打开的sheet
ws = wb.active
# 表格在被创建的时候会自动的有一个名字。它们被命名在一个队列中(sheet, ...),可以使用title属性在任何时候来改变它们的名字。
ws.title = "tmp"

# 删除sheet
wb.remove(ws)

# 创建sheet
ws1 = wb.create_sheet("tmp1")  # 默认在最后插入新sheet
ws2 = wb.create_sheet("tmp2", 0)  # 在索引为0的位置插入

# 保存文件(覆盖同名文件的全部内容)
wb.save("文件名称.xlsx")

打开已有文件:

# 打开已有文件
from openpyxl import load_workbook

# 打开指定文件
wb = load_workbook("e:\\test.xlsx")

# 查看所有sheet名
print(wb.sheetnames)  # 返回列表
# 遍历所有sheet名
for sheet in wb.sheetnames:
    print(sheet.title())

# 选择sheet
ws3 = wb["tmp3"]  # 方法1:名称可以作为key进行查找
ws4 = wb.get_sheet_by_name("tmp4")  # 方法2
print(ws3 is ws4)  # True

# 在原有内容上进行修改并保存
wb.save("e:\\test.xlsx")

访问单元格及其值

注意:当一个工作表在内存中被创建时,它里面默认是没有表格对象的,它们只有在第一次被访问的时候才会被创建,从而减少内存占用。因为这个特性,我们要循环表格而不是直接访问它们,这样会将所有的表格对象在内存中创建,就算你没有访问它们中的任何一个值。

openpyxl 读写单元格时,单元格的坐标位置起始值是(1,1),即下标最小值为1。

访问单个单元格:

# 获取最大行列(返回数值)
print(ws3.max_row)
print(ws3.max_column)

# 方法1:指定行列
print(ws3["A2"].value)

# 方法2:指定行列
print(ws3.cell(row=2, column=2).value)  # 行号和列号从1开始

# 方法3:只要访问就会创建对应单元格对象
for i in range(1, 10):
    for j in range(1, 10):
        print(ws4.cell(i, j).value)

行列序号转换:

from openpyxl.utils import get_column_letter, column_index_from_string
# 根据列的数字返回字母
print(get_column_letter(2))  # B
# 根据字母返回列的数字
print(column_index_from_string('D'))  # 4

访问多个单元格:

# 访问指定行数据

print(ws3[1])  # 方法1:索引从1开始
print(ws3[1:3])  # 切片方式,返回二维元组
print(tuple(ws3.rows)[1])  # 方法2:索引从0开始,sheet.rows为生成器, 里面是每一行的数据,每一行又由一个tuple包裹
# 遍历获取每个单元格的值
for cell in ws3[1]:
    print(cell.value)


# 访问指定列数据

print(ws3["A"])
print(tuple(ws3.columns)[1])  # 访问第2列单元格
print(ws3["A:C"])  # 返回二维元组


# 指定范围

# 方法1
print(ws3["A1:B4"])
# 方法2:最多访问两行两列的单元格
for row in ws3.iter_rows(min_row=1, max_row=2, max_col=2):  # 行号和列号从1开始
    for cell in row:
        print(cell)
'''执行结果:
<Cell 'tmp3'.A1>
<Cell 'tmp3'.B1>
<Cell 'tmp3'.A2>
<Cell 'tmp3'.B2>
'''

for row in ws3.iter_cols(min_row=1, max_row=2, max_col=2):  # 行号和列号从1开始
    for cell in row:
        print(cell)
'''注意与上述iter_rows的获取顺序不同
<Cell 'tmp3'.A1>
<Cell 'tmp3'.A2>
<Cell 'tmp3'.B1>
<Cell 'tmp3'.B2>
'''

矩阵置换:

rows = [
    ['Number', 'data1', 'data2'],
    [2, 40, 30],
    [3, 40, 25],
    [4, 50, 30],
    [5, 30, 10],
    [6, 25, 5],
    [7, 50, 10]]
print(list(zip(*rows)))  # 传入二维序列时需要解包
'''执行结果:
[('Number', 2, 3, 4, 5, 6, 7), ('data1', 40, 40, 50, 30, 25, 50), ('data2', 30, 25, 30, 10, 5, 10)]
'''

# 注意:该方法会舍弃缺少数据的列(行)
a1 = [1, 2]
a2 = [4, 5, 6]
print(list(zip(a1, a2)))
'''执行结果:
[(1, 4), (2, 5)]
'''

写数据

写入单元格值:

# 写入常规值

# 方法1
ws3["A1"] = 1
# 方法2:行号和列号从1开始
ws3.cell(row=2, column=2, value="A2")
# 方法3:追加一行数据(即最下方空白处的最左第一个单元格开始)
ws3.append([1, 2, 3])


# 写时间
import time

# 方法1
now_time_1 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
ws3.cell(row=1, column=1, value=now_time_1)

# 方法2
import locale
locale.setlocale(locale.LC_ALL, 'en')
locale.setlocale(locale.LC_CTYPE, 'chinese')
now_time_2 = time.strftime("%Y年%m月%d日 %H:%M:%S")  # 自动传入当前时间
ws3.cell(row=1, column=2, value=now_time_2)

合并单元格
合并单元格以合并区域的左上角的那个单元格为基准,覆盖其他单元格,使之称为一个大的单元格。

相反,拆分单元格后将这个大单元格的值返回到原来的左上角位置。

ws3.merge_cells('A1:B1')  # 合并一行中的几个单元格
ws3.merge_cells('B2:C11')  # 合并一个矩形区域中的单元格

合并后只可以往左上角写入数据,也就是区间中最左上角的坐标。

如果这些要合并的单元格都有数据,只会保留左上角的数据,其他则丢弃。换句话说若合并前不是在左上角写入数据,那么合并后的单元格则不会有数据。

拆分单元格

ws3.unmerge_cells('A1:B1')  # 拆分后,值回写到A1位置
ws3.unmerge_cells('B2:C11')  # 拆分后,值回写到B2位置

设置样式

sheet标签颜色:

ws3.sheet_properties.tabColor = "1072BA"

行高与列宽:

# 第2行行高
ws3.row_dimensions[2].height = 40
# C列列宽
ws3.column_dimensions['C'].width = 30

单元格样式:

'''字体'''
# 等线24号,加粗斜体,字体颜色红色
bold_italic_24_font = Font(name='等线', size=24, italic=True, color=colors.RED, bold=True)
# 直接使用cell的font属性,将Font对象赋值给它
ws3['A1'].font = bold_italic_24_font

'''对齐方式'''
# 设置B1中的数据垂直居中和水平居中(除了center,还可以使用right、left等参数)
ws3['B1'].alignment = Alignment(horizontal='center', vertical='center')

pywinauto(windows自动化GUI)

pywinauto是一组用于自动化Microsoft Windows GUI的python模块。 最简单的是,它允许您将鼠标和键盘操作发送到窗口对话框和控件。但有些软件本身就是不可被访问的,还有就是中文问题。
第三方库文档:https://pywinauto.readthedocs.io/en/latest/getting_started.html
中文文档:https://www.kancloud.cn/gnefnuy/pywinauto_doc/1193046
参考网站:https://www.bbsmax.com/A/Vx5MYanL5N/

问题记录

需要管理员权限打开的的进程【报错:pywintypes.error: (740, ‘CreateProcess’, ‘请求的操作需要提升。’)】
解决方法:
打包.exe后用管理员方式打开
代码实现管理员权限

import ctypes, sys
import os
def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False
if is_admin():
    # 这里写入需要管理员权限执行的操作
    # app = Application(backend = "uia").start(r"D:\XXXX.exe")
    pass
else:
    if sys.version_info[0] == 3:
        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)

报错:pywinauto打开程序时报错pywinauto.application.AppStartError: Could not create the process “MDK527pre:
解决方法:
将start(‘F:\KEIL527\MDK527pre.exe’) 改为start(r'F:\\KEIL527\\MDK527pre.exe')或者start(r'F:/KEIL527/MDK527pre.exe')

自动安装腾讯QQ:(软件默认为win32)

from pywinauto import application
import time

#QQ自动安装例子**
app = application.Application().start('D:\software_用户软件\QQ9.0.3.exe')
time.sleep(2)

#2.获取 执行程序的窗体
# 在不知道窗体名称,可以报错的方式查找窗体名称
# window_title=['无标题-记事本']
# print(app[window_title].wrapper_object())
window_title='腾讯QQ安装向导'

#3.查看一个窗体含有的控件,子窗体,菜单
# print(app[window_title].print_control_identifiers())

#4.触发窗体含有的控件,子窗体,菜单
#触发方式:app[window_title].child_window(title='窗体名',class_name="窗体类名")

#.click() 点击事件
#.set_edit_text() 设置Edit
# 更多方式可以 通过help(app[window_title].child_window(class_name="Edit"))查到

#点开QQ安装自定义选项
app[window_title].child_window(title="自定义选项").click()
time.sleep(1)

#修改默认安装路径
app[window_title].child_window(class_name="Edit").set_edit_text(r'D:\Program Files (x86)\Tencent\QQ')

#取消自启动
app[window_title].child_window(title="添加到快速启动栏").click()
app[window_title].child_window(title="开机自动启动").click()

#执行安装
# print(app[window_title].print_control_identifiers())
# help(app[window_title].child_window(class_name="#32770").child_window(title="立即安装", class_name="Button").click())
app[window_title].child_window(class_name="#32770").child_window(title="立即安装", class_name="Button").click()
time.sleep(40)
# print(app[window_title].print_control_identifiers())
app[window_title].child_window(class_name="#32770").child_window(title="安装QQ浏览器", class_name="Button").uncheck_by_click()
app[window_title].child_window(class_name="#32770").child_window(title="安装QQ游戏 免费获取专属礼包", class_name="Button").uncheck_by_click()
app[window_title].child_window(class_name="#32770").child_window(title="安装QQ音乐播放器", class_name="Button").uncheck_by_click()
app[window_title].child_window(class_name="#32770").child_window(title="完成安装", class_name="Button").click()

自动安装话务软件:(软件默认为uia),这个软件自动安装有点特殊,启动的进程不是窗口进程,所有拿不到窗口对象,所以采用connect 进程号的方式去获取 启动的窗口对象.

from pywinauto import application
import time
import psutil
import re
import os

os.popen('D:\software_用户软件\X-Lite电话系统.exe')
time.sleep(1)
PID = 0
for proc in psutil.process_iter():
    try:
        pinfo = proc.as_dict(attrs=['pid', 'name'])
    except psutil.NoSuchProcess:
        pass
    else:
        if re.match(r'^is.*?.tmp$',pinfo['name']):
            PID = pinfo['pid']
# print(PID)
app = application.Application(backend='uia').connect(process=PID)
# print(app.window(class_name='TWizardForm').print_control_identifiers())
# print(dir(app.window(class_name='TWizardForm')))
app.window(class_name='TWizardForm').child_window(title="Next >",control_type="Button").click()
# print(app.window(class_name='TWizardForm').print_control_identifiers())
app.window(class_name='TWizardForm').child_window(title="I accept the agreement", control_type="RadioButton").click()
app.window(class_name='TWizardForm').child_window(title="Next >", control_type="Button").click()
# print(app.window(class_name='TWizardForm').print_control_identifiers())
app.window(class_name='TWizardForm').child_window(title="To continue, click Next. If you would like t"
                                                        "o select a different folder, click Browse.",
                                                  control_type="Edit").set_edit_text(r'D:\Program Files (x86)\CounterPath\X-Lite')
app.window(class_name='TWizardForm').child_window(title="Next >",control_type="Button").click()
app.window(class_name='TWizardForm').child_window(title="Next >",control_type="Button").click()
time.sleep(2)
# print(app.window(class_name='TWizardForm').print_control_identifiers())
# print(dir(app.window(class_name='TWizardForm').child_window(title="Launch X-Lite", control_type="CheckBox")))
app.window(class_name='TWizardForm').child_window(title="Finish", control_type="Button").click()

pywin32(GUI)

问题记录:

打包版本和pywin不兼容:The application can not locate Python39.dll (126)找不到指定的模块。
解决方法:
出错版本: pyinstaller 4.1 pywin32 300
修改后: pyinstaller 4.1 pywin32 226

模拟按键模拟键盘按键按下放开

import win32con
import win32api
import time
# 模拟A

win32api.keybd_event(65,0,0,0)  #按下
time.sleep(0.1)                            #延迟一会儿
win32api.keybd_event(65,0,win32con.KEYEVENTF_KEYUP,0)  #松开

键盘按键和键盘对应代码表:
A <--------> 65 B <--------> 66 C <--------> 67 D <--------> 68
E <--------> 69 F <--------> 70 G <--------> 71 H <--------> 72
I <--------> 73 J <--------> 74 K <--------> 75 L <--------> 76
M <--------> 77 N <--------> 78 O <--------> 79 P <--------> 80
Q <--------> 81 R <--------> 82 S <--------> 83 T <--------> 84
U <--------> 85 V <--------> 86 W <--------> 87 X <--------> 88
Y <--------> 89 Z <--------> 90 0 <--------> 48 1 <--------> 49
2 <--------> 50 3 <--------> 51 4 <--------> 52 5 <--------> 53
6 <--------> 54 7 <--------> 55 8 <--------> 56 9 <--------> 57
数字键盘 1 <--------> 96 数字键盘 2 <--------> 97 数字键盘 3 <--------> 98
数字键盘 4 <--------> 99 数字键盘 5 <--------> 100 数字键盘 6 <--------> 101
数字键盘 7 <--------> 102 数字键盘 8 <--------> 103 数字键盘 9 <--------> 104
数字键盘 0 <--------> 105
乘号 <--------> 106 加号 <--------> 107 Enter <--------> 108 减号 <--------> 109
小数点 <--------> 110 除号 <--------> 111
F1 <--------> 112 F2 <--------> 113 F3 <--------> 114 F4 <--------> 115
F5 <--------> 116 F6 <--------> 117 F7 <--------> 118 F8 <--------> 119
F9 <--------> 120 F10 <--------> 121 F11 <--------> 122 F12 <--------> 123
F13 <--------> 124 F14 <--------> 125 F15 <--------> 126
Backspace <--------> 8
Tab <--------> 9
Clear <--------> 12
Enter <--------> 13
Shift <--------> 16
Control <--------> 17
Alt <--------> 18
Caps Lock <--------> 20
Esc <--------> 27
空格键 <--------> 32
Page Up <--------> 33
Page Down <--------> 34
End <--------> 35
Home <--------> 36
左箭头 <--------> 37
向上箭头 <--------> 38
右箭头 <--------> 39
向下箭头 <--------> 40
Insert <--------> 45
Delete <--------> 46
Help <--------> 47
Num Lock <--------> 144
; : <--------> 186
= + <--------> 187
- _ <--------> 189
/ ? <--------> 191
` ~ <--------> 192
[ { <--------> 219
| <--------> 220
] } <--------> 221
'' ' <--------> 222

PyUserInput(键盘、鼠标模拟)

问题记录:

Python:ModuleNotFoundError: No module named ‘windows’:
前往网站->http://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载PyHook

想要使用PyKeyboard,需要先安装:pywin32->pyHook->PyUserInput


 上一篇
STM32 STM32
STM32安装下载调试keil5安装包下载:www.aflasdkasda;lsdaksa;d;alskda;sd;alk芯片支持包下载:https://www.keil.com/dd2/pack/1、烧写器方式: #JTAG 1
2021-02-15
下一篇 
Python语言 Python语言
——取自崇天老师的视频(中国大学MOOC),文章不适合新手,此文章只作为记忆记录方便查阅,记录的标准为方便自己再次学习和直接利用资源—— 官方文档:http://docs.python.org/zh-cn/3/建议作为某些疑惑内容深入理解和
2021-01-22
  目录