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中mechanize库的简单使用示例
Jan 10 Python
Python去除字符串两端空格的方法
May 21 Python
Python中的错误和异常处理简单操作示例【try-except用法】
Jul 25 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
Nov 30 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
May 09 Python
Python打包方法Pyinstaller的使用
Oct 09 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
Dec 10 Python
Python字典的概念及常见应用实例详解
Oct 30 Python
使用matplotlib动态刷新指定曲线实例
Apr 23 Python
python 轮询执行某函数的2种方式
May 03 Python
详解selenium + chromedriver 被反爬的解决方法
Oct 28 Python
Python中的tkinter库简单案例详解
Jan 22 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 配置open_basedir 让各虚拟站点独立运行
2009/11/12 PHP
php版微信公众平台回复中文出现乱码问题的解决方法
2016/09/22 PHP
PHP利用二叉堆实现TopK-算法的方法详解
2017/04/24 PHP
七种PHP开发环境搭建工具
2020/06/28 PHP
jQuery 使用手册(七)
2009/09/23 Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
一个简单的js树形菜单
2011/12/09 Javascript
js网页中的(运行代码)功能实现思路
2013/02/04 Javascript
nodeJS代码实现计算交社保是否合适
2015/03/09 NodeJs
jQuery实现跨域iframe接口方法调用
2015/03/14 Javascript
jquery中attr和prop的区别分析
2015/03/16 Javascript
Angular 2父子组件之间共享服务通信的实现
2017/07/04 Javascript
详谈Node.js之操作文件系统
2017/08/29 Javascript
angularjs select 赋值 ng-options配置方法
2018/02/28 Javascript
微信小程序class封装http代码实例
2019/08/24 Javascript
vue移动端使用canvas签名的实现
2020/01/15 Javascript
[09:43]DOTA2每周TOP10 精彩击杀集锦vol.5
2014/06/25 DOTA
pygame学习笔记(4):声音控制
2015/04/15 Python
Python中字符串的格式化方法小结
2016/05/03 Python
Python中的descriptor描述器简明使用指南
2016/06/02 Python
Python的collections模块中namedtuple结构使用示例
2016/07/07 Python
在Python中使用AOP实现Redis缓存示例
2017/07/11 Python
利用Python如何生成hash值示例详解
2017/12/20 Python
pyQt4实现俄罗斯方块游戏
2018/06/26 Python
Python Numpy库安装与基本操作示例
2019/01/08 Python
详解Django 时间与时区设置问题
2019/07/23 Python
使用Matplotlib 绘制精美的数学图形例子
2019/12/13 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
python 操作excel表格的方法
2020/12/05 Python
a标签下载链接的简单实现
2016/09/13 HTML / CSS
HTML5 视频播放(video),JavaScript控制视频的实例代码
2018/10/08 HTML / CSS
幼儿教师自我鉴定
2013/11/02 职场文书
主持人演讲稿范文
2013/12/28 职场文书
计算机专业自荐信范文
2014/05/28 职场文书
厨师长岗位职责范本
2014/08/25 职场文书
师德师风培训感言
2015/08/03 职场文书