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 相关文章推荐
Python3实现从文件中读取指定行的方法
May 22 Python
Python Sqlite3以字典形式返回查询结果的实现方法
Oct 03 Python
浅谈Python中的私有变量
Feb 28 Python
python使用opencv驱动摄像头的方法
Aug 03 Python
解决Python下json.loads()中文字符出错的问题
Dec 19 Python
Python序列化与反序列化pickle用法实例
Nov 11 Python
浅谈python 调用open()打开文件时路径出错的原因
Jun 05 Python
python 元组的使用方法
Jun 09 Python
浅析Python 责任链设计模式
Sep 11 Python
Python 操作 MySQL数据库
Sep 18 Python
Django windows使用Apache实现部署流程解析
Oct 12 Python
python批量更改目录名/文件名的方法
Apr 18 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
Win2000+Apache+MySql+PHP4+PERL安装使用小结
2006/10/09 PHP
php 上一篇,下一篇文章实现代码与原理说明
2010/05/09 PHP
php程序的国际化实现方法(利用gettext)
2011/08/14 PHP
phpExcel中文帮助手册之常用功能指南
2014/08/18 PHP
php递归法读取目录及文件的方法
2015/01/30 PHP
php array_values 返回数组的值实例详解
2016/11/17 PHP
文本链接逐个出现的js脚本
2007/12/12 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
js截取中英文字符串、标点符号无乱码示例解读
2014/04/17 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
jquery如何获取元素的滚动条高度等实现代码
2015/10/19 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
2016/03/09 Javascript
Vue.JS入门教程之列表渲染
2016/12/01 Javascript
详解用原生JavaScript实现jQuery的某些简单功能
2016/12/19 Javascript
如何实现星星评价(jquery.raty.js插件)
2016/12/21 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
JavaScript同源策略和跨域访问实例详解
2018/04/03 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
javascript实现简单打字游戏
2019/10/29 Javascript
VUE 动态组件的应用案例分析
2019/12/02 Javascript
flexible.js实现移动端rem适配方案
2020/04/07 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
2020/08/18 Javascript
[00:26]TI7不朽珍藏III——冥界亚龙不朽展示
2017/07/15 DOTA
python daemon守护进程实现
2016/08/27 Python
Python连接Redis的基本配置方法
2018/09/13 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
Flask框架模板渲染操作简单示例
2019/07/31 Python
flask 实现上传图片并缩放作为头像的例子
2020/01/09 Python
Django 设置多环境配置文件载入问题
2020/02/25 Python
Jmeter HTTPS接口测试证书导入过程图解
2020/07/22 Python
Python unittest如何生成HTMLTestRunner模块
2020/09/08 Python
美国滑板店:Tactics
2020/11/08 全球购物
喜之郎果冻广告词
2014/03/20 职场文书
物业消防安全责任书
2014/07/23 职场文书