2022年 11月 4日

利用Python实现Excel合并单元格

利用Python实现Excel合并单元格

最近在工作中需要批量处理一些Excel文件,为了更直观的展示数据,需要对Excel中的单元格进行合并处理。因为一直使用Pandas实现Excel读写操作,而Pandas无法将单元格进行合并,利用Python的xlsxwriter模块可以实现Excel合并单元格。帖子 python之DataFrame写excel合并单元格 中提供了一种方法,但在使用中会出现一些问题,比如无法处理字符串等类型数据。通过修改方法,定义了一个excel_merge_cells函数,基本可以满足日常利用Python实现Excel合并单元格的需求。

原帖方法

在工作中经常遇到需要将数据输出到excel,且需要对其中一些单元格进行合并,比如如下表表格,需要根据A列的值,合并B、C列的对应单元格

在这里插入图片描述
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文档时会报错。

用图解释如下:

在这里插入图片描述

具体代码如下:
# -*- 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.