目录
一、题目描述
将两个工作簿合并为一个工作簿
二、分析
1、思路
分别将工作簿中的数据拿出来,然后写到一个工作簿中
2、实现
①创建工作簿对象
all_wb = openpyxl.Workbook()
②创建工作表对象
all_ws = all_wb.active
all_ws.title = '小保健药房汇总数据'
③ 写入表头
写入的只能是元组或者列表
all_ws.append(['购药时间', '社保卡号', '商品编码', '商品名称', '销售数量', '应收金额', '实收金额'])
④ 写入数据
首先获取要取出数据的工作簿对象,然后获取对应的表,然后从中拿数据,拿数据的具体原理可在之前的文章——合并单元格中看;
此处的一个新知识点是用到了生成器;
ws存储的是工作表对象,对象中存储的是多个元祖,元组中保存的是每一行的每一列对应的对象的地址;
因为表开始的行为第三行而不是第一行,所以需要用到生成器去从第三行开始取元组,然后再从元组中去遍历每一列的地址,再通过value方法去得到其值,再将得到的值写到新的工作表中;
此处有一个坑,就是工作表中有空白的数据,如果不进行处理,则合并之后的工作簿的工作表会出现断层的现象,所以此处有一个判断其是否为空,用一个标识符即可,还可以判断行的第一列是否为空,思路一样只是实现稍有不同
row_index = 2
names = ('高新', '犀浦', '新津')
for name in names:
wb = openpyxl.load_workbook(f'小宝剑大药房({name}店)2018年销售数据.xlsx')#打开工作簿对象
ws = wb.worksheets[0]#获取工作表对象
# flag = True
for row in ws.iter_rows(min_row=3):
if row[0].value == None:
break
for index, cell in enumerate(row):
# if cell.value is None:
# flag = False
# break
all_ws.cell(row_index, index + 1, cell.value)
# if not flag:
# break
row_index += 1
⑤保存到工作簿
之前是将数据保存到工作表中,那为什么就保存到对应的工作簿中呢,原因就在于最开始生成工作表对象的时候是在工作簿对象的前提下生成的
此题一共有四个对象,第一个是自己生成的工作簿对象,当做要保存的工作簿对象;第二个对象是生成的工作表对象(在生成的工作簿的前提下),用来存储数据的工作表;第三个对象是获取的文件的工作簿对象;第四个是在获取的工作簿的前提下获取的工作表对象,用于将数据提取出来;
三、第二种方法
思路其实是一样的,区别①在于获取工作表存储的元组的内容上,上一种方法用的是生成器,而这种方法是通过列的名称的方式,即每次从A列到G列,而最开始的数字3代表的是初始行号,然后一直往下到没有表对象(此时也会出现空值的情况),存储得到的结果是一个元组
区别②添加的方式:上一种是通过逐依的遍历,一个值一个值的写入(通过对应的行列的序号写入),此方法是遍历之前存储的元组,得到每一行的元组,然后再遍历元组得到对象地址,在获得其值,存储到列表中,再将每一行的列表存入的一个大列表中,得到一个二维列表,最后再遍历二维列表,将其以添加表头的方式添加到工作表中
四、源码
1、第一种方法
from tkinter import N
from matplotlib.pyplot import flag
import openpyxl
all_wb = openpyxl.Workbook()
all_ws = all_wb.active
all_ws.title = '小保健药房汇总数据'
# print(all_ws)
all_ws.append(['购药时间', '社保卡号', '商品编码', '商品名称', '销售数量', '应收金额', '实收金额'])
row_index = 2
names = ('高新', '犀浦', '新津')
for name in names:
wb = openpyxl.load_workbook(f'小宝剑大药房({name}店)2018年销售数据.xlsx')
ws = wb.worksheets[0]
flag = True
for row in ws.iter_rows(min_row=3):
for index, cell in enumerate(row):
if cell.value is None:
flag = False
break
all_ws.cell(row_index, index + 1, cell.value)
if not flag:
break
row_index += 1
all_wb.save('小保健药房汇总数据.xlsx')
2、 第二种方法
import openpyxl
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
res_wb = openpyxl.Workbook()
res_ws = res_wb.active
res_ws.title = '汇总数据'
res_ws.append(('小保健大药房2022全国销售数据', ))
# 设置单元格的样式
cell = res_ws['A1']
cell.font = Font(size=20, bold=True, color="0000ff", name="微软雅黑")
cell.alignment = Alignment(horizontal='center', vertical='center')
cell.fill = PatternFill(fill_type='solid', fgColor="00ff00")
# 合并单元格
res_ws.merge_cells('A1:G1')
res_ws.append(['购药时间', '社保卡号', '商品编码', '商品名称', '销售数量', '应收金额', '实收金额'])
names = ('高新', '犀浦', '新津')
for name in names:
wb = openpyxl.load_workbook(f'小宝剑大药房({name}店)2018年销售数据.xlsx')
sheet = wb.worksheets[0]
rows = sheet[f'A3:G{sheet.max_row}']
print(rows)
data = []
for row in rows:
if row[0].value is not None:
res = []
for cell in row:
res.append(cell.value)
data.append(res)
# data = [[cell.value for cell in row] for row in rows if row[0].value]
for content in data:
#类似于写表头的方式,传入一个列表
res_ws.append(content)
res_wb.save('小保健药房汇总数据20220512.xlsx')
五、效果图
1、原表
2、合并后的表
①方法一
②方法二