大家好,我们经常会有这样的需求。比如下图
我们需要把同一个省份的合并起来,如下图的效果
如何实现呢,这是原有的df
直观的操作是这样的:
1
2
3
4
5
6
7
8
9
10
11
|
df.to_excel( 'test.xlsx' ,index = false) from openpyxl import load_workbook wb = load_workbook( 'test.xlsx' ) ws = wb.active() ws.merge_cells(start_row = 2 ,end_row = 8 ,start_column = 1 ,end_column = 1 ) ws.merge_cells(start_row = 2 ,end_row = 8 ,start_column = 2 ,end_column = 2 ) ws.merge_cells(start_row = 9 ,end_row = 14 ,start_column = 1 ,end_column = 1 ) ws.merge_cells(start_row = 9 ,end_row = 14 ,start_column = 2 ,end_column = 2 ) ws.merge_cells(start_row = 15 ,end_row = 18 ,start_column = 1 ,end_column = 1 ) ws.merge_cells(start_row = 15 ,end_row = 18 ,start_column = 2 ,end_column = 2 ) wb.save() |
只是问题在于我们不能总是人工判断start_row和end_row,如何能使程序自动获取row的起始点呢?其实我们使用一个groupby就发现了方法了!大家看到了吗?
真是柳暗花明又一村啊,完整解决方案已经有了,我封装到了tkinter里面,请看!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#-*- coding:utf-8 -*- import tkinter as tk #使用tkinter前需要先导入 from tkinter import filedialog,messagebox,ttk from openpyxl import load_workbook from openpyxl.styles import alignment import os import pandas as pd #建立窗口window window = tk.tk() window.title( 'excel合并单元格工具' ) w_width = 630 w_height = 600 scn_width = window.maxsize()[ 0 ] x_point = (scn_width - w_width) / / 2 window.geometry( '%dx%d+%d+%d' % (w_width,w_height,x_point, 100 )) window.wm_attributes( '-topmost' ,true) window.tk_focusfollowsmouse() window.bind( "<escape>" , lambda event:window.iconify()) path_tar = tk.stringvar() sheetvar = tk.stringvar() #目标工作表 #打开目标文件 def getmergefile(): file_path = filedialog.askopenfilename(title = u '选择文件' ,filetype = [( 'excel' , '.xlsx' )]) path_tar. set (file_path) alldata = pd.read_excel(file_path,none) ttk.label(frame1,text = "请选择目标工作表:" ).grid(row = 1 ,column = 0 ,sticky = 'w' ) global sheetvar chosen_sheet = ttk.combobox(frame1,width = 16 ,textvariable = sheetvar) chosen_sheet[ 'values' ] = list (alldata) chosen_sheet.grid(row = 1 ,column = 1 ,sticky = 'w' ) chosen_sheet.bind( "<<comboboxselected>>" , lambda event:getmergeseg(event,alldata,sheetvar.get())) #勾选目标字段 def getmergeseg(event,alldata,sheet): global frame2,segvars segvars = [] try : frame2.destroy() except : pass frame2 = tk.frame(window,padx = 15 ,pady = 6 ) frame2.grid(row = 1 ,column = 0 ,sticky = 'w' ) ttk.label(frame2,text = "请勾选分组合并的目标字段(第一个勾选框为分组合并依据,必须事先进行排序:" ).grid(row = 0 ,column = 0 ,columnspan = 4 ,sticky = 'w' ) data = alldata[sheet] for index,item in enumerate (data.columns): segvars.append(tk.stringvar()) ttk.checkbutton(frame2,text = item,variable = segvars[ - 1 ],onvalue = item,offvalue = ' ').grid(row=(index//4+1),column=index%4,sticky=' w') #合并字段单元格 def merging( file ,sheet,segvars): selected = [i.get() for i in segvars if i.get()] df = pd.read_excel( file ,sheet) wb = load_workbook( file ) ws = wb[sheet] mergecells(ws,df,selected) try : wb.save( file ) messagebox.showinfo( '提示' , file + '-' + sheet + '指定单元格合并完成' ) os.system( 'start ' + os.path.dirname( file )) except exception as e: messagebox.showerror( '警告' , str (e)) #合并单元格函数 def mergecells(ws,df,cols): col = cols[ 0 ] gdic = df.groupby(col).groups aligncenter = alignment(horizontal = 'center' ,vertical = 'center' ) for gname in gdic: indexs = gdic[gname] + 2 indexs = indexs.sort_values() for col in cols: #每一个要合并的字段 colindex = df.columns.tolist().index(col) + 1 ws.merge_cells(start_row = indexs[ 0 ],end_row = indexs[ - 1 ],start_column = colindex,end_column = colindex) #合并 for i in range ( 1 ,ws.max_row + 1 ): #实现居中 ws.cell(row = i,column = colindex).alignment = aligncenter def manual(): #使用说明 info = """ 作用是合并单元格,把同样内容的单元格合并到一起,所以必须实现对目标字段进行排序,否则无法实现合并 """ messagebox.showinfo( '提示' ,info) frame1 = tk.frame(window,pady = 6 ,padx = 15 ) frame1.grid(row = 0 ,column = 0 ,sticky = 'w' ) ttk.button(frame1,text = "打开目标文件" ,command = getmergefile).grid(row = 0 ,column = 0 ,sticky = 'w' ) ttk.entry(frame1,textvariable = path_tar,width = 40 ).grid(row = 0 ,column = 1 ) frame3 = tk.frame(window,pady = 10 ,padx = 15 ) frame3.grid(row = 2 ,column = 0 ,sticky = 'w' ) ttk.button(frame3,text = "点击合并单元格" ,command = lambda :merging(path_tar.get(),sheetvar.get(),segvars)).grid(row = 0 ,column = 0 ,sticky = 'w' ) ttk.button(frame3,text = "使用说明" ,command = manual).grid(row = 0 ,column = 1 ) window.mainloop() |
效果如图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/chaodaibing/article/details/108320039