Python批量处理行、列和单元格

案例01 精确调整多个工作簿的行高和列宽——销售表

import os  # 导入os模块
import xlwings as xw # 导入xlwings模块
file_path='e:\\table\\销售表' # 给出工作簿所在的文件夹路径
file_list = os.listdir(file_path) # 列出文件夹下所有文件和子文件的名称
app = xw.App(visible = False, add_book = False) # 启动Excel程序
for i in file_list: # 遍历文件夹路径下的所有文件名
    if i.startswith('~$'):  # 判断文件是否有文件名以“~$”开头的文件
        continue   # 如果有,则跳过这种类型的文件
    file_paths = os.path.join(file_path, i) # 将文件夹路径和文件名拼接成工作簿的完整路径
    workbook = app.books.open(file_paths) # 打开要调整行高和列宽的工作簿
    for j in workbook.sheets:  # 遍历当前工作簿中的工作表
        value = j.range('A1').expand('table') # 在工作表中选择要调整行高和列宽的单元格区域
        value.column_width = 12   # 将列宽调整为可容纳12个字符的宽度
        value.row_height = 20    # 将行高调整为20磅
    workbook.save()   # 保持当前工作簿
    workbook.close()  # 关闭当前工作簿
app.quit()      # 退出Excel程序

 知识延伸

  1. column_width是xlwings模块中用于获取和设置列宽的属性。列宽的单位是字符数,取值范围是0-255。这里的字符指的是英文字符,如果字符的字体是比例字体(每个字符的宽度不同),则以字符0的宽度为准。在用该属性获取列宽时,如果所选单元格区域中各列的列宽不同,则根据所选单元格区域位于包含数据单元区域的内部或外部分别返回None或第一列的列宽。
  2. row_height是xlwings模块中用于获取和设置行高的属性。行高的单位是磅,取值范围是0-409.5。在用该属性获取行高时,如果所选单元格区域中各列的行高不同,则根据所选单元格区域位于包含数据单元格区域的内部或外部分别返回None或第一行的行高。

精确调整一个工作簿中所有工作表的行高与列宽 ——采购表.xlsx

import xlwings as xw
app = xw.App(visible = False, add_book = False)
workbook = app.books.open('e:\\table\\采购表.xlsx')
for i in workbook.sheets:
    value = i.range('A1').expand('table')
    value.column_width = 12
    value.row_height = 20
workbook.save()
app.quit()

案例02 批量更改多个工作簿的数据格式——采购表(文件夹)

import os
import xlwings as xw
file_path = '采购表'  # 给出工作簿所在的文件夹路径
file_list = os.listdir(file_path)  # 列出文件夹下所有文件和子文件夹的名称
app = xw.App(visible = False, add_book = False) # 启动Excel程序
for i in file_list:  # 遍历文件夹路径下的所有文件名
    if i.startswith('~$'):  # 判断是否有文件名以“~$”开头的文件
        continue  # 如果有,则跳过这种类型的文件
    file_paths = os.path.join(file_path, i)  # 将文件夹路径和文件名拼接成工作簿的完整路径
    workbook = app.books.open(file_paths)  # 打开要设置的数据格式的工作簿
    for j in workbook.sheets:   # 遍历当前工作簿中的工作表
        row_num = j['A1'].current_region.last_cell.row  # 获取工作表中数据区域最后一行的行号
        j['A2:A{}'.format(row_num)].number_format = 'm/d' # 将A列的“采购日期”数据全部更改为“月/日”格式
        j['D2:D{}'.format(row_num)].number_format = '¥#,##0.00'  # 将D列的“采购金额”数据全部更改为带货币符号和两位小数的格式
    workbook.save()
    workbook.close()
app.quit()

知识延伸

1、format()函数用来拼接代表单元格区域的字符串。

例如:‘A2:A{}'.format(row_num),假设当前工作表中数据区域最后一行的行号row_num为16,则 ‘A2:A{}'.format(row_num)就相当于’A2:A16‘,代表单元格区域A2:A16。

