将excel中的合并单元格拆分并填充数据

需求场景:
有时候处理EXCEL时,会遇到合并单元格的数据。如果直接用pandas空值补全,会导致空单元格会被相邻的数据填充。需要处理合并单元格的同时,不影响原有的空值单元格。

实现思路:

  1. 使用 openpyxl 获取表中所有的合并单元格
  2. 根据合并单元格的信息,将合并单元格左上角,也就是start_cell单元格数据填充到其他的单元格中。
  3. 如果原有的单元格有一定的格式,比如居中、填充色、字体设置,将原有的格式设置到每一个单元格中。

实现代码:

import openpyxl as xl
import copy
import logging
import os
import sys

logger = logging.Logger('拆分合并单元格')
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(filename)s: %(lineno)d %(message)s')
ch = logging.StreamHandler(sys.stdout)  # 输出到控制台
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)

logger.addHandler(ch)

def fill_merge_cell(cur_excel_path, sheet_name, save_path="data3.xlsx"):
    # 填充合并单元格的数据
    work_book = xl.load_workbook(cur_excel_path, read_only=False)
    work_sheet = work_book[sheet_name]

    logger.debug(f'获取当前工作表 {sheet_name} 所有合并区域') 
    for merge_range in work_sheet.merged_cell_ranges:
        value = merge_range.start_cell.value
        work_sheet.unmerge_cells(start_row=merge_range.min_row, start_column=merge_range.min_col,
                                 end_row=merge_range.max_row,
                                 end_column=merge_range.max_col)
        # 获取单元格格式
        source_cell = work_sheet.cell(merge_range.start_cell.row, merge_range.start_cell.column)
        
        for coordinate in merge_range.cells:
            target_cell = work_sheet.cell(*coordinate)
            target_cell.value = value
            
            # 如果单元格有格式,保持格式一致
            if source_cell.has_style:
                target_cell._style = copy.copy(source_cell._style)
                target_cell.font = copy.copy(source_cell.font)
                target_cell.border = copy.copy(source_cell.border)
                target_cell.fill = copy.copy(source_cell.fill)
                target_cell.number_format = copy.copy(source_cell.number_format)
                target_cell.protection = copy.copy(source_cell.protection)
                target_cell.alignment = copy.copy(source_cell.alignment)
           
    logger.debug(f'表格 {os.path.basename(cur_excel_path)} {sheet_name} 中的合并单元格已全部处理完')
    work_book.save(save_path)

你可能感兴趣的:(common,python)