一、openpyxl读取Excel
book = load_workbook(filename='副本题.xlsx')
sheet = book['Sheet1']
二、用字典存储分类汇总的结果
以上代码是对sheet的第一列进行分类,对三四列的乘积进行汇总
dict = {}
# 从第二行开始遍历
for row in range(2, sheet.max_row + 1):
# 数据下方有空格,故加上对要计算汇总的2列是否为None的判断
if sheet.cell(row, 3).value and sheet.cell(row, 4).value:
supplier_amount = sheet.cell(row, 3).value * sheet.cell(row, 4).value
# dict.get()第2个参数为值不存在时的返回值
dict[sheet.cell(row, 1).value] = dict.get(sheet.cell(row, 1).value, 0) + supplier_amount
三、将结果写入sheet
相比pandas,选择openpyxl,处理数据的时候有很多便捷的方法和函数不能用。诸如:
# 直接对一整列进行计算操作
df['新列名'] = df["列1"] * df["列2"]
# 分列汇总
radio = df.groupby('分类依据')['汇总项'].sum()
# 日期转换方法
df1['日期新'] = pd.to_datetime(df['日期'], format='%Y%m%d')
但它也有优点,那就是写入的时候,可以直接对单元格进行操作,比较自由。
pandas的写入格式则较难调整。(比如,我想在表格第一行自行加入内容,从第2行开始是列名,用了行拼接没成功;
# 列表转为DataFrame
df1 = pd.DataFrame([['总金额', total]])
# 字典转为DataFrame,ratio是df分类汇总的结果
df2 = pd.DataFrame({
'列名一': ratio.index,
'列名二': ratio.values
})
combined_df = pd.concat([df1, df2], axis=0, ignore_index=True)
用了在数据前插入一行、更改索引值的方法,也未成功。第一行还是列名,只能插在第2行。
# DataFrame插入一行数据
df2.loc[-1] = ["总金额", total]
df2.index += 1
df = df2.sort_index()
进入正题,用openpyxl写入Excel。
# 创建一个Excel workbook 对象
book = openpyxl.Workbook()
# 创建时,会自动产生一个sheet,通过active获取
sheetc = book.active
sheetc.title = '字典分类汇总结果'
sheetc['A1'] = "第一列列名"
sheetc['B1'] = "第二列列名"
1.将字典写入sheet
# 遍历字典的键值对,从第2行开始逐行写入
r = 1
for k, v in dict.items():
r += 1
sheetc[f"A{r}"] = k
sheetc[f"B{r}"] = v
2.如果想对结果排序,可先将字典转为列表。
# 字典无序
list = list(dict.items())
# 根据list每个元素的第2个值降序排列
list.sort(key=lambda x: x[1], reverse=True)
再将列表写入sheet
# 将列表写入sheet
r = 1
for x in list:
r += 1
sheetc[f"A{r}"] = x[0]
sheetc[f"B{r}"] = x[1]
四、根据条件筛选并写入整行
# 首先开发一个函数,获取 指定行 里面的数据
# rowx 为行号; start_colx,end_colx 分别为起止列号
# next() 内置函数,用于获取迭代器对象中的下一个元素
def row_values(sheet, rowx, start_colx=None, end_colx=None):
return next(sheet.iter_rows(
min_row=rowx, max_row=rowx,
min_col=start_colx, max_col=end_colx,
values_only=True))
# over_row :新表的行号
over_row = 1
# 把第一行(row==1放or前不会报错)和满足条件的行输入
for row in range(1, sheet.max_row + 1):
if row == 1 or (sheet.cell(row, 5).value is not None & sheet.cell(row,5).value < 100):
for i, v in enumerate(row_values(sheet, row)):
sh1.cell(over_row, i + 1).value = v
over_row += 1
如果这里也想排序,可先将迭代器的内容存入列表,再将列表存入sheet。
五、最后,保存文件。
如果文件名已存在,会覆盖内容。
book.save('结果文件.xlsx')