win32com 操作excel

news/2024/11/23 4:06:12/

目录

打开表格,读取数据

获取到当前已打开的excel (22/9/20)

win32的写入操作 与 下拉列表(数据验证)

隐藏表(行列)

刷格式 

数据透视表 

复制粘贴,快速下拉



使用win32com操作excel有点类似于VBA(双厨狂喜),这是一个很顾名思义的库,他的作用是模拟用户去做一些操作,像一些简单的例如操作office全家桶完全不在话下。

安装

pip install pywin32

以下进入正文:

打开表格,读取数据

import win32com.clientpath=r'C:\Users\gztsrayz\Desktop\酸奶.xlsx'
excel = win32com.client.DispatchEx('Excel.Application')   #这个是必备的,使用win32建新excel也需要他
excel.Visible = True          #是否可视化
wb = excel.Workbooks.Open(path, UpdateLinks=False, ReadOnly=False)wb1 = excel.Workbooks.Add()   #新建excelwb1.Worksheets.Add().Name = '帅比'   #新建sheet,.Name 与后面可不写
ws1 = wb1.Worksheets('帅比')wb.Save()     #保存
wb.SaveAs(r'C:xxx/xxx/milk.xlsx')    #另存为
wb.Close(False)               #关闭,问就是不保存
#如果你想看到excel温馨的提示,括号里就别填东西
excel.quit()
print([i.Name for i in wb.Sheets])     #查看已有sheet名
ws = wb.Worksheets('汇总')
#ws = wb.Worksheets(1)
#ws = wb.Worksheets[0]                #同样的,通过名字或者位置来指定表#在测试的时候还发现通过位置选定表时()和[]都可用,但是[]获取位置是从0开始计

ws.UsedRange.Rows                #最大使用行(包括中间的空行),注意某些行若曾经存在过数据
ws.UsedRange.Columns             #即单元格被设置了格式,使用此种方法会被判定为被占用#导致读出来的行数可能并不正确
ws.Range("A1").End(-4121).Row       # 模拟 ctrl + ↓ ,从此格往下读到空行,或者跳过空行
ws.Range("A100").End(-4162).Row     # ctrl + ↑list0=ws.Range('A2:A5').Value        #跨行读出来是二维元组
sheet1.Range('A2:Z2').AutoFilter(17,"精英干员")  #筛选

=========================================================================

获取到当前已打开的excel (22/9/20)

当我们打开多个同样的表时,从第二个开始都会变成只读模式。

当关掉第一份表,第二份表就会弹出提示,而这个提示会导致我们的代码报错

判断这个excel是否打开,可以利用os遍历文件夹判断是否存在临时文件

        for i in os.listdir(path0):if '~$' in i and 'xlsx' in i:  #可以用名字判断,更加准确breakelse:print('此文件已打开')time.sleep(0.5)sys.exit()

但是这样只能够判断是否打开,而无法接着打开的excel进行操作,于是又尝试了下面这一段代码

import win32com.client
ee = win32com.client.GetActiveObject('Excel.Application')   #只能用注册名
print(ee.name)
# ee = ee.Workbooks(1)   #当只有一个excel时此句可有可无
# print(ee.name)
ws =ee.Worksheets(1)
ws.Range('A1').Value===============================
if len(ee.Workbooks)>1:   #判断该进程下有多少打开的excel文件for i in ee.Workbooks:print(i.name)
else:print(ee.Workbooks(1).name)

值得注意的是,我们每次使用win32com打开excel都会生成一个新的进程,而人手打开的excel会归在同一个进程下 (此图中第一个进程为人手打开)

而代码似乎只能识别到第一个进程?(后续我会继续尝试可否识别到第二第三个进程)

也就是说若第一个进程是以人手打开的情况下,我们可以很轻松的判断这个文件是否打开,并且接手它。(PS:当然这里只是举个例子,事实上我们每次使用win32com操作完excel都应该关闭创建的excel进程,除非有特例如user运行完了不希望退出excel以方便直接观看)

如果你的第一个进程是win32com创建的,哪怕你将它所打开的excel关闭了,也依然会读取到这个进程,然后报错

在注释掉此句代码之后,我们会获取到目前活跃的excel文件(即最近一次选中的excel)(仅限在第一个进程中)

ee = ee.Workbooks(1)

 通过接手直接打开的excel 而不是使用win32com打开,在关闭的时候我们可以减去关闭excel进程的这一操作,因为进程会在我们关闭excel时自动结束。

 =========================================================================

