エクセルを処理する時、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