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的即时标记项目练习笔记
Sep 18 Python
python实现从web抓取文档的方法
Sep 26 Python
Python的Django框架中的select_related函数对QuerySet 查询的优化
Apr 01 Python
Python的爬虫框架scrapy用21行代码写一个爬虫
Apr 24 Python
利用Python+Java调用Shell脚本时的死锁陷阱详解
Jan 24 Python
python 用正则表达式筛选文本信息的实例
Jun 05 Python
python 地图经纬度转换、纠偏的实例代码
Aug 06 Python
基于python if 判断选择结构的实例详解
May 06 Python
Keras实现支持masking的Flatten层代码
Jun 16 Python
python定义类的简单用法
Jul 24 Python
几款Python编译器比较与推荐(小结)
Oct 15 Python
python“静态”变量、实例变量与本地变量的声明示例
Nov 13 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入门速成(2)
2006/10/09 PHP
php adodb连接带密码access数据库实例,测试成功
2008/05/14 PHP
PHP+MYSQL 出现乱码的解决方法
2008/08/08 PHP
php实现用于计算执行时间的类实例
2015/04/18 PHP
sina的lightbox效果。
2007/01/09 Javascript
js escape,unescape解决中文乱码问题的方法
2010/05/26 Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
2014/08/27 Javascript
node.js中的events.EventEmitter.listenerCount方法使用说明
2014/12/08 Javascript
浅谈JSON.parse()和JSON.stringify()
2015/07/14 Javascript
javascript图片延迟加载实现方法及思路
2015/12/31 Javascript
jquery easyui datagrid实现增加,修改,删除方法总结
2016/05/25 Javascript
Bootstrap3 Grid system原理及应用详解
2016/09/30 Javascript
老生常谈javascript的类型转换
2016/10/12 Javascript
javaScript嗅探执行神器-sniffer.js
2017/02/14 Javascript
详解使用nvm管理多版本node的方法
2017/08/30 Javascript
基于vue组件实现猜数字游戏
2020/05/28 Javascript
快速解决select2在bootstrap模态框中下拉框隐藏的问题
2018/08/10 Javascript
node.js文件操作系统实例详解
2019/11/05 Javascript
详解为element-ui的Select和Cascader添加弹层底部操作按钮
2020/02/07 Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
2020/04/03 Javascript
手动实现把python项目发布为exe可执行程序过程分享
2014/10/23 Python
python如何实现反向迭代
2018/03/20 Python
Python爬虫爬取新浪微博内容示例【基于代理IP】
2018/08/03 Python
Python tkinter的grid布局及Text动态显示方法
2018/10/11 Python
python random从集合中随机选择元素的方法
2019/01/23 Python
浅析python 中大括号中括号小括号的区分
2019/07/29 Python
PyTorch: 梯度下降及反向传播的实例详解
2019/08/20 Python
如何在 Django 模板中输出 "{{"
2020/01/24 Python
解决Pycharm 导入其他文件夹源码的2种方法
2020/02/12 Python
通过Python实现一个简单的html页面
2020/05/16 Python
Python Tkinter图形工具使用方法及实例解析
2020/06/15 Python
html5 touch事件实现触屏页面上下滑动(一)
2016/03/10 HTML / CSS
会计与审计毕业生自荐信范文
2013/12/30 职场文书
师范学院美术系毕业生自我鉴定
2014/01/29 职场文书
爱心捐赠活动简讯
2015/07/20 职场文书
2016年学校安全教育月活动总结
2016/04/06 职场文书