2、拼接出单元格区域后,就可以使用xlwings模块中的number_format属性来设置单元格区域中的数据格式。该属性的取值为一个代表特定格式的字符串,与Excel的“设置单元格格式”对话框中“数字”选项卡下设置的格式对应。

批量更改多个工作簿的外观格式——销售表(文件夹)

import os
import xlwings as xw
file_path = '销售表'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    for j in workbook.sheets: 
        j['A1:H1'].api.Font.Name = '宋体'  # 设置工作表标题行的字体为“宋体”
        j['A1:H1'].api.Font.Size = 10  # 设置工作表标题行的字号为“10”磅
        j['A1:H1'].api.Font.Bold = True		# 加粗工作表标题行
        j['A1:H1'].api.Font.Color = xw.utils.rgb_to_int((255,255,255))   # 设置工作表标题行的字体颜色为“白色”
        j['A1:H1'].color = xw.utils.rgb_to_int((0,0,0))  # 设置工作表标题行的单元格填充颜色为“黑色”
        j['A1:H1'].api.HorizontalAlignment = xw.constants.HAlign.xlHAlignCenter  # 设置工作表标题行的水平对齐方式为“居中”
        j['A1:H1'].api.VerticalAlignment = xw.constants.VAlign.xlVAlignCenter  # 设置工作表标题行的垂直对齐方式为“居中”
        j['A2'].expand('table').api.Font.Name = '宋体'   # 设置工作表的正文字体为“宋体”
        j['A2'].expand('table').api.Font.Size = 10    # 设置工作表的正文字号为“10”磅
        j['A2'].expand('table').api.HorizontalAlignment = xw.constants.HAlign.xlHAlignLeft # 设置工作表正文的水平对齐方式为“靠左”
        j['A2'].expand('table').api.VerticalAlignment = xw.constants.VAlign.xlVAlignCenter   # 设置工作表正文的垂直对齐方式为“居中”
        for cell in j['A1'].expand('table'):  # 从单元格A1开始为工作表添加合适粗细的边框
            for b in range(7, 11): 
                cell.api.Borders(b).LineStyle = 1  # 设置单元格的边框线型
                cell.api.Borders(b).Weight = 2   # 设置单元格的边框粗细
    workbook.save()
    workbook.close()
app.quit()

案例03 批量替换多个工作簿的行数据——分部信息(文件夹)

import os
import xlwings as xw
file_path = '分部信息' # 要批量处理的工作簿所在的文件夹路径
file_list = os.listdir(file_path) # 列出文件夹下所有文件和子文件夹的名称
app = xw.App(visible = False, add_book = False) # 启动Excel程序
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i) # 将文件夹路径和文件名拼接成工作簿的完整路径
    workbook = app.books.open(file_paths) # 打开要处理的工作簿
    for j in workbook.sheets:  # 遍历工作簿中的工作表
        value = j['A2'].expand('table').value  # 读取工作表数据
        for index, val in enumerate(value):   # 按行遍历工作表数据
            if val == ['背包', 16, 65]:   # 判断行数据是否为“背包”、16、65
                value[index] = ['双肩包', 36, 79]  # 如果是,则将该行数据替换为新的数据
        j['A2'].expand('table').value = value   # 将完成替换的数据写入工作表
    workbook.save()
    workbook.close()
app.quit()

知识延伸

1、enumerate()是python的内置函数,用于将一个可遍历的数据对象(如列表、元组或字符串等)组合为一个索引序列,可以同时得到数据对象的索引及对应的值,一般用在for语句当中。

该函数的语法格式和常用参数

enumerate(sequence,[start=0])

参数:

sequence :可遍历的数据对象,可以是列表、元组或字符串等

start:索引的起始位置,若省略,则默认为0。

批量替换多个工作簿中的单元格数据——分部信息(文件夹) 

import os
import xlwings as xw
file_path = '分部信息'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    for j in workbook.sheets: 
        value = j['A2'].expand('table').value # 读取工作表数据
        for index, val in enumerate(value):  # 按行遍历工作表数据
            if val[0] == '背包':  # 判断当前行第1个单元格的数据是否为“背包”
                val[0] = '双肩包'  # 将第一个单元格的数据修改为“双肩包”
                value[index] = val  # 替换整行数据
        j['A2'].expand('table').value = value  # 将完成替换的数据写入工作表
    workbook.save()
    workbook.close()
