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使用cStringIO实现临时内存文件访问的方法
Mar 26 Python
在DigitalOcean的服务器上部署flaskblog应用
Dec 19 Python
深入理解 Python 中的多线程 新手必看
Nov 20 Python
python3 kmp 字符串匹配的方法
Jul 07 Python
Python中的字符串切片(截取字符串)的详解
May 15 Python
Python面向对象进阶学习
May 21 Python
python实现局域网内实时通信代码
Dec 22 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
Mar 04 Python
计算Python Numpy向量之间的欧氏距离实例
May 22 Python
Python+OpenCV图像处理——实现直线检测
Oct 23 Python
matplotlib绘制多子图共享鼠标光标的方法示例
Jan 08 Python
Python如何解决secure_filename对中文不支持问题
Jul 16 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 程序员的调试技术小结
2009/11/15 PHP
PHP中怎样保持SESSION不过期 原理及方案介绍
2013/08/08 PHP
PHP中Fatal error session_start()错误解决步骤
2014/08/05 PHP
PHP实现更新中间关联表数据的两种方法
2014/09/01 PHP
PHP的全局错误处理详解
2016/04/25 PHP
php中foreach结合curl实现多线程的方法分析
2016/09/22 PHP
PHP后期静态绑定实例浅析
2018/12/21 PHP
Laravel 读取 config 下的数据方法
2019/10/13 PHP
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
2010/07/11 Javascript
动态加载JS文件的三种方法
2013/11/08 Javascript
jQuery中scrollTop()方法用法实例
2015/01/16 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
2016/12/14 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
2017/07/10 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
vue获取当前激活路由的方法
2018/03/17 Javascript
小程序server请求微信服务器超时的解决方法
2019/05/21 Javascript
通过Kettle自定义jar包供javascript使用
2020/01/29 Javascript
python实现监控windows服务并自动启动服务示例
2014/04/17 Python
Python读取Json字典写入Excel表格的方法
2018/01/03 Python
pandas按若干个列的组合条件筛选数据的方法
2018/04/11 Python
对python中的logger模块全面讲解
2018/04/28 Python
利用Python在一个文件的头部插入数据的实例
2018/05/02 Python
解决python中的幂函数、指数函数问题
2019/11/25 Python
完美解决jupyter由于无法import新包的问题
2020/05/26 Python
Python爬虫headers处理及网络超时问题解决方案
2020/06/19 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
Python提取视频中图片的示例(按帧、按秒)
2020/10/22 Python
python中使用.py配置文件的方法详解
2020/11/23 Python
基于MUI框架使用HTML5实现的二维码扫描功能
2018/03/01 HTML / CSS
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
投标单位介绍信
2014/01/09 职场文书
学生打架检讨书1000字
2014/01/16 职场文书
2014年项目工作总结
2014/11/24 职场文书
mybatis源码解读之executor包语句处理功能
2022/02/15 Java/Android
一起来看看Vue的核心原理剖析
2022/03/24 Vue.js