Leer celdas combinadas en Excel con Python

Estoy tratando de leer celdas combinadas de Excel con Python usando xlrd.

Mi Excel: (tenga en cuenta que la primera columna se combina en las tres filas)

ABC +---+---+----+ 1 | 2 | 0 | 30 | + +---+----+ 2 | | 1 | 20 | + +---+----+ 3 | | 5 | 52 | +---+---+----+ 

Me gustaría leer la tercera línea de la primera columna como igual a 2 en este ejemplo, pero devuelve '' . ¿Tiene alguna idea de cómo llegar al valor de la celda fusionada?

Mi código:

 all_data = [[]] excel = xlrd.open_workbook(excel_dir+ excel_file) sheet_0 = excel.sheet_by_index(0) # Open the first tab for row_index in range(sheet_0.nrows): row= "" for col_index in range(sheet_0.ncols): value = sheet_0.cell(rowx=row_index,colx=col_index).value row += "{0} ".format(value) split_row = row.split() all_data.append(split_row) 

Lo que consigo:

 '2', '0', '30' '1', '20' '5', '52' 

Lo que me gustaría conseguir:

 '2', '0', '30' '2', '1', '20' '2', '5', '52' 

Acabo de intentar esto y parece funcionar para sus datos de muestra:

 all_data = [] excel = xlrd.open_workbook(excel_dir+ excel_file) sheet_0 = excel.sheet_by_index(0) # Open the first tab prev_row = [None for i in range(sheet_0.ncols)] for row_index in range(sheet_0.nrows): row= [] for col_index in range(sheet_0.ncols): value = sheet_0.cell(rowx=row_index,colx=col_index).value if len(value) == 0: value = prev_row[col_index] row.append(value) prev_row = row all_data.append(row) 

regresando

 [['2', '0', '30'], ['2', '1', '20'], ['2', '5', '52']] 

Realiza un seguimiento de los valores de la fila anterior y los utiliza si el valor correspondiente de la fila actual está vacío.

Tenga en cuenta que el código anterior no comprueba si una celda determinada es realmente parte de un conjunto de celdas fusionadas, por lo que posiblemente podría duplicar los valores anteriores en los casos en que la celda debería estar realmente vacía. Aún así, podría ser de alguna ayuda.

Información Adicional:

Posteriormente, encontré una página de documentación que habla de un atributo merged_cells que se puede usar para determinar las celdas que se incluyen en varios rangos de celdas combinadas. La documentación dice que es “Nuevo en la versión 0.6.1”, pero cuando intenté usarlo con xlrd-0.9.3 como se instaló por pip , recibí el error.

NotImplementedError: formatting_info = True aún no implementado

No estoy particularmente inclinado a comenzar a buscar diferentes versiones de xlrd para probar la función merged_cells , pero quizás te interese hacerlo si el código anterior es insuficiente para tus necesidades y encuentras el mismo error que hice con formatting_info=True

También puede intentar usar el método fillna disponible en pandas https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html

 excel = pd.read_excel(dir+filename,header=1) excel[ColName]=excel[ColName].fillna(method='ffill') 

Esto debería reemplazar el valor de la celda con el valor anterior.

Para aquellos que buscan manejar celdas combinadas, la forma en que OP lo ha pedido, sin sobrescribir las celdas vacías no fusionadas.

Basado en el código de OP e información adicional proporcionada por las respuestas de @ gordthompson y el comentario de @stavinsky, el siguiente código funcionará para archivos de Excel (xls, xlsx), leerá la primera hoja del archivo de Excel como un dataframe. Para cada celda combinada, replicará ese contenido de celda combinada sobre todas las celdas que representa esta celda combinada, tal como lo solicitó el póster original. Tenga en cuenta que la función merged_cell de xlrd para el archivo ‘xls’ solo funcionará si se pasa el parámetro ‘formatting_info’ libro de trabajo.

 import pandas as pd filepath = excel_dir+ excel_file if excel_file.endswith('xlsx'): excel = pd.ExcelFile(xlrd.open_workbook(filepath), engine='xlrd') elif excel_file.endswith('xls'): excel = pd.ExcelFile(xlrd.open_workbook(filepath, formatting_info=True), engine='xlrd') else: print("don't yet know how to handle other excel file formats") sheet_0 = excel.sheet_by_index(0) # Open the first tab df = xls.parse(0, header=None) #read the first tab as a datframe for e in sheet_0.merged_cells: rl,rh,cl,ch = e print e base_value = sheet1.cell_value(rl, cl) print base_value df.iloc[rl:rh,cl:ch] = base_value 

Estaba probando las soluciones anteriores sin haber existido, sin embargo lo siguiente funcionó para mí:

 sheet = book.sheet_by_index(0) all_data = [] for row_index in range(sheet.nrows): row = [] for col_index in range(sheet.ncols): valor = sheet.cell(row_index,col_index).value if valor == '': for crange in sheet.merged_cells: rlo, rhi, clo, chi = crange if rlo <= row_index and row_index < rhi and clo <= col_index and col_index < chi: valor = sheet.cell(rlo, clo).value break row.append(valor) all_data.append(row) print(all_data) 

Espero que le sirva a alguien en el futuro.

 openpyxl.worksheet.merged_cell_ranges 

Esta función le permite obtener una matriz como ['A1:M1', 'B22:B27'] , que le indica las celdas a fusionar.

 openpyxl.worksheet.merged_cells 

Esta función le muestra si una celda se ha fusionado o no