win32的写入操作 与 下拉列表(数据验证)

list1=[['das'],['hdfg'],['asg'],[456]]
list2=[45,132,46]
ws.Range('G1:G4').Value=list1
ws.Range('H1:J1').Value=list2#亦或者是
ws.Range(ws.Cells(1,1),ws.Cells(2,2)).Value=[['a','s'],['d','a']]

ws.Range('C1:C5').Validation.Add(Type=3, AlertStyle=1, Operator=1, Formula1="=$G$1:$G$7")
#   $  符号不能少
#注意数据验证的源范围只能在同excel内
#val = ws.Cells(6,1).Validation
#val.Add(Type=3, AlertStyle=1, Operator=1, Formula1="=Sheet1!A1:A5")
#val.IgnoreBlank = -1
#val.InCellDropdown = -1
#val.InputTitle = ""
#val.ErrorTitle = ""
#val.InputMessage = ""
#val.ErrorMessage = ""
#val.ShowInput = -1
#val.ShowError = -1

========================================================================= 

隐藏表(行列)

ws.Visible= False   #隐藏sheet,显示为True,隐藏为False
ws.Range('A:G').EntireColumn.Hidden=True
ws.Range('1:5').EntireRow.Hidden=True

========================================================================= 

刷格式 

既然有写入,那么自然就要刷格式

ws.Range("A1:B1").Interior.ColorIndex=44           #刷单元格颜色
ws.Range("A2").Font.ColorIndex=23                   #刷字体颜色
ws.Range('A2:B2').NumberFormatLocal = "@"     #设置单元格格式为文本
ws.Range("A1:B1").Font.Bold = True            #加粗
ws.Range("C1:D1").Merge()          #合并单元格,合并之后读写均需选中第一个单元格ws.Range("A1:T1").Columns.AutoFit() 
#自动调节边框宽度,有时调节出来不准确,需要手动再校正
ws.Range("A1").ColumnWidth = 40          # 手动设置宽度

 ps : 这个B列就是我说的时灵时不灵的情况

 =========================================================================

数据透视表 

给大家来一个数据透视表的简单版:

PivotSourceRange = ws.Range("M1:O10")    #数据源
PivotTargetRange = ws.Range("R2")        #存放位置PivotCache = wb.PivotCaches().Create(SourceType=1, \
SourceData=PivotSourceRange, Version=5)
#这里的version需要注意,不同版本的excel可能version会有偏差PivotTable = PivotCache.CreatePivotTable(\
TableDestination=PivotTargetRange,TableName=PivotTableName)
PivotTable.PivotFields("不能说的").Orientation = 1               #行筛选 
PivotTable.PivotFields("我好想你").Orientation = 4     #求和项值   

 =========================================================================

复制粘贴,快速下拉

在我刚开始使用win32com的时候,时常会遇到要先将数据源筛选再拿取的情况,我一开始的想法是,先筛选再全部吃,但是这种方法,不论你使用win32com还是xlrd读取数据,你获得的最大行列都是不受筛选影响的。后来我想到了不进行   AutoFilter  筛选,而是在我吃数据的时候添加筛选条件,但是这样如果条件多的话,写出来会很冗杂很不美观,(ps:虽然长名称确实易于理解,但是放在长代码里却会看的人眼花缭乱)

ws.AutoFilterMode=False   #取消这个表的所有筛选
ws.Range('A1:Q1').AutoFilter(7,'精英干员')  #在你选定的范围中是第几列
ws.Range('A1:Q1').AutoFilter(6,'*龙门*')
ws.Range('A1:Q1').AutoFilter(5,'人外娘')
============================================
list1=[]
for i in (0,nrows):if ws.Range('E%d'%i).Value=='人外娘' and ws.Range('F%d'%i).Value=='龙门' and ws.Range('G%d'%i).Value=='精英干员':list1.append(ws.Range('A%d:Q%d'%(i,i)).Value)

再后来我发现了复制粘贴的方法,虽然与一开始一样,获得的最大行是筛选前的,但是被筛选隐藏的部分却不会被选中,这样一来我就能让我的代码更加的简洁,在写入的时候也不用再一行行的写入,运行时间得到了极大的提升。

ws.Range('A1:Q1').AutoFilter(7,'精英干员')
ws.Range('A1:Q1').AutoFilter(6,'龙门')
ws.Range('A1:Q1').AutoFilter(5,'人外娘')wb.Worksheets.Add().Name='铜雀台'
ws1=wb.Worksheets('铜雀台')ws.Range('A1:Q%d'%nrows).Copy(ws1.Range('A1')) #同理Cut则是剪切# ws1.Range('K1').Copy()
# ws1.Range('K14').PasteSpecial(-4163)   #值粘贴