app.quit()

批量修改多个工作簿中指定工作表的列数据——分部信息(文件夹) 

import os
import xlwings as xw
file_path = '分部信息'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    worksheet = workbook.sheets['产品分类表'] # 指定要修改的工作表
    value = worksheet['A2'].expand('table').value 
    for index, val in enumerate(value): 
        val[2] = val[2] * (1 + 0.05) # 修改第3个单元格的数据,这里就是指将销售价上调5%
        value[index] = val # 替换整行数据
    worksheet['A2'].expand('table').value = value # 将完成替换的数据写入工作表
    workbook.save()
    workbook.close()
app.quit()

案例04 批量提取一个工作簿中所有工作表的特定数据——采购表.xlsx

import xlwings as xw
import pandas as pd
app = xw.App(visible = False, add_book = False) 
workbook = app.books.open('采购表.xlsx')  
worksheet = workbook.sheets # 列出工作簿中的所有工作表
data = [] # 创建一个空列表用于存放数据
for i in worksheet: # 遍历工作簿中的工作表
    values = i.range('A1').expand().options(pd.DataFrame).value # 读取当前工作表的所有数据
    filtered = values[values['采购物品'] == '复印纸'] # 提取“采购物品”为“复印纸”的行数据
    if not filtered.empty:  # 判断提取出的行数据是否为空
        data.append(filtered) # 将提取出的行数据追加到列表中
new_workbook = app.books.add() # 新建工作簿
new_worksheet = new_workbook.sheets.add('复印纸')  # 在新工作簿中新增一个名为“复印纸”的工作表
new_worksheet.range('A1').value = pd.concat(data, ignore_index = False) # 将提取出的行数据写入工作表“复印纸”中
new_workbook.save('复印纸.xlsx') # 保持新工作簿并命名为“复印纸.xlsx”
workbook.close()
app.quit()

 知识延伸

1、concat()是pandas模块中的函数,可将数据根据不同的轴进行简单的拼接

concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False,copy=True)

参数 说明
objs 要拼接的数据对象
axis 拼接时所依据的轴。如果为0,则沿着行拼接;如果为1,则沿着列拼接
join 拼接的方式,默认为“outer”
join_axes index对象列表
ignore_index 默认为False。如果为True,则忽略原有索引,并生成新的数字序列作为索引
keys 序列,默认值为空。使用传递的键作为最外层构建层次索引。如果为多索引,因使用元组
levels 序列列表,默认值为空。结果层次索引中的级别的名称
names 列表,默认值为空。结果层次索引中的级别的名称
verify_integrity 默认值为False。用于检查新拼接的轴是否包含重复项
copy 默认值为True。如果为False,则不执行非必要的数据复制

批量提取一个工作簿中所有工作表的列数据——采购表.xlsx 

import xlwings as xw
import pandas as pd
app = xw.App(visible = False, add_book = False) 
workbook = app.books.open('采购表.xlsx')
worksheet = workbook.sheets 
column = ['采购日期', '采购金额'] # 指定要提取的列的列标题
data = []
for i in worksheet:
    values = i.range('A1').expand().options(pd.DataFrame, index = False).value
    filtered = values[column]  # 根据前面指定的列标题提取数据
    data.append(filtered)
new_workbook = app.books.add()  
new_worksheet = new_workbook.sheets.add('提取数据') 
new_worksheet.range('A1').value = pd.concat(data, ignore_index = False).set_index(column[0])
new_workbook.save('提取表.xlsx') 
workbook.close()
app.quit()

在多个工作簿的指定工作表中批量追加行数据——分部信息(文件夹) 

import os
import xlwings as xw
newContent = [['双肩包', '64', '110'], ['腰包', '23', '58']] # 给出要追加的行数据
app = xw.apps.add()
file_path = '分部信息'  
file_list = os.listdir(file_path)  
for i in file_list:  
    if os.path.splitext(i)[1] == '.xlsx':  
        workbook = app.books.open(file_path + '\\' + i)  
        worksheet = workbook.sheets['产品分类表'] # 指定要追加行数据的工作表
        values = worksheet.range('A1').expand()  # 读取原有数据
        number = values.shape[0]  # 获取原有数据的行数
        worksheet.range(number + 1, 1).value = newContent  # 将前面指定的行数据追加到原有数据的下方
        workbook.save()
        workbook.close()
