Python实现Excel自动分组合并单元格


Posted in Python onFebruary 22, 2021

大家好,我们经常会有这样的需求。比如下图

Python实现Excel自动分组合并单元格

我们需要把同一个省份的合并起来,如下图的效果

Python实现Excel自动分组合并单元格

如何实现呢,这是原有的df

Python实现Excel自动分组合并单元格

直观的操作是这样的:

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就发现了方法了!大家看到了吗?

Python实现Excel自动分组合并单元格

真是柳暗花明又一村啊,完整解决方案已经有了,我封装到了tkinter里面,请看!

#-*- 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()

效果如图:

Python实现Excel自动分组合并单元格

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现统计英文单词个数及字符串分割代码
May 28 Python
Python的Django框架中的URL配置与松耦合
Jul 15 Python
Python中的集合类型知识讲解
Aug 19 Python
基于python的字节编译详解
Sep 20 Python
深入了解Python枚举类型的相关知识
Jul 09 Python
python自带tkinter库实现棋盘覆盖图形界面
Jul 17 Python
Python使用itchat 功能分析微信好友性别和位置
Aug 05 Python
Python values()与itervalues()的用法详解
Nov 27 Python
使用Python来做一个屏幕录制工具的操作代码
Jan 18 Python
tensorflow指定GPU与动态分配GPU memory设置
Feb 03 Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
Oct 28 Python
termux中matplotlib无法显示中文问题的解决方法
Jan 11 Python
matplotlib绘制正余弦曲线图的实现
Feb 22 #Python
Python使用tkinter制作在线翻译软件
Feb 22 #Python
Python中使用Selenium环境安装的方法步骤
Feb 22 #Python
Python爬虫实例之2021猫眼票房字体加密反爬策略(粗略版)
Feb 22 #Python
python实现计算图形面积
Feb 22 #Python
python实现银行账户系统
Feb 22 #Python
Django实现简单的分页功能
Feb 22 #Python
You might like
探讨多键值cookie(php中cookie存取数组)的详解
2013/06/06 PHP
PHP图像处理类库及演示分享
2015/05/17 PHP
round robin权重轮循算法php实现代码
2016/05/28 PHP
PHP实现用户登录的案例代码
2018/05/10 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
Laravel 创建指定表 migrate的例子
2019/10/09 PHP
基于PHP实现短信验证码发送次数限制
2020/07/11 PHP
自己开发Dojo的建议框架
2008/09/24 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
js实现横向伸展开的二级导航菜单代码
2015/08/28 Javascript
AngularJS页面带参跳转及参数解析操作示例
2017/06/28 Javascript
Vue.js组件间的循环引用方法示例
2017/12/27 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
2018/05/09 Javascript
微信小程序onLaunch异步,首页onLoad先执行?
2018/09/20 Javascript
JavaScript面向对象中接口实现方法详解
2019/07/24 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
2019/11/05 Javascript
JS数组方法slice()用法实例分析
2020/01/18 Javascript
用vue 实现手机触屏滑动功能
2020/05/28 Javascript
python 生成目录树及显示文件大小的代码
2009/07/23 Python
Python中声明只包含一个元素的元组数据方法
2014/08/25 Python
python入门教程之识别验证码
2017/03/04 Python
Python实现的多进程和多线程功能示例
2018/05/29 Python
解决Mac安装scrapy失败的问题
2018/06/13 Python
TensorFlow使用Graph的基本操作的实现
2020/04/22 Python
英语自荐信常用语句
2013/12/13 职场文书
银行个人求职自荐信范文
2013/12/16 职场文书
优秀团支部事迹材料
2014/02/08 职场文书
2014年五一活动策划方案
2014/03/15 职场文书
新闻专业毕业生求职信
2014/08/08 职场文书
2014年专项整治工作总结
2014/11/17 职场文书
学校教师师德师风承诺书
2015/04/28 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
Redis中一个String类型引发的惨案
2021/07/25 Redis
各种货币符号快捷输入
2022/02/17 杂记
【海涛dota】偶遇拉娜娅 质量局德鲁伊第一视角解说
2022/04/01 DOTA