本节介绍几个比较实用的综合实例,通过实战来加强对win32com包的学习和理解。
批量新建和删除工作表
使用win32com可以批量新建和删除工作表。
一、批量新建工作表
使用for循环,利用Worksheets对象的Add方法批量新建工作表。
1 import win32com.client as win32
2 app=win32.gencache.EnsureDispatch("excel.application")
3 app.Visible=True
4 bk=app.Workbooks.Add()
5 for i in range(1,11):
6 bk.Worksheets.Add(After=bk.Worksheets(bk.Worksheets.Count))
第1行导入win32com包,别名为win32。
第2-3行创建Excel应用app,设置它的Visible属性的值为True,使之可见。
第4行用Workbooks对象的Add方法创建工作簿对象bk。
第5-6行用1个for循环批量新建10个工作表。新建工作表使用的是Worksheets对象的Add方法,用After参数定义新建的工作表放在已有工作表的最后面。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,批量新建10个工作表如图6-4所示。
图6-4 批量新建工作表
二、批量删除工作表
使用for循环,利用Sheets对象的Delete方法批量删除指定工作簿中的工作表。
1 import win32com.client as win32
2 import os
3 app=win32.gencache.EnsureDispatch("excel.application")
4 app.Visible=True
5 root = os.getcwd()
6 bk=app.Workbooks.Open(root+r"/test01.xlsx")
7 app.DisplayAlerts=False
8 for i in range(11,1,-1):
9 bk.Sheets(i).Delete()
10 app.DisplayAlerts=True
第1-2行导入win32com包和os包。
第3-4行创建Excel应用对象并使之可见。
第5行获取本py文件所在的目录,即当前目录。
第6行用Workbooks对象的Open方法打开同目录下的test01.xlsx文件,返回工作簿对象。
第7行设置Excel应用对象app的DisplayAlerts属性的值为False,这样设置以后,后面删除工作表的时候就不会弹出提示信息对话框,就可以实现连续删除。
第8-9行用1个for循环实现批量删除10个工作表。注意range函数的参数,范围的起始位置和终止位置是从11到1,是从大到小的,步长为-1,递减。这样处理是因为连续删除时剩下的工作表在Sheets集合中的索引号不会变。如果从1到11,即从小到大迭代,把前面的工作表删除以后,后面工作表的索引号会自动减1,变动了,最后会导致出错。
第10行将app的DisplayAlerts属性的值恢复为True。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,从后往前批量删除10个工作表。
按工作表某列分类拆分到多个工作表
现有各部门工作人员信息如图6-5处理前工作表中所示。现在要根据第1列的值对工作表数据进行拆分,每个部门的人员信息归总到一起组成一个新表,表的名称为该部门的名称。拆分的思路是遍历工作表的每一行,如果以部门名称命名的工作表不存在,则创建该名称的新表;如果已经存在,则将该行信息追加到该已经存在的工作表中。
图6-5 按部门拆分工作表到多个新表
使用win32com包进行拆分的代码如下所示。
1 import win32com.client as win32
2 from win32com.client import Dispatch,constants
3 import os
4 app=win32.gencache.EnsureDispatch("excel.application")
5 app.Visible=True
6 root = os.getcwd() #获取当前工作目录,即本py文件所在目录
7 bk=app.Workbooks.Open(root+r"/各部门员工.xlsx") #打开数据文件
8 app.ScreenUpdating=False
9 app.DisplayAlerts=False
10 sht=bk.Worksheets(1) #获取“汇总”工作表
11 irow=sht.Range("A"+str(sht.Rows.Count)).End(constants.xlUp).Row
12 strs=[] #新建列表,用于保存已经新建工作表的名称
13 #遍历数据表的每一行
14 for i in range(2,irow+1):
15 sht2=bk.Worksheets("汇总")
16 strt=sht2.Range("A"+str(i)).Text #获取该行所属部门名称
17 if(strt not in strs):
18 #如果是新部门,添加名称到strs列表,复制表头和数据
19 strs.append(strt)
20 bk.Worksheets.Add(After=bk.Worksheets(bk.Worksheets.Count))
21 bk.ActiveSheet.Name = strt
22 bk.Worksheets("汇总").Rows(1).Copy(bk.ActiveSheet.Rows(1))
23 bk.Worksheets("汇总").Rows(i).Copy(bk.ActiveSheet.Rows(2))
24 else:
25 #如果是已经存在的部门名称,直接追加数据行
26 bk.Worksheets(strt).Select()
27 r=bk.ActiveSheet.Range("A"+\
28 str(bk.ActiveSheet.Rows.Count)).\
29 End(constants.xlUp).Row + 1
30 bk.Worksheets("汇总").Rows(i).Copy(bk.ActiveSheet.Rows(r))
31
32 #删除新生成的工作表的第一列
33 for i in range(1,bk.Worksheets.Count+1):
34 bk.Worksheets(i).Columns(1).Delete()
35
36 app.ScreenUpdating=True
37 app.DisplayAlerts=True
第1-3行导入win32com包、win32com包中的constants模块和os包。设置对象方法的参数为枚举值时需要使用constants模块。
第4-5行创建Excel应用对象并使之可见。
第6行获取py文件所在的目录,即当前目录。
第7行打开数据文件。
第8-9行设置Excel应用对象的ScreenUpdating和DisplayAlerts属性的值为False,取消窗口重画和警告提示信息对话框的显示。
第10-11行获取工作簿中的第1个工作表,获取该工作表中数据区域的行数。
第12行创建空列表strs,列表中的元素对应于已经存在的部门工作表的名称。
第14-30行遍历数据表中各行,实现工作表按部门取值进行拆分。
第15行获取“汇总”工作表。
第16行获取当前行第1个单元格中的文本,即部门名称。
第17-30行判断刚刚获取的部门名称是否被包含在strs列表中,如果不在,就创建新表添加数据;如果在,则将该行数据追加到与部门名称同名的工作表中。
第19-23行向strs列表中追加部门名称,添加工作表到所有工作表末尾,名称为部门名称。将“汇总”表的表头复制到新表第1行,将该行数据复制到新表第2行。
第25-30行计算与部门名称同名的工作表中数据区域的下一行行号,将“汇总”表中当前行的数据复制过来。
第33-34行用for循环删除新生成的工作表的第1列,即“部门”列。
第36-37行恢复Excel应用对象的ScreenUpdating和DisplayAlerts属性的值为True。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,进行工作表拆分。拆分效果如图6-34中处理后各工作表中所示。
将多个工作表分别保存为工作簿
现有各部门工作人员信息如图6-6处理前工作表中所示。不同部门工作人员的信息单独放在一个工作表中,现在要将不同工作表中的数据单独保存为工作簿文件。
图6-6 将多个工作表分别保存为工作簿文件
下面用win32com包将各工作表数据保存为单独的工作簿文件。
使用win32com包来实现的代码如下所示。
1 import win32com.client as win32
2 import os
3 app=win32.gencache.EnsureDispatch("excel.application")
4 app.Visible=True
5 root = os.getcwd()
6 bk=app.Workbooks.Open(root+r"/各部门员工.xlsx") #打开数据文件
7
8 app.ScreenUpdating=False
9 #遍历每个工作表,分别保存
10 for sht in bk.Worksheets:
11 sht.Copy()
12 app.ActiveWorkbook.SaveAs(root+"\\"+sht.Name+".xlsx", 51)
13 app.ActiveWorkbook.Close()
14
15 app.ScreenUpdating=True
第1-2行导入win32com和os包。
第3-4行创建Excel应用对象并使之可见。
第5行获取py文件所在的目录,即当前目录。
第6行打开当前目录下的数据文件。
第8行设置Excel应用对象的ScreenUpdating属性的值为False,取消窗口重画。
第10-13行用1个for循环遍历各工作表,实现各工作表数据的单独保存。
第11行用不带参数的Copy方法创建一个新的工作簿并将原始工作表中的数据拷贝过来。新创建的工作簿即为活动工作簿。
第12行把活动工作簿中的数据保存到文件,文件名称为原始工作表的名称。
第13行关闭新生成的工作簿。
第15行恢复Excel应用对象的ScreenUpdating属性的值为True。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,保存各工作表中的数据。处理效果如图6-35中处理后各工作表中所示。
将多个工作表合并到一个工作表
6.2.2小节将一个工作表根据某个列的值拆分为多个工作表,这里反过来,将多个工作表中的数据合并到一个工作表。
现有各部门工作人员信息如图6-7处理前工作表中所示。不同部门工作人员的信息单独放在一个工作表中,现在要将不同工作表中的数据合并到“汇总”工作表中,并添加“部门”列,列的值为数据来源工作表的表名。
图6-7 多个工作表合并为一个工作表
下面用win32com包将各工作表数据合并到“汇总”工作表。
使用win32com包来实现的代码如下所示。
1 import win32com.client as win32
2 from win32com.client import Dispatch,constants
3 import os
4 app=win32.gencache.EnsureDispatch("excel.application")
5 app.Visible=True
6 root=os.getcwd()
7 bk=app.Workbooks.Open(root+r"/各部门员工.xlsx") #打开数据文件
8 sht= bk.Worksheets("汇总")
9 #清空“汇总”表
10 sht.Cells.Clear()
11 #复制表头
12 sht.Range("A1").Value = "部门"
13 bk.Worksheets(1).Range("A1:D1").Copy(sht.Range("B1"))
14 #遍历"汇总"工作表外的每个工作表,复制数据
15 for shtt in bk.Worksheets:
16 if shtt.Name!="汇总":
17 rngt=shtt.Range("A2",shtt.Cells(shtt.\
18 Range("A"+str(shtt.Rows.Count)).\
19 End(constants.xlUp).Row,4))
20 row=sht.Range("A1").CurrentRegion.Rows.Count+1
21 rngt.Copy(sht.Cells(row,2)) #复制数据
22 #在第一列添加部门名称
23 rt=sht.Range("A"+str(sht.Rows.Count)).\
24 End(constants.xlUp).Row+1
25 row2=shtt.Range("A1").CurrentRegion.Rows.Count-1
26 rt2=rt+row2
27 for i in range(rt,rt2):
28 sht.Cells(i,1).Value=shtt.Name
第1-3行导入win32com包、win32com包的constants模块和os包。
第4-5行创建Excel应用对象并使之可见。
第6行获取py文件所在的目录,即当前目录。
第7行打开当前目录下的数据文件。
第8行获取“汇总”工作表。
第10行清空“汇总”工作表。
第12-13行把第1个工作表的表头复制到“汇总”表B1到E1单元格,A1单元格添加“部门”。
第15-28行用1个for循环遍历各工作表,将各部门工作表的数据复制粘贴到“汇总”工作表,并在第1列添加对应的部门名称。
第17-21行将各部门工作表的数据复制粘贴到“汇总”工作表。第17-19行实为1行,用斜杠表示续行。该行取得源工作表的数据区域。第20行获取“汇总”工作表中当前数据区域的行数,将行数加1即为追加数据的起始位置。第21行用Copy方法将源数据复制到“汇总”工作表。
第23-28行在“汇总”工作表的第1列添加部门名称。变量rt和rt2记录该次追加数据在“汇总”工作表中的起始行和终止行。第27-28行用for循环将当前工作表的名称作为“部门”列的值进行添加。
在Python IDLE文件脚本窗口,在"Run"菜单中单击"Run Module"选项,合并各工作表中的数据到”汇总“工作表,并添加”部门“列。处理效果如图6-7中处理后“汇总“工作表中所示。