app.quit()

案例05 对多个工作簿中指定工作表的数据进行分列——产品记录表(文件夹)

import os
import xlwings as xw
import pandas as pd
file_path = '产品记录表'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    worksheet = workbook.sheets['规格表']  # 指定要处理的工作表
    values = worksheet.range('A1').options(pd.DataFrame, header = 1, index = False, expand = 'table').value # 读取指定工作表中的数据
    new_values = values['规格'].str.split('*', expand = True)  # 根据“*”号拆分“规格”列
    values['长(mm)'] = new_values[0] # 将拆分出的第1部分数据添加到标题为“长(mm)”的列中
    values['宽(mm)'] = new_values[1] # 将拆分出的第2部分数据添加到标题为“宽(mm)”的列中
    values['高(mm)'] = new_values[2] # 将拆分出的第3部分数据添加到标题为“高(mm)”的列中
    values.drop(columns =['规格'], inplace = True)  # 删除“规格”列
    worksheet['A1'].options(index = False).value = values # 用分列后的数据替换工作表中的原有数据
    worksheet.autofit() # 根据数据内容自动调整工作表的行高和列宽
    workbook.save()
    workbook.close()
app.quit()

知识延伸

1、split()是pandas模块中Series对象的一个字符串函数,用于根据指定的分隔符拆分字符串。

语法格式

Series.str.split(pat=None,n=-1,expand=False)

参数:

pat=None,指定分隔符,如果省略,则以空格作为分隔符

n=-1,指定拆分的次数:如果为1,则只在第1个分隔符处进行拆分;如果为2,则只在第1个和第二个分隔符处进行拆分;以此类推。如果省略或者为0或-1,则在所有分隔符处进行拆分

expand=False,指定拆分结果的格式:如果为True,则为DataFrame;如果为False,则为Series。

2、drop()是pandas模块中DataFrame对象的函数,用于删除DataFrame对象的某一行或某一列。

语法格式

DataFrame.drop(labels=None,axis=0,index=None,columns=None,inplace=False)

参数 说明
labels 要删除的行、列的名称
axis 默认为0,表示删除列;如果为1,则表示删除行
index 指定要删除的行
columns 指定要删除的列
inplace 默认为False,表示该删除操作不改变原DataFrame,而是返回一个执行删除操作后的新DataFrame。如果为True,则会直接在原DataFrame上进行删除,删除后无法恢复原有数据

批量合并多个工作簿中指定工作表的列数据——产品记录表(文件夹) 

import os
import xlwings as xw
import pandas as pd
file_path = '产品记录表'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    worksheet = workbook.sheets['规格表'] 
    values = worksheet.range('A1').options(pd.DataFrame, header = 1, index = False, expand = 'table').value 
    values['规格'] =  values['长(mm)'].astype('str') + '*' + values['宽(mm)'].astype('str') + '*' + values['高(mm)'].astype('str') 
    values.drop(columns = ['长(mm)'], inplace = True) # 删除标题为“长(mm)”的列
    values.drop(columns = ['宽(mm)'], inplace = True) # 删除标题为“宽(mm)”的列
    values.drop(columns = ['高(mm)'], inplace = True) # 删除标题为“高(mm)”的列
    worksheet.clear() # 清除工作表“规格表”中原有的数据
    worksheet['A1'].options(index = False).value = values # 将处理好的数据写入工作表
    worksheet.autofit() 
    workbook.save()
    workbook.close()
app.quit()

将多个工作簿中指定工作表的列数据拆分为多行——产品记录表(文件夹) 

