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基础教程之基本内置数据类型介绍
Feb 20 Python
Python编程中的文件读写及相关的文件对象方法讲解
Jan 19 Python
Linux 发邮件磁盘空间监控(python)
Apr 23 Python
详解Python如何获取列表(List)的中位数
Aug 12 Python
Python3 操作符重载方法示例
Nov 23 Python
Python的Tkinter点击按钮触发事件的例子
Jul 19 Python
python web框架 django wsgi原理解析
Aug 20 Python
python jenkins 打包构建代码的示例代码
Nov 29 Python
借助Paramiko通过Python实现linux远程登陆及sftp的操作
Mar 16 Python
Python自省及反射原理实例详解
Jul 06 Python
浅谈Python __init__.py的作用
Oct 28 Python
Python 中Operator模块的使用
Jan 30 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
PHP生成静态页面详解
2006/12/05 PHP
global.php
2006/12/09 PHP
基于PHP实现的事件机制实例分析
2015/06/18 PHP
制作个性化的WordPress登陆界面的实例教程
2016/05/21 PHP
详解PHP中foreach的用法和实例
2016/10/25 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
Laravel框架基于中间件实现禁止未登录用户访问页面功能示例
2019/01/17 PHP
Yii使用DbTarget实现日志功能的示例代码
2020/07/21 PHP
PHP实现简易图形计算器
2020/08/28 PHP
js动态设置鼠标事件示例代码
2013/10/30 Javascript
Ajax局部更新导致JS事件重复触发问题的解决方法
2014/10/14 Javascript
浅谈JavaScript中的Math.atan()方法的使用
2015/06/14 Javascript
跟我学习javascript的隐式强制转换
2015/11/16 Javascript
实现React单页应用的方法详解
2016/08/02 Javascript
jQuery Dialog 取消右上角删除按钮事件
2016/09/07 Javascript
JS实现动态修改table及合并单元格的方法示例
2017/02/20 Javascript
canvas实现简易的圆环进度条效果
2017/02/28 Javascript
Vue请求java服务端并返回数据代码实例
2019/11/28 Javascript
vue使用svg文件补充-svg放大缩小操作(使用d3.js)
2020/09/22 Javascript
python使用urllib模块开发的多线程豆瓣小站mp3下载器
2014/01/16 Python
Python实现PS滤镜中马赛克效果示例
2018/01/20 Python
Python使用MD5加密算法对字符串进行加密操作示例
2018/03/30 Python
python判断一个数是否能被另一个整数整除的实例
2018/12/12 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
对Django 转发和重定向的实例详解
2019/08/06 Python
Python collections中的双向队列deque简单介绍详解
2019/11/04 Python
详解HTML5中ol标签的用法
2015/09/08 HTML / CSS
个人找工作求职简历的自我评价
2013/10/20 职场文书
给老婆的搞笑检讨书
2014/01/12 职场文书
门前三包责任书
2014/04/15 职场文书
教育实践活动对照检查材料
2014/09/23 职场文书
端午节活动总结报告
2015/02/11 职场文书
礼仪培训心得体会
2016/01/22 职场文书
2016年“11.11”光棍节活动总结
2016/04/05 职场文书
MySQL Server层四个日志的实现
2022/03/31 MySQL