エクセルを処理する時、xlrdはよく使っている。ところが、通常のsheet.cell(0,0).valueだと、結合したセルの値は空になる。実は、sheetクラスに、merged_cellsというものがあり、そこから実際の値を取れる。
import xlrd
excel_path = "test.xlsx"
wb = xlrd.open_workbook(excel_path)
sh = wb.sheet_by_name("Sheet1")
print("通常のやりかた")
print("A1: ", sh.cell(0, 0).value) # A1-B5
print("A3: ", sh.cell(2, 0).value) # ""(空)
print("B5: ", sh.cell(4, 1).value) # ""(空)
print("D9: ", sh.cell(8, 3).value) # ""(空)
print("H7: ", sh.cell(6, 7).value) # ""(空)
for crange in sh.merged_cells:
# crange: row_top, row_length, col_top, col_length
print("crange: ", crange)
"""
crange: (0, 5, 0, 2)
crange: (3, 9, 3, 4)
crange: (6, 7, 5, 8)
"""
merged_cellsから、sheet内結合した全てのセル範囲がわかる。crange:(開始行, 結合した行数, 開始列, 結合した列数)
これを元に、該当セルの行列がある範囲内にある場合、そのセルが別のセルと結合しているということになる。なお、結合範囲内のセルの値は、一番左上のセルに保存されている。
def get_cell_real_value(sh, row, col):
cell = sh.cell(row, col)
for crange in sh.merged_cells: # 結合したセル
if crange[0] <= row < crange[1] and crange[2] <= col < crange[3]:
# 結合範囲内のセルの場合
# 結合したセルの値は、一番左上のセルに保存されている
return sh.cell(crange[0], crange[2]).value
return cell.value
実際の結果:
print("-" * 50)
print("A1: ", get_cell_real_value(sh, 0, 0)) # A1-B5
print("A3: ", get_cell_real_value(sh, 2, 0)) # A1-B5
print("B5: ", get_cell_real_value(sh, 4, 1)) # A1-B5
print("-" * 50)
print("D4: ", get_cell_real_value(sh, 3, 3)) # D4-D9
print("D9: ", get_cell_real_value(sh, 8, 3)) # D4-D9
print("-" * 50)
print("F7: ", get_cell_real_value(sh, 6, 5)) # F7-H7
print("H7: ", get_cell_real_value(sh, 6, 7)) # F7-H7