这样一来,我就将8行的代码直接缩短了一半

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

excel的使用总不会是单纯的复制粘贴,我们经常需要将数据进行一些加工处理

比如最经典的成绩单

不论数据的多少,我们总是习惯使用公式,包括但不仅限于excel的函数,在我最开始使用win32com的时候,我使用的是这种方法:

for i in range(0,nrows):ws.Range('H%d'%i).Value='=F%d+G%d'%(i,i)

 但很快我就发现了这种方法的局限性,平时玩玩还可以,但要是放到大文件中,它写入的速度就实在是太慢了,excel的处理经常一个表就会有上千近万条,像这样一个一个格子得写到什么时候啊

于是我又发现了这种方法

ws.Range('H2').Value='=F2+G2'
ws.Range('H2').AutoFill(ws.Range('H2:H%d'%nrows))

我只需要声明一次我要的方法,后面的格子就会自动调用

使用这两种方法,我原来运行一次要六分钟的代码,现在只需要几十秒就能解决。

 
小贴士

 最后的最后,给大家一个温馨的提示

因为win32com部分内容是VBA与差不多的,所以可能大家会感到困惑。

这种时候我们只需要打开excel的视图,点击录制宏,录制下我们想进行的操作,

然后再查看宏,就能看到这些操作的VBA代码啦


http://www.ppmy.cn/news/373734.html

相关文章

博途 WinCC VBS 记录笔记

如何在一个脚本中访问数组中的元素? 对数组元素的访问是通过数组的名称和数组中由括号分隔的数组索引来实现的:“SmartTags("Array Name")(array index) ” 例如 访问数组 "DB10_HMI_Data" 的第二个元素 : Dim Tag_01…

「项目案例」使用西门子博途 SCL高级语言编写

此项目用博途 SCL高级语言编写如何开启运行时间最少的几台设备 需求: 如果客户共有8台水泵,4用4备,但每次启动设备时累计运行时需要最运行时间最短的4台运行。 解析: 如果使用梯形图来写的话,此程序会非常复杂&#xf…

计算机office demo,办公软件应用(Office2007)中级_DEMO盘-2013

办公软件应用(Office2007)中级_DEMO盘-2013 第1大题: 一、启动“资源管理器”。 解题步骤: 1.在桌面上,选中“计算机”项,单击鼠标右键选中“资源管理器”项。 二、在C盘下新建文件夹,文件夹名为“4000001”。 解题步骤…

ASP.NET教育行业OA办公系统源码(带文档)免费分享

ASP.NET教育OA源码 教育行业OA源码带文档 需要源码学习可私信。 一、源码描述 这款教育OA是对整个教学业务信息进行管理,其中包括教师排课,学生基本信息,学生学籍变更,成绩管理,宿舍管理,后勤服务等。对…

Wincc常用C脚本

原创作品,如需转载请注明出处 文章目录 1 set/get相关2 用户登录/注册3 操作项目4 弹窗5 操作元素6 WINCC中制作一个保持型按钮7 声光报警8 动画脚本电机风扇旋转(几何---起始角度):9 物料水平右移动(几何---位置X&am…

WinCC 使用VBS脚本操作变量、控件总结

WinCC的VBS脚本,变量的读写不用定义变量类型。 自读自写 Dim objvar Set objvar HMIRuntime.Tags(WinCC_Tag) objvar.Read objvar.Value objvar.Value 1 objvar.Write写入变量WinCC_Tag数值100 方法一 HMIRuntime.Tags(WinCC_Tag).Write 100方法二 Dim objvar …

wincc里vbs脚本

各位大佬好,初学代码,有很多疑问请教 wincc里变量从别的地方录入后,它的数值是在不断变化的,在变量归档后可以在表格控件里显示, 如果我想对表格里的某列数据进行运算操作,实际就是把某个变量的历史值做一次…

DSP之Controlsuit和C2000Ware下载安装

DSP之Controlsuit和C2000Ware下载安装 Controlsuit 用于 C2000TM 微处理器的 controlSUITETM 是一套全面的软件基础设施和软件工具集,旨在最大程度地缩短软件开发时间。从特定于器件的驱动程序和支持软件到复杂系统应用中的完整系统示例,controlSUITET…