1 问题描述
要处理的Excel文件如图所示:
文件中有部分单元格已合并。为了便于后续数据处理,需要对单元格进行拆分并填充,期望得到的表格如下图所示:
2 处理步骤
2.1 读取Excel文件中要处理的页面
使用openpyxl模块读取要处理的Excel文件相关页面。
其中path表示Excel文件路径,sheet_name表示页面名称。
path = r"E:\workspace\temp\test01.xlsx" # Excel文件路径
sheet_name = "Sheet1" # 要处理的页面名称
book = openpyxl.load_workbook(path) # <class 'openpyxl.workbook.workbook.Workbook'>
sheet = book[sheet_name] # <class 'openpyxl.worksheet.worksheet.Worksheet'>
2.2 获取该页面中所有已合并的单元格
读取表格中所有已合并单元格的区域,保存在列表list_ranges中。
其中sheet.merged_cells.ranges是一个列表,其中的每个元素表示一个已合并单元格的区域。
在读取该列表后要进行复制,因为该列表为引用类型,会随着后续处理而动态变化。
list_ranges = sheet.merged_cells.ranges.copy() # <class 'list'>
2.3 遍历每个已合并单元格的区域
对列表list_ranges中的每个元素进行遍历,即依次处理每个已合并单元格的区域。
其中range表示其中的一个区域。
cell_start表示该区域中的起始单元格,一般情况下,在对合并单元格进行拆分后,该区域的数据会回到起始单元格中。
for range in list_ranges: # range:<class 'openpyxl.worksheet.merge.MergedCellRange'>
cell_start = range.start_cell # <class 'openpyxl.cell.cell.Cell'>
"""后续处理步骤"""
"""……"""
2.4 将该区域内的单元格进行拆分
其中sheet.unmerge_cells方法完成对指定区域内合并单元格的拆分。
range_string指定需要拆分的区域,如“A1:A2”表示对合并单元格“A1:A2”进行拆分。
range.coord为指定区域range的字符串,即若range表示区域“A1:A2”,则range.coord输出为“A1:A2”。
sheet.unmerge_cells(range_string = range.coord)
2.5 对拆分后得到的空单元格进行填充
遍历指定区域中拆分后得到的每个单元格,依次填入数据。
其中row_index、col_index分别表示指定单元格的对应的行、列序号。
对每个单元格,使用该区域中起始单元格的数值进行填充。
for row_index, col_index in range.cells:
cell = sheet.cell(row = row_index, column = col_index)
cell.value = cell_start.value
2.6 保存文件并关闭
path_new = r"E:\workspace\temp\test02.xlsx"
book.save(path_new)
book.close()
3 处理结果
打开处理后得到的Excel文件,如下图所示:
发现原先合并的单元格已完成拆分和填充,但格式需要进一步调整。
生成的新文件中,每一行表示一条数据,可以使用Pandas等模块进行读取并处理。
4 源代码
import openpyxl
path = r"E:\workspace\temp\test01.xlsx" # 源文件路径
path_new = r"E:\workspace\temp\test02.xlsx" # 处理后新文件的保存路径
sheet_name = "Sheet1" # 需要处理的页面名称
"""读取Excel文件中要进行处理的页面"""
book = openpyxl.load_workbook(path) # <class 'openpyxl.workbook.workbook.Workbook'>
sheet = book[sheet_name] # <class 'openpyxl.worksheet.worksheet.Worksheet'>
"""获取页面内所有已合并的单元格"""
list_ranges = sheet.merged_cells.ranges.copy() # <class 'list'>
"""遍历每个含有合并单元格的区域"""
for range in list_ranges: # range:<class 'openpyxl.worksheet.merge.MergedCellRange'>
"""该区域内的起始单元格"""
cell_start = range.start_cell # <class 'openpyxl.cell.cell.Cell'>
"""将该区域内的单元格进行拆分"""
sheet.unmerge_cells(range_string = range.coord)
"""遍历该区域内的所有(拆分后得到的)单元格"""
for row_index, col_index in range.cells:
cell = sheet.cell(row = row_index, column = col_index)
cell.value = cell_start.value
book.save(path_new)
book.close()