使用 pandas 从 excel 中读取下拉值

Posted

技术标签:

【中文标题】使用 pandas 从 excel 中读取下拉值【英文标题】:Read drop down values from excel using pandas 【发布时间】:2018-11-27 18:24:26 【问题描述】:

我有一个带有下拉单元格的 Excel。我一直在尝试读取 excel 下拉列表,但它只读取选定的选项。

import pandas

df = pandas.read_excel("BQA.xlsx", header=0)
df.columns = df.columns.str.strip()

print(df)

输出:

 Empty DataFrame
 Columns: [Column 1, Column 2, Column 3, Column 4, yes]
 Index: []

预期输出:

Empty DataFrame
Columns: [Column 1, Column 2, Column 3, Column 4, [yes, no, yes1, no1]]
Index: []

【问题讨论】:

这是一个有趣的问题,希望有人能回答。我的直觉说它在带有 xlrd 等的 python 中不可用。在带有 excel-interop 的 .NET 中,您需要单元格验证属性。见:***.com/questions/25659888/…。一个可能仍然没有结果的建议是看看 xlwings。 在一个单元格中存储一个列表通常是一个糟糕的主意,但是在列中使用一个列表真的很难。有没有更明智的存储方法? 好的,给我任何可以读取该单元格所有选项的方法 @ReKx 不确定你是否仍然关心这个,但我所做的是将选项列表存储在字典中,然后将选项的键存储在数据框中。 【参考方案1】:

您可以使用openpyxl 提取下拉信息:它存储在给定工作表的 data_validations 中。例如(为了便于阅读而插入换行符):

>>> wb = openpyxl.load_workbook("dropdown.xlsx")
>>> ws = wb["Sheet1"]
>>> ws.data_validations
<openpyxl.worksheet.datavalidation.DataValidationList object>
Parameters:
disablePrompts=None, xWindow=None, yWindow=None, count=1, 
dataValidation=[<openpyxl.worksheet.datavalidation.DataValidation object>
Parameters:
sqref=<MultiCellRange [E1]>, showErrorMessage=True, showDropDown=None, showInputMessage=True, 
allowBlank=False, errorTitle=None, error=None, promptTitle=None, prompt=None,
type='list', errorStyle=None, imeMode=None, operator=None, formula1='$L$4:$L$7', formula2=None]

我不会处理所有可能的情况,所以这只是你可以做的各种事情的一个例子,但是像

def read_with_dropdown(book_name, sheet_name, range_str):
    wb = openpyxl.load_workbook(book_name)
    ws = wb[sheet_name]
    data = [[cell.value for cell in row] for row in ws[range_str]]

    validations = ws.data_validations.dataValidation
    for validation in validations:
        ranges = validation.sqref.ranges
        if len(ranges) != 1:
            raise NotImplementedError
        if validation.type == 'list':
            list_cells = ws[validation.formula1]
            values = [cell.value for cell_row in list_cells for cell in cell_row]
        else:
            raise NotImplementedError
        bounds = ranges[0].bounds
        try:
            data[bounds[1]-1][bounds[0]-1] = values
        except IndexError:
            pass
    return data

给我(再次插入换行符):

>>> data = read_with_dropdown("dropdown.xlsx", "Sheet1", "A1:E5")
>>> data
[['Column 1', 'Column 2', 'Column 3', 'Column 4', ['yes', 'no', 'yes1', 'no1']],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None],
 [None, None, None, None, None]]

【讨论】:

我收到一个错误:----&gt; ranges = validation.sqref.rangesAttributeError: 'str' object has no attribute 'ranges' 很好的答案,对我有用。只需删除您的第一个 if, else 语句,因为我的工作表有多个范围,其中有下拉菜单。 在我的情况下,所有“列表”类型验证都具有 formula1 等“name6”、“name8”、“name19”等... 没关系!我认为它们是已定义的名称。他们在这种情况下定义范围

以上是关于使用 pandas 从 excel 中读取下拉值的主要内容,如果未能解决你的问题,请参考以下文章

使用 python/pandas 从特定文件夹中读取几个嵌套的 .json 文件到 excel 中

如何使用 Pandas 从 Excel 中读取某些列 - Python

使用 pandas 从 Excel 文件中读取最后一列

无法使用 read_excel 从 pandas 中的 xlsx 文件中读取日期列?

使用 pandas 从 Excel 中读取矩阵会根据所使用的 PC 提供 2 种不同的输出

使用 lambda 中的 pandas 从 s3 读取 excel 文件并转换为 csv