首页 > 解决方案 > openpyxl:使用 Python 创建 Excel 工作表时,如何使用列表和数据验证?

问题描述

我对使用 Python 还是很陌生……我正在尝试研究如何使用命名的单元格范围将数据验证应用于 Excel 工作表的区域……除此之外。

对于下面的代码,我正在寻找如何: -

...以及寻找更好的方法来:-

我在 Google 搜索和 Stack Overflow 方面做了很多工作……但没有取得多大成功。我还浏览了https://openpyxl.readthedocs.io/en/stable/的相关部分,虽然这些示例很有帮助,但对象的实际定义等、它们的用法等却不那么重要。

我在 Windows 10 64 位、openpyxl 3.0.3 下使用 (Anaconda) Python v3.6.5。

我将不胜感激任何指示或建议...

编码:


import openpyxl
from openpyxl import Workbook
from openpyxl.worksheet.datavalidation import DataValidation

# ---- Create the 'Data' worksheet - to set-up defined ranges

data_headers = [ "StatusValues", "ActivityValues" ]
status_values = [ "ROOKIE", "ACTIVE", "SUSPENDED", "RETIRED" ]
activity_values = [ "ASSIGNED", "TRAINING", "TRAVELLING" ]

# ----

wb = Workbook()
ws_name = wb.create_sheet('Data')              # Does NOT make it active (current)
ws = wb.get_sheet_by_name('Data')

ws.append(data_headers)                        # Create header line
for idx, row in enumerate(status_values):      # Populate the worksheet with 'Status' items...
   ws.cell(column=1, row=idx+2, 
                  value=status_values[idx])

for idx, row in enumerate(activity_values):    # ...and 'Activity' items
   ws.cell(column=2, row=idx+2, 
                  value=activity_values[idx])

# ---- Set-up the named ranges for the entire workbook
#      There HAS to be a BETTER way of specifying the 'worksheet:range' thing(!)

lo = 2
hi = len(status_values) + 1
sbuf = 'Data!$A$%s:$A$%s'%(lo, hi)
sv_range = openpyxl.workbook.defined_name.DefinedName('StatusValues', attr_text=sbuf)
wb.defined_names.append(sv_range)

lo = 2
hi = len(activity_values) + 1
sbuf = 'Data!$B$%s:$B$%s'%(lo, hi)
av_range = openpyxl.workbook.defined_name.DefinedName('ActivityValues', attr_text=sbuf)
wb.defined_names.append(av_range)

# ---- Get some data into the 'main' worksheet

ws = wb.worksheets[0]   # Use the 'original' worksheet
ws.title = "Operatives"
ws.append(["Beast", "Status", "Activity"])     
ws["A2"] = "Dog"
ws["A3"] = "Cat"
ws["A4"] = "Wombat"
ws["A5"] = "Serval"
ws["A6"] = "Camel"

# Create a data-validation object with list validation

dv = DataValidation(type="list", 
                    formula1='"ROOKIE,ACTIVE,SUSPENDED,RETIRED"',  # How can I use 'status_values'...
                    allow_blank=True)

dv2 = DataValidation(type="list", 
                    formula1='"ASSIGNED,TRAINING,TRAVELLING"',     # ...and 'activity_values' lists?
                    allow_blank=True)


# Add the data validation objects to the worksheet
ws.add_data_validation(dv)
ws.add_data_validation(dv2)

# ...and to specific range (ugh... so ugly.. again, has to be a better way..)
dv_app = "B2:B" + str(ws.max_row)
dv.add(dv_app)

dv_app = "C2:C" + str(ws.max_row)
dv2.add(dv_app)

# ----

wb.save(filename = 'validation.xlsx')

exit(0)

标签: pythonexcelopenpyxl

解决方案


我也有同样的问题。Skeeve,您的代码非常有帮助,我相信,9 个月后,您已经找到了使用列表名称作为 formula1 参数的参数的解决方案。谢谢

实际上,我找到了一种方法:

str1 = ','.join(status_values)                                    
str1 = '"'+str1+'"'                                               
                                                                                                       
dv = DataValidation(type="list", formula1=str1, allow_blank=True)

推荐阅读