pythonopenpyxl

Why doesn't dropdown appear when I attach DataValidation to the column?


I want to create a spreadsheet that only allows two values in column A. Here is my attempt:

import openpyxl
from openpyxl.worksheet.datavalidation import DataValidation


book = openpyxl.Workbook()
sheet = book.active

for i in range(1, 11):
    sheet.cell(row=i, column=1).value = 'Acceptable'
    sheet.cell(row=i, column=2).value = 'Foo'
    sheet.cell(row=i, column=3).value = 'Fah'

validator = DataValidation(type='list', formula1='Acceptable,Allowed,Permitted', allow_blank=True, showDropDown=False)
validator.add('A1:A10')

book.save('test.xlsx')

Actual output:

actual output in Excel, with no dropdown showing

Desired output (manually done by adding the data validation in Excel):

desired output in excel, with dropdown showing

The showDropDown=False is not a typo. I tried True and False there, but according to some sources, showDropDown is a misnomer and showDropDown=False should make it appear.

I tried adding the data validation to individual cells in a loop, but that didn't work either. Here's that attempt:

validator = DataValidation(type='list', formula1='Acceptable,Allowed,Permitted', allow_blank=True, showDropDown=False)
for i in range(1, 4):
    sheet.cell(row=i, column=1).value = 'Acceptable'
    sheet.cell(row=i, column=2).value = 'Foo'
    sheet.cell(row=i, column=3).value = 'Fah'
    validator.add(sheet.cell(row=i, column=1))

I also tried copying and pasting the example from openpyxl's documentation and adding a wb.save('test.xlsx') to the end. They add the validator directly to the sheet. I think the expected result is that the validator is applied to all cells on that sheet, but instead the entire workbook becomes invalid. Windows prompts me to "repair" the book, and after that is done, none of the cells have validation.

Using Python 3.11, openpyxl 3.1.5 (also tried 3.0.10).


Solution

  • You do not add the validation configuration to the Sheet, just try to apply an empty DV config to a range.
    Also your list needs to be quoted correctly;

    Modified code;

    import openpyxl
    from openpyxl.worksheet.datavalidation import DataValidation
    
    
    book = openpyxl.Workbook()
    sheet = book.active
    
    for i in range(1, 11):
        sheet.cell(row=i, column=1).value = 'Acceptable'
        sheet.cell(row=i, column=2).value = 'Foo'
        sheet.cell(row=i, column=3).value = 'Fah'
    
    validator = DataValidation(
        type='list',
        formula1='"Acceptable,Allowed,Permitted"',  # Set values in quotes
        allow_blank=True,
        showDropDown=False
    )
    sheet.add_data_validation(validator)  # Add config as a DV to Sheet
    validator.add('A1:A10')  # Define the range 
    
    book.save('test.xlsx')