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将图片文件转换成base64编码的方法
Mar 14 Python
python实现发送和获取手机短信验证码
Jan 15 Python
Python处理XML格式数据的方法详解
Mar 21 Python
python实现树形打印目录结构
Mar 29 Python
Python实现的爬取百度文库功能示例
Feb 16 Python
linux安装python修改默认python版本方法
Mar 31 Python
python通过SSH登陆linux并操作的实现
Oct 10 Python
python实现Oracle查询分组的方法示例
Apr 30 Python
python实现邮件循环自动发件功能
Sep 11 Python
python的数学算法函数及公式用法
Nov 18 Python
python爬虫基础之urllib的使用
Dec 31 Python
Python游戏开发实例之graphics实现AI五子棋
Nov 01 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
Laravel推荐使用的十个辅助函数
2019/05/10 PHP
laravel 出现command not found问题的解决方案
2019/10/23 PHP
php7 图形用户界面GUI 开发示例
2020/02/22 PHP
javascript 函数速查表
2010/02/07 Javascript
JavaScript如何从listbox里同时删除多个项目
2013/10/12 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
javascript框架设计读书笔记之数组的扩展与修复
2014/12/02 Javascript
angularjs客户端实现压缩图片文件并上传实例
2015/07/06 Javascript
实例讲解JavaScript中instanceof运算符的用法
2016/06/08 Javascript
原生js获取元素样式的简单方法
2016/08/06 Javascript
浅谈JS验证表单文本域输入空格的问题
2017/02/14 Javascript
jQuery日程管理控件glDatePicker用法详解
2017/03/29 jQuery
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
浅谈Angular6的服务和依赖注入
2018/06/27 Javascript
JS数组求和的常用方法总结【5种方法】
2019/01/14 Javascript
详解Vuex下Store的模块化拆分实践
2019/07/31 Javascript
Eclipse和PyDev搭建完美Python开发环境教程(Windows篇)
2016/11/16 Python
TensorFlow实现模型评估
2018/09/07 Python
python多进程下实现日志记录按时间分割
2019/07/22 Python
python3正则模块re的使用方法详解
2020/02/11 Python
Python3爬虫中关于中文分词的详解
2020/07/29 Python
python批量生成条形码的示例
2020/10/10 Python
Kathmandu美国网站:新西兰户外运动品牌
2019/03/23 全球购物
linux面试题参考答案(1)
2016/01/22 面试题
夜班门卫岗位职责
2013/12/09 职场文书
自我评价的写作规则
2014/01/06 职场文书
2014年乡镇植树节活动方案
2014/02/28 职场文书
开展批评与自我批评发言材料
2014/05/15 职场文书
火锅店的活动方案
2014/08/15 职场文书
公民代理授权委托书
2014/09/24 职场文书
2014年初级职称工作总结
2014/12/08 职场文书
幼儿园教师安全责任书
2015/05/08 职场文书
离婚财产分割协议书
2015/08/11 职场文书
微信小程序基础教程之echart的使用
2021/06/01 Javascript
React Fragment介绍与使用详解
2021/11/11 Javascript
Nginx实现负载均衡的项目实践
2022/03/18 Servers