使用 Python 读取 Excel 中的合并单元格

Read merged cells in Excel with Python

我正在尝试使用 xlrd 读取 Excel 与 Python 的合并单元格。

我的Excel:(注意第一列合并了三行)

    A   B   C
  +---+---+----+
1 | 2 | 0 | 30 |
  +   +---+----+
2 |   | 1 | 20 |
  +   +---+----+
3 |   | 5 | 52 |
  +---+---+----+

在本例中,我想将第一列的第三行读为等于 2,但 returns ''。您知道如何获取合并单元格的值吗?

我的代码:

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)

我得到的:

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

我想得到什么:

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

我刚刚试过了,它似乎适用于您的示例数据:

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)

回归

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

它会跟踪上一行的值,如果当前行的相应值为空,则使用它们。

请注意,上面的代码不会检查给定的单元格是否实际上是一组合并的单元格的一部分,因此在单元格确实应该为空的情况下,它可能会重复以前的值。不过,它可能会有一些帮助。

附加信息:

我随后找到了一个文档页面,其中讨论了一个 merged_cells 属性,可以使用该属性来确定包含在各种合并单元格范围内的单元格。文档说它是 "New in version 0.6.1",但是当我尝试将它与 pip 安装的 xlrd-0.9.3 一起使用时,我得到了错误

NotImplementedError: formatting_info=True not yet implemented

我并不是特别倾向于开始寻找不同版本的 xlrd 来测试 merged_cells 特性,但是如果上面的代码不能满足您的需求并且您遇到我用 formatting_info=True.

做的同样的错误
openpyxl.worksheet.merged_cell_ranges

这个函数你可以得到一个像['A1:M1', 'B22:B27']这样的数组,它告诉你要合并的单元格。

openpyxl.worksheet.merged_cells

此函数显示单元格是否已合并

您也可以尝试使用 pandas 中提供的 fillna 方法 https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html

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

这应该用以前的值替换单元格的值

对于那些正在寻找处理合并单元格的人,OP 要求的方式,同时不覆盖非合并的空单元格。

根据 OP 的代码以及@gordthompson 的回答和@stavinsky 的评论给出的附加信息,以下代码将适用于 excel 个文件(xls、xlsx),它将首先读取 excel 个文件sheet 作为数据框。对于每个合并的单元格,它将复制该合并单元格所代表的所有单元格的合并单元格内容,正如原始 poster.Note 所要求的那样,'xls' 文件的 xlrd 的 merged_cell 功能仅在以下情况下有效'formatting_info' 打开工作簿时传递了参数。

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

我在没有 existo 的情况下尝试了以前的解决方案,但是以下对我有用:

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)

我希望它将来能为某人服务

使用 XLRD 合并单元格

ExcelFile = pd.read_excel("Excel_File.xlsx")
xl = xlrd.open_workbook("Excel_File.xlsx")
FirstSheet = xl.sheet_by_index(0)
for crange in FirstSheet.merged_cells:
    rlo, rhi,clo, chi = crange
    for rowx in range(rlo,rhi):
        for colx in range(clo,chi):
            value = FirstSheet.cell(rowx,colx).value
        if len(value) == 0:
            ExcelFile.iloc[rowx-1,colx] = FirstSheet.cell(rlo,clo).value