python之DataFrame实现excel合并单元格


Posted in Python onFebruary 22, 2021

在工作中经常遇到需要将数据输出到excel,且需要对其中一些单元格进行合并,比如如下表表格,需要根据A列的值,合并B、C列的对应单元格

python之DataFrame实现excel合并单元格

pandas中的to_excel方法只能对索引进行合并,而xlsxwriter中,虽然提供有merge_range方法,但是这只是一个和基础的方法,每次都需要编写繁琐的测试才能最终调好,而且不能很好的重用。所以想自己写一个方法,结合dataframe和merge_range。大概思路是:

1、定义一个MY_DataFrame类,继承DataFrame类,这样能很好的利用pandas的很多特性,而不用自己重新组织数据结构。
2、定义一个my_mergewr_excel方法,参数分别为:输出excel的路径、用于判断是否需要合并的key_cols列表、用于指明哪些列上的单元格需要被合并的列表
3、将MY_DataFrame封装为一个My_Module模块,以备重用。

合并的算法如下:

1、根据给定参数的【关键列】,进行分组计数和排序,添加CN和RN两个辅助列
2、判断CN大于1的,该分组需要合并,否则该分组(行)无需合并(CN=1说明这个分组数据行是唯一的,无需合并)
3、对应需要合并的分组,判断当前列是不是在给定参数【合并列】中,是则用合并写excel单元格,否则就是普通的写excel单元格。
4、在需要合并的列中,如果对于的RN=1则调用merge_range,一次性写想下写CN个单元格,如果RN>1则跳过该单元格,因为在RN=1的时候,已经合并写了该单元格,若再重复调用erge_range,打开excel文档时会报错。

用图解释如下:

python之DataFrame实现excel合并单元格

具体代码如下:

# -*- coding: utf-8 -*- 
""" 
Created on 20170301 
 
@author: ARK-Z 
""" 
import xlsxwriter 
 
 
import pandas as pd 
 
class My_DataFrame(pd.DataFrame): 
 def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): 
  pd.DataFrame.__init__(self, data, index, columns, dtype, copy) 
 
 def my_mergewr_excel(self,path,key_cols=[],merge_cols=[]): 
  # sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True): 
  self_copy=My_DataFrame(self,copy=True) 
  line_cn=self_copy.index.size 
  cols=list(self_copy.columns.values) 
  if all([v in cols for i,v in enumerate(key_cols)])==False:  #校验key_cols中各元素 是否都包含与对象的列 
   print("key_cols is not completely include object's columns") 
   return False 
  if all([v in cols for i,v in enumerate(merge_cols)])==False: #校验merge_cols中各元素 是否都包含与对象的列 
   print("merge_cols is not completely include object's columns") 
   return False  
 
  wb2007 = xlsxwriter.Workbook(path) 
  worksheet2007 = wb2007.add_worksheet() 
  format_top = wb2007.add_format({'border':1,'bold':True,'text_wrap':True}) 
  format_other = wb2007.add_format({'border':1,'valign':'vcenter'}) 
  for i,value in enumerate(cols): #写表头 
   #print(value) 
   worksheet2007.write(0,i,value,format_top) 
   
  #merge_cols=['B','A','C'] 
  #key_cols=['A','B'] 
  if key_cols ==[]: #如果key_cols 参数不传值,则无需合并 
   self_copy['RN']=1 
   self_copy['CN']=1 
  else: 
   self_copy['RN']=self_copy.groupby(key_cols,as_index=False).rank(method='first').ix[:,0] #以key_cols作为是否合并的依据 
   self_copy['CN']=self_copy.groupby(key_cols,as_index=False).rank(method='max').ix[:,0] 
  #print(self) 
  for i in range(line_cn): 
   if self_copy.ix[i,'CN']>1: 
    #print('该行有需要合并的单元格') 
    for j,col in enumerate(cols): 
     #print(self_copy.ix[i,col]) 
     if col in (merge_cols): #哪些列需要合并 
      if self_copy.ix[i,'RN']==1: #合并写第一个单元格,下一个第一个将不再写 
       worksheet2007.merge_range(i+1,j,i+int(self_copy.ix[i,'CN']),j, self_copy.ix[i,col],format_other) ##合并单元格,根据LINE_SET[7]判断需要合并几个 
       #worksheet2007.write(i+1,j,df.ix[i,col]) 
      else: 
       pass 
      #worksheet2007.write(i+1,j,df.ix[i,j]) 
     else: 
      worksheet2007.write(i+1,j,self_copy.ix[i,col],format_other) 
     #print(',') 
   else: 
    #print('该行无需要合并的单元格') 
    for j,col in enumerate(cols): 
     #print(df.ix[i,col]) 
     worksheet2007.write(i+1,j,self_copy.ix[i,col],format_other) 
     
     
  wb2007.close() 
  self_copy.drop('CN', axis=1) 
  self_copy.drop('RN', axis=1)

