- 本文内容来源于《超简单:用Python让Excel飞起来实战150例》
- Excel的工作表是由行和列组成的,因此,学习完工作表的操作,就需要接着学习行和列的操作。本章将详细介绍如何使用Python操作工作表的行和列,如调整行高和列宽、插入和删除行或列、提取和替换行列数据等。
根据数据内容自动调整一个工作表的行高和列宽
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\副本案例1.xlsx')
worksheet = workbook.sheets[0]
worksheet.autofit()
workbook.save()
workbook.close()
app.quit()
- 在第5行代码中,autofit()是xlwings模块中Sheet对象的函数,用于根据单元格的内容自动调整整个工作表的行高和列宽。该函数有一个参数axis:如果省略,表示同时调整行高和列宽;如果设置为’rows’或’r’,表示仅调整行高;如果设置为’columns’或’c’,表示仅调整列宽。例如将代码改为worksheet.autofit(axis=‘c’),就表示仅自动调整工作表的列宽。
精确调整一个工作表的行高和列宽
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\副本案例1.xlsx')
worksheet = workbook.sheets[1]
area = worksheet.range('A1').expand('table')
area.column_width = 15
area.row_height = 40
workbook.save()
workbook.close()
app.quit()
调整一个工作簿中所有工作表的行高和列宽
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\副本案例1.xlsx')
worksheet = workbook.sheets
for i in worksheet:
i.autofit()
workbook.save()
workbook.close()
app.quit()
- 运行完该代码后,可看到单元格的行高和列宽根据内容的多少自动进行了调整。
调整多个工作簿的行高和列宽
from pathlib import Path
import xlwings as xw
app = xw.App(visible=False,add_book=False)
folder_path = Path('D:\python自动化office')
file_list = folder_path.glob('*.xls')
for i in file_list:
workbook = app.books.open(i)
worksheet = workbook.sheets
for j in worksheet:
j.autofit()
workbook.save()
workbook.close()
app.quit()
在一个工作表中插入空白行
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook['非专业组']
worksheet.insert_rows(6,1)
workbook.save('第十二届大学生数学竞赛考试安排1.xlsx')
在一个工作表中每个一行插入空白行
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook['专业组']
num = 2
last_num = worksheet.max_row
for i in range(0,last_num):
worksheet.insert_rows(i*(num+1)+3,num)
workbook.save('第十二届大学生数学竞赛考试安排2.xlsx')
- 第4行代码用于指定插入空白行的数量,读者可根据实际需求修改。第5行代码用于获取工作表中数据区域的行数。
- 第6行和第7行代码用于在工作表中每个员工的数据行下插入两个空白行。如果要在标题行下方也插入空白行,则将第7行代码中的"3"修改为"2".
在一个工作表中插入空表列
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook['非专业组']
worksheet.insert_cols(5,1)
workbook.save('第十二届大学生数学竞赛考试安排3.xlsx')
在一个工作表中删除行
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook['专业组']
worksheet.delete_rows(6,2)
workbook.save('第十二届大学生数学竞赛考试安排4.xlsx')
在一个工作表中删除列(方法一)
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook['专业组']
worksheet.delete_cols(6,2)
workbook.save('第十二届大学生数学竞赛考试安排5.xlsx')
在一个工作表中删除列(方法二)
- 本案例中要讲解删除列的第2中方法:用pandas模块读取工作簿中的数据,然后用drop()函数删除列,再将数据写入工作簿。
import pandas as pd
data = pd.read_excel('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx',sheet_name=1)
data.drop(columns=['年级','班级'],inplace=True)
data.to_excel('第十二届大学生数学竞赛考试安排6.xlsx',sheet_name='专业组',index=False)
在一个工作表中追加一行数据
import xlwings as xw
app = xw.App(visible=False,add_book=False)
new_data = [['1440','吴**','20001102940' ,'男','**大学','2001级','***班','数学与应用数学','专业组','7*01','70'
],['1441','刘**','2001030121','女','**大学','2001级','***班','数学与应用数学','专业组','7*02','71']]
workbook = app.books.open('D:\python自动化office\第十二届大学生数学竞赛考试安排.xlsx')
worksheet = workbook.sheets['专业组']
data = worksheet.range('A1').expand('table')
num = data.shape[0]
worksheet.range(num + 1,1).value = new_data
workbook.save()
workbook.close()
app.quit()
在多个工作簿的同名工作表中追加行数据
from pathlib import Path
import xlwings as xw
app = xw.App(visible=False,add_book=False)
folder_path = Path('D:\python自动化office')
file_list = folder_path.glob('*.xlsx')
new_data = [['1440','吴**','20001102940' ,'男','**大学','2001级','***班','数学与应用数学','专业组','7*01','70'
],['1441','刘**','2001030121','女','**大学','2001级','***班','数学与应用数学','专业组','7*02','71']]
for i in file_list:
workbook = app.books.open(i)
worksheet = workbook.sheets['专业组']
data = worksheet.range('A1').expand('table')
num = data.shape[0]
worksheet.range(num + 1,1).value = new_data
workbook.save()
workbook.close()
app.quit()
在一个工作表中追加一列数据(如分等级“优”,“良”,“差”)
- 如下页图所示为工作簿“销售表.xlsx”中的产品销售数据。现在需要根据利润为每一行数据划分等级:大于10000的标为“优”,大于5000且小于等于10000的标为“良”,小于等于5000的标为“差”。将等级标签写入“利润”列右侧的列中。
import pandas as pd
data = pd.read_excel('D:\python自动化office\销售表.xlsx',sheet_name=0)
max_data = data['利润'].max()
level = [0,5000,10000,max_data]
level_names = ['差','良','优']
data['等级'] = pd.cut(data['利润'],level,labels=level_names)
data.to_excel('销售表1.xlsx',sheet_name='总表',index=False)
提取一个工作表的行数据和列数据
import pandas as pd
data = pd.read_excel('D:\python自动化office\销售表.xlsx',sheet_name='总表')
row_data = data.iloc[0:10]
col_data = data[['单号','销售日期','产品名称','利润']]
range_data = data.iloc[0:5][['单号','销售日期','产品名称','利润']]
row_data.to_excel('提取行数据.xlsx',sheet_name='利润表',index=False)
col_data.to_excel('提取列数据.xlsx',sheet_name='利润表',index=False)
range_data.to_excel('提取数据.xlsx',sheet_name='Sheet1',index=False)
提取一个工作簿中所有工作表的行数据
import pandas as pd
data = pd.read_excel('D:\python自动化office\销售表.xlsx',sheet_name=None)
workbook = pd.ExcelWriter('提取表.xlsx')
for i,j in data.items():
row_data = j.iloc[0:5]
row_data.to_excel(workbook,sheet_name=i,index=False)
workbook.save()
- 如果要提取各个工作表的列数据,则将第5行代码修改为
col_data = data[['单号','销售日期','产品名称','利润']]
- 并将第6行代码中的row_data修改为col_data。(提取列数据未成功)
替换一个工作表的数据
- 在Excel中,可使用查找和替换功能批量修改数据,本案例则要通过Python编程达到相同的目的。如下图所示为工作簿“销售表.xlsx”的工作表“总表”中的数据,现要将其中所有的“离合器”替换为“刹车片”。
import pandas as pd
data = pd.read_excel('D:\python自动化office\销售表.xlsx',sheet_name=0)
data = data.replace('离合器','刹车片')
data.to_excel('销售表1.xlsx',sheet_name='总表',index=False)
- 第3行代码中的replace()是pandas模块中的函数,该函数不仅可以进行全表替换,而且可以在指定的列或行中进行替换。例如,在“产品名称”列中进行替换的代码如下:
data['产品名称'] = data['产品名称'].replace('离合器','刹车片')
- 需要注意的是,本案例的代码中使用replace()函数的方式只能完成精确的查找和替换。也就是说,单元格中的值必须为“离合器”才能被替换成“刹车片”,而“电磁离合器”或“摩擦离合器”则不会被替换为“电磁刹车片”或“摩擦刹车片”。如果要对值的一部分进行查找和替换,可将replace()函数的参数regex设置为True,例如:
data = data.replace('离合','制动',regex=True)
替换一个工作簿中所有工作表的数据
- 本案例要在上一个案例的基础上实现在一个工作簿中批量查找和替换所有工作表中的数据。
import pandas as pd
data = pd.read_excel('D:\python自动化office\销售表.xlsx',sheet_name=None)
workbook = pd.ExcelWriter('销售表1.xlsx')
for i,j in data.items():
data = j.replace('离合器','刹车片')
data.to_excel(workbook,sheet_name=i,index=False)
workbook.save()
替换一个工作表的列数据
- 在下图所示为工作簿“销售表.xlsx”的工作表“总表”中的数据,本案例要通过编写python代码将该工作表中“销售价”列的数据增加10%。
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\销售表.xlsx')
worksheet = workbook.sheets['总表']
data = worksheet.range('A2').expand('table').value
for i,j in enumerate(data):
data[i][4] = float(j[4])*(1+0.1)
worksheet.range('A2').expand('table').value = data
workbook.save()
workbook.close()
app.quit()
替换一个工作表指定列数据对应的列数据
- 如下图所示为工作簿“销售表.xlsx”中工作表“总表”的数据,现在需要将里程表的成本价由850更新为900。此时不能使用案例084中介绍的方法直接进行统一替换,因为还有其他产品,如组合表的成本价也是850(为便于读者查看,这里将成本价相同的不同产品的单元格填充了颜色)。要正确地更新里程表的成本价,需要在替换数据前使用if语句判断产品是否为里程表以及其成本价是否为850。
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\销售表.xlsx')
worksheet = workbook.sheets['总表']
data = worksheet.range('A1').expand('table').value
for i,j in enumerate(data):
if (j[2]=='里程表') and (j[3]==850):
data[i][3] = 900
worksheet.range('A1').expand('table').value = data
workbook.save()
workbook.close()
app.quit()
运行结果
88 转置一个工作表的行列
import xlwings as xw
app = xw.App(visible=False,add_book=False)
workbook = app.books.open('D:\python自动化office\第十二届大学生数学竞赛考试安排3.xlsx')
worksheet = workbook.sheets[1]
data = worksheet.range('A1').expand('table').options(transpose=True).value
worksheet.clear()
worksheet.range('A1').expand().value = data
workbook.save('案例1')
workbook.close()
app.quit()
89 从指定行列冻结一个工作表的窗格
- 在Excel中查看比较复杂的大型表格时,常常需要使用“冻结窗格”工具固定显示标题行或标题列,以方便浏览数据。本案例则要通过Python编程实现相同的冻结窗格效果。
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\销售表.xlsx')
worksheet = workbook['总表']
worksheet.freeze_panes = 'B2'
workbook.save('销售表1.xlsx')
- 第4行代码中的freeze_panes是openpyxl模块中工作表对象的属性,用于冻结窗格。如果将“B2”修改为“B1”,表示冻结工作表的首列;如果修改为“A2”,则表示冻结工作表的首行。如果要取消冻结窗格,则将第4行代码修改为“worksheet.freeze_panes=‘A1’”或“worksheet.freeze_panes=None”。
90 将一个工作表的一列拆分为多列
- 如右图所示,工作簿“产品规格表.xlsx”中“产品规格”列的数字都是用“*”号分隔开的。使用Excel的分列功能可将该列拆分成3列。本案例则要通过Python编程来完成拆分。
import pandas as pd
data = pd.read_excel('D:\python自动化office\产品规格表.xlsx',sheet_name=0)
data_col = data['产品规格'].str.split('*',expand=True)
data['长(cm)'] = data_col[0]
data['宽(cm)'] = data_col[1]
data['高(cm)'] = data_col[2]
data.drop(columns=['产品规格'],inplace=True)
data.to_excel('产品规格表1.xlsx',sheet_name='规格表',index=False)
- 第3行代码中的split()是pandas模块中Series对象的一个字符串函数,用于根据指定的分隔符拆分字符串。该函数的第1个参数用于指定分隔符,如果省略,则以空格作为分隔符。参数expand用于指定拆分结果的格式:如果为True,则拆分结果为DataFrame;如果为False,则拆分结果为Series。
91将一个工作表的多列合并为一列
- 本案例要通过Python编程实现案例090的逆向操作:将一个工作表中的多列数据合并为一列。
import pandas as pd
data = pd.read_excel('D:\python自动化office\产品规格表1.xlsx',sheet_name='规格表')
data['产品规格'] = data['长(cm)'].astype(str)+'*'+data['宽(cm)'].astype(str)+'*'+data['高(cm)'].astype(str)
data.drop(columns=['长(cm)','宽(cm)','高(cm)'],inplace=True)
data.to_excel('产品规格表2.xlsx',sheet_name='Sheet1',index=False)
92在一个工作表中隐藏行数据
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\销售表.xlsx')
worksheet = workbook['总表']
worksheet.row_dimensions.group(2,10,hidden=True)
workbook.save('销售表附表.xlsx')
93 在一个工作表中隐藏列数据
from openpyxl import load_workbook
workbook = load_workbook('D:\python自动化office\销售表.xlsx')
worksheet = workbook['总表']
worksheet.column_dimensions.group('A','D',hidden=True)
workbook.save('销售表副表.xlsx')