import os
import xlwings as xw
import pandas as pd
file_path = '产品记录表'
file_list = os.listdir(file_path)
app = xw.App(visible = False, add_book = False)
for i in file_list:
    if i.startswith('~$'):
        continue
    file_paths = os.path.join(file_path, i)
    workbook = app.books.open(file_paths)
    worksheet = workbook.sheets['规格表'] 
    values = worksheet.range('A1').options(pd.DataFrame, header = 1, index = False, expand = 'table').value 
    new_values = values['规格'].str.split('*', expand=True) 
    values['长(mm)'] = new_values[0] 
    values['宽(mm)'] = new_values[1] 
    values['高(mm)'] = new_values[2] 
    values.drop(columns =['规格'], inplace = True) 
    values = values.T # 转置数据的行列
    values.columns = values.iloc[0] 
    values.index.name = values.iloc[0].index.name 
    values.drop(values.iloc[0].index.name, inplace = True) 
    worksheet.clear()
    worksheet['A1'].value = values 
    worksheet.autofit() 
    workbook.save() 
    workbook.close() 
app.quit()

案例06 批量提取一个工作簿中所有工作表的唯一值——上半年销售统计表.xlsx

import xlwings as xw
app = xw.App(visible = True, add_book = False)
workbook = app.books.open('上半年销售统计表.xlsx') # 打开指定工作簿
data = [] # 创建一个空列表用于存放书名数据
for i,worksheet in enumerate(workbook.sheets): # 遍历工作簿中的工作表
    values = worksheet['A2'].expand('down').value # 提取当前工作表中的书名数据
    data = data + values  # 将提取中的书名数据添加到前面创建的列表中
data = list(set(data)) # 对列表中的书名数据进行去重操作
data.insert(0, '书名') # 在去重后的书名数据前添加列标题“书名”
new_workbook = app.books.add() # 新建工作簿
new_worksheet = new_workbook.sheets.add('书名') # 在新工作簿中新增一个名为“书名”的工作表
new_worksheet['A1'].options(transpose = True).value = data # 将处理好的书名数据写入新工作表
new_worksheet.autofit() # 根据数据内容自动调整新工作表的行高和列宽
new_workbook.save('书名.xlsx') # 保存新工作簿并命名为“书名.xlsx”
workbook.close()
app.quit()

知识延伸

1、set()函数原本的功能是将其他类型的序列对象(如列表)转换为集合,因为集合中不允许出现重复元素,转换过程中重复元素便会被自动去除,所以该函数也常用于数据的去重。

2、insert()是Python中列表对象的函数,用于在列表的指定位置插入元素。

语法格式:

insert(index,obj)

参数:

index:要插入元素的位置

obj:要插入的元素

批量提取一个工作簿中所有工作表的唯一值并汇总——上半年销售统计表.xlsx 

import os
import xlwings as xw
app = xw.App(visible = True, add_book = False)
wb = app.books.open('上半年销售统计表.xlsx')
data = list() # 创建一个空列表用于存放书名和销量的明细数据
for i,sht in enumerate(wb.sheets):
    values = sht['A2'].expand('table').value
    data = data + values
sales = dict() # 创建一个空字典用于存放书名和销量的汇总数据
for i in range(len(data)): # 按行遍历书名和销量的明细数据
    name = data[i][0] # 获取当前书名
    sale = data[i][1] # 获取当前销量
    if name not in sales: # 判断字典中是否不存在当前书名
        sales[name] = sale # 如果不存在,则在字典中添加此书名的销量记录
    else:
        sales[name] += sale # 如果已存在,则计算此书名的累计销量
dictlist = list()
for key, value in sales.items():
    temp = [key, value] # 列出书名与对应的累计销量
    dictlist.append(temp)
dictlist.insert(0, ['书名', '销量']) # 在获取的数据前添加列标题“书名”和“销量”
new_workbook = app.books.add()
new_worksheet = new_workbook.sheets.add('销售统计')
new_worksheet['A1'].value = dictlist
new_worksheet.autofit()
new_workbook.save('销售统计.xlsx')
wb.close()
app.quit()

Python批量处理行、列和单元格,这些案例中使用到的数据文件请点击这里(1条消息) 【免费】Python批量处理行、列和单元格使用到的数据.zip资源-CSDN文库

你可能感兴趣的:(Python操控Excel,python)