调用代码:

import My_Module 
 
DF=My_DataFrame({'A':[1,2,2,2,3,3],'B':[1,1,1,1,1,1],'C':[1,1,1,1,1,1],'D':[1,1,1,1,1,1]}) 
 
DF 
Out[120]: 
 A B C D 
0 1 1 1 1 
1 2 1 1 1 
2 2 1 1 1 
3 2 1 1 1 
4 3 1 1 1 
5 3 1 1 1 

DF.my_mergewr_excel('000_2.xlsx',['A'],['B','C'])

效果如下:

python之DataFrame实现excel合并单元格

也可以设置合并A、B列:

DF.my_mergewr_excel('000_2.xlsx',['A'],['A','B'])

效果如下:

python之DataFrame实现excel合并单元格

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

Python 相关文章推荐
Python代码调试的几种方法总结
Apr 15 Python
Python实现的弹球小游戏示例
Aug 01 Python
Python Tkinter实现简易计算器功能
Jan 30 Python
解决Ubuntu pip 安装 mysql-python包出错的问题
Jun 11 Python
python修改txt文件中的某一项方法
Dec 29 Python
Python实现的ftp服务器功能详解【附源码下载】
Jun 26 Python
Django  ORM 练习题及答案
Jul 19 Python
python脚本监控logstash进程并邮件告警实例
Apr 28 Python
通过cmd进入python的步骤
Jun 16 Python
Python 如何查找特定类型文件
Aug 17 Python
python生成随机数、随机字符、随机字符串
Apr 06 Python
python自然语言处理之字典树知识总结
Apr 25 Python
python合并同类型excel表格的方法
Apr 01 #Python
python实现两个文件合并功能
Apr 01 #Python
Python中一行和多行import模块问题
Apr 01 #Python
Python对List中的元素排序的方法
Apr 01 #Python
Python去除、替换字符串空格的处理方法
Apr 01 #Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 #Python
python 通过xml获取测试节点和属性的实例
Mar 31 #Python
You might like
php一些公用函数的集合
2008/03/27 PHP
mysql 中InnoDB和MyISAM的区别分析小结
2008/04/15 PHP
php相当简单的分页类
2008/10/02 PHP
php mssql 时间格式问题
2009/01/13 PHP
PHP实现获取文件mime类型多种方法解析
2020/05/28 PHP
经验几则 推荐
2006/09/05 Javascript
jquery左边浮动到一定位置时显示返回顶部按钮
2014/06/05 Javascript
JS交换变量的方法
2015/01/21 Javascript
jQuery实现精美的多级下拉菜单特效
2015/03/14 Javascript
jQuery实现的自定义弹出层效果实例详解
2016/09/04 Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
2016/12/07 Javascript
vuejs2.0实现一个简单的分页示例
2017/02/22 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
2017/02/28 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
2017/07/07 Javascript
在vue中,v-for的索引index在html中的使用方法
2018/03/06 Javascript
基于Axios 常用的请求方法别名(详解)
2018/03/13 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
vue.js使用v-model实现表单元素(input) 双向数据绑定功能示例
2019/03/08 Javascript
微信小程序分包加载代码实现方法详解
2019/09/23 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
Python基础知识_浅谈用户交互
2017/05/31 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
python自动发邮件总结及实例说明【推荐】
2019/05/31 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
学会迭代器设计模式,帮你大幅提升python性能
2021/01/03 Python
python os.listdir()乱码解决方案
2021/01/31 Python
香港现代设计家具品牌:Ziinlife Furniture
2018/11/13 全球购物
商务英语广告词大全
2014/03/18 职场文书
静心口服夜广告词
2014/03/20 职场文书
党风廉政建设责任书
2014/04/14 职场文书
优秀会计求职信
2014/07/04 职场文书
校运动会广播稿(100篇)
2014/09/12 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
项目经理助理岗位职责
2015/04/13 职场文书
HTML+VUE分页实现炫酷物联网大屏功能
2021/05/27 Vue.js
CSS几步实现赛博朋克2077风格视觉效果
2021/06/16 HTML / CSS