Excel多级联动下拉菜单的自动化设置(使用Python中的openpyxl模块)

news2025/3/28 23:18:22

1 主要目的

在Excel中,经常会遇到需要制作多级联动下拉菜单的情况,要求单元格内填写的内容只能从指定的多个选项中进行选择,并且需要设置多级目录,其中下级目录的选项内容要根据上级目录的填写内容确定,如下图所示:

 

上图中的数据区域均要求通过下拉菜单实现。其中A列要通过下拉菜单选择省份信息,B列要根据相应的省份信息,通过下拉菜单选择相应的地市信息。

之前的博客已经讲过多级联动下拉菜单在Excel中的设置步骤。但考虑到数据量较大的情况,手动在Excel文件中进行设置的工作量较大,本文通过Python中的openpyxl模块实现多级联动下拉菜单的自动化设置。

2 基本原理

2.1 Excel中多级联动下拉菜单设置的主要步骤

Excel中的下拉菜单主要通过名称管理器以及数据验证界面进行设置。

名称管理器的界面如下图所示。其中“名称”栏记录各选项集的名称,“数值”栏记录各选项集中的所有选项,“引用位置”栏记录选项集中各选项在Excel文件中所在的单元格。

数据验证界面如下图所示。其中“来源”栏可通过indirect函数与名称管理器中的选项集名称进行关联,以此来设置该单元格的选项范围为该选项集中的选项;也可通过indirect函数关联上一级目录对应的单位格位置,以设置本单元格的选项应根据上一级单元格的内容来确定,实现多级联动下拉菜单设置。

 

 

2.2 使用openpyxl完成自动化设置的主要思路 

由于Excel中的名称管理器以及数据验证相关设置均可由openpyxl模块完成,可以通过该模块对相关数据进行处理,并完成对Excel文件的相关设置,以实现多级联动下拉菜单设置的自动化。主要包括三个关键步骤:

(1)将各选项集的信息写入Excel文件。通过openpyxl模块的相关操作,将各选项集信息写入Excel文件中指定的页面。

(2)将各选项集的信息加载至名称管理器。由于openpyxl.workbook.defined_name模块中的DefinedName函数可以进行Excel名称管理器相关设置,可以将各选项集信息加载至名称管理器。

(3)进行数据验证相关内容设置。由于openpyxl.worksheet.datavalidation模块中的DataValidation函数可以对数据验证相关内容进行设置,可以通过该方法完成下拉菜单的制作。

3 选项数据准备

由于Excel中的多级联动下拉菜单选项通常需要通过名称管理器进行关联,为了便于将数据选项写入Excel中的名称管理器,在Python中建立有序字典(OrderedDict),以保存下拉菜单的选项信息。

字典中的每条数据作为一个选项集合,键(key)为选项集名称,值(value)为选项集中的选项。

代码如下:

# data_options.py

from collections import OrderedDict

dic = OrderedDict()
dic["省份"] = ["河北省","河南省","山西省"]
dic["河北省"] = ["石家庄市","保定市","张家口市"]
dic["河南省"] = ["郑州市","开封市","洛阳市"]
dic["山西省"] = ["太原市","运城市","大同市"]

if __name__ == "__main__":
    for key, value in dic.items():
        print(f"key = {key}, value = {value}")

如果选项集较多、数据量较大,可以使用Pandas模块进行读取和处理,并转换为上述OrderedDict格式。具体过程不再赘述。

4 主要步骤

4.1 将选项数据写入Excel文件

为了制作Excel中的下拉菜单,需要获取每个下拉菜单的选项信息,即选项信息需要保存在Excel中。这里使用openpyxl模块将选项信息写入Excel文件。代码如下:

# write_options.py

from data_options import dic
from openpyxl import Workbook
from openpyxl.utils import get_column_letter

path = r"D:\temp\table01.xlsx"  # 文件输出路径
sheet_name_dic = "dic"  # 保存在Excel中页面的名称

book = Workbook()  # 新建Workbook
for sheet in book.sheetnames:
    del book[sheet]  # 删除其他页面
sheet_dic = book.create_sheet(sheet_name_dic)  # 新建sheet

for num, (key, value) in enumerate(dic.items(), start=1):
    sheet_dic[f"A{num}"] = key  # 第1列的值为key值(选项集名称)
    for i in range(len(value)):
        sheet_dic[f"{get_column_letter(i+2)}{num}"] = value[i]
        # (上一行)依次将该选项集中的选项填充在该行后续列的单元格中

book.save(path)  # 保存Excel文件

运行上述代码后,打开保存的Excel文件(table01.xlsx)中的dic页面如下:

其中A列为各选项集的名称,B列及后续列为各选项集中的选项名称。

4.2 Excel中名称管理器设置

在将选项信息写入Excel文件后,需要通过名称管理器将选项信息与下拉菜单进行关联,因此需要将各选项集的选项信息写入Excel的名称管理器中。

该步骤可以结合上一步(将选项数据写入Excel文件)进行,在遍历每个选项集的过程中,将该选项集的信息写入Excel文件相应位置后,同步保存在Excel的名称管理器中。

因此可以改写上一步的代码(write_options.py文件),加入保存名称管理器相关步骤。主要添加以下代码:

attr_text = f"{sheet_name_dic}!$B${num}:${get_column_letter(len(value)+1)}${num}"
# (上一行)设置名称管理器中每个选项集的取值区域(如:attr_text = "dic!$B$1:$D$1)
value_range = DefinedName(key, attr_text=attr_text)  # 将选项集的名称和选项映射为Excel名称管理器中的格式
book.defined_names.append(value_range)  # 加入Excel中的名称管理器

上述代码中,第1行设置了每个选项集的选项取值区域,第3行将选项集名称与选项信息转换为Excel名称管理器相关格式,第4行将该选项集信息加入Excel的名称管理器。

改写后的代码如下:

# write_options.py

from data_options import dic
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
from openpyxl.workbook.defined_name import DefinedName

path = r"D:\temp\table01.xlsx"  # 文件输出路径
dic_name = "dic"  # 保存在Excel中页面的名称

book = Workbook()  # 新建Workbook
for sheet in book.sheetnames:
    del book[sheet]  # 删除其他页面
sheet_dic = book.create_sheet(dic_name)  # 新建sheet

for num, (key, value) in enumerate(dic.items(), start=1):
    sheet_dic[f"A{num}"] = key  # 第1列的值为key值(选项集名称)
    for i in range(len(value)):
        sheet_dic[f"{get_column_letter(i+2)}{num}"] = value[i]
        # (上一行)依次将该选项集中的选项填充在该行后续列的单元格中
    attr_text = f"{dic_name}!$B${num}:${get_column_letter(len(value)+1)}${num}"
    # (上一行)设置名称管理器中每个选项集的取值区域(如:attr_text = "dic!$B$1:$D$1)
    value_range = DefinedName(key, attr_text=attr_text)  # 将选项集的名称和选项映射为Excel名称管理器中的格式
    book.defined_names.append(value_range)  # 加入Excel中的名称管理器

sheet_dic.sheet_state = "hidden"  # 隐藏该页面
book.save(path)  # 保存Excel文件

运行上述代码后,打开保存的Excel文件(table01.xlsx)中的名称管理器如下:

可知各选项集的选项信息以保存在Excel文件的名称管理器中。 

4.3 Excel中数据验证设置

为了设置Excel中的下拉菜单,通常需要手动在Excel中的数据验证界面完成相应的设置,如下图所示:

为了完成数据验证的自动化设置,需要使用openpyxl模块,具体代码如下:

# set_validation.py

from openpyxl import load_workbook
from openpyxl.worksheet.datavalidation import DataValidation

"""参数设置"""
path = r"D:\temp\table01.xlsx"  # 文件路径
table_name = "table"  # 数据表页面名称
row_num = 3  # 数据区域的行数(计划在数据表中录入多少条数据)
row_start = 1  # 数据区域从第几行开始(如果第1行需要设置为标题行,则数据区域的起始行数应往后放)
name1 = "省份"  # Excel名称管理器中,一级目录选项关联的选项集名称

"""文件读取"""
book = load_workbook(path)  # 读取Excel文件
sheet = book.create_sheet(table_name)  # 创建数据表页面

"""一级目录的数据验证设置"""
validation1 = DataValidation(type="list", allow_blank=True, showDropDown=False)  # 数据验证选项
validation1.formula1 = f'=indirect("{name1}")'  # 数据验证表达式
validation1.sqref = f"$A{row_start}:$A{row_start+row_num-1}"  # 数据验证规则的应用区域
sheet.add_data_validation(validation1)  # 添加改规则

"""二级目录的数据验证设置"""
validation2 = DataValidation(type="list", allow_blank=True, showDropDown=False)  # 数据验证选项
validation2.formula1 = f'=indirect($A{row_start}:$A{row_start+row_num-1})'  # 数据验证表达式
validation2.sqref = f"$B{row_start}:$B{row_start+row_num-1}"  # 数据验证规则的应用区域
sheet.add_data_validation(validation2)  # 添加改规则

"""保存文件"""
book.save(path)

其中DataValidation函数对应着一个Excel数据验证界面设置;formula1对应着Excel数据验证界面的“来源”一栏;sqref对应着该数据验证规则的应用区域。

运行程序后,重新打开该Excel文件,发现已经成功新建了“table”页面。打开该页面,发现指定的区域已经成功设置了下拉菜单,如下图所示:

分别打开A列(省份)、B列(地市)单元格的数据验证界面,发现其设置符合预期要求。

 

5 小结 

本文通过Python中的openpyxl模块分别完成“选项数据写入”“名称管理器设置”“数据验证设置”等步骤,实现了Excel多级联动下拉菜单的自动化设置,在录入数据量较大的情况下能够减少人工录入的工作。

本文通过data_options.py、write_options.py以及set_validation.py共3个Python脚本文件,分别实现了选项数据准备、选项数据写入及Excel名称管理器设置、数据验证设置功能。在实际操作时,可以将上述步骤合并为一个Python文件运行,以避免不必要的文件读写操作。合并后的总代码如下:

from collections import OrderedDict
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.workbook.defined_name import DefinedName
from openpyxl.worksheet.datavalidation import DataValidation

"""参数设置"""
path = r"D:\temp\table03.xlsx"  # 输出文件路径
dic_name = "dic"  # Excel中保存选项的页面名称
table_name = "table"  # Excel中数据表页面名称
row_num = 3  # 数据表中数据区域的行数(计划在数据表中录入多少条数据)
row_start = 1  # 数据表中数据区域从第几行开始(如果第1行需要设置为标题行,则数据区域的起始行数应往后放)
name1 = "省份"  # Excel名称管理器中,一级目录选项关联的选项集名称

"""选项数据整理"""
dic = OrderedDict()
dic[name1] = ["河北省","河南省","山西省"]
dic["河北省"] = ["石家庄市","保定市","张家口市"]
dic["河南省"] = ["郑州市","开封市","洛阳市"]
dic["山西省"] = ["太原市","运城市","大同市"]

"""选项数据写入以及Excel名称管理器设置"""
book = Workbook()  # 新建Workbook
for sheet in book.sheetnames:
    del book[sheet]  # 删除其他页面
sheet_dic = book.create_sheet(dic_name)  # 新建页面,用于存放选项数据
for num, (key, value) in enumerate(dic.items(), start=1):
    sheet_dic[f"A{num}"] = key  # 第1列的值为key值(选项集名称)
    for i in range(len(value)):
        sheet_dic[f"{get_column_letter(i+2)}{num}"] = value[i]
        # (上一行)依次将该选项集中的选项填充在该行后续列的单元格中
    attr_text = f"{dic_name}!$B${num}:${get_column_letter(len(value)+1)}${num}"
    # (上一行)设置名称管理器中每个选项集的取值区域(如:attr_text = "dic!$B$1:$D$1)
    value_range = DefinedName(key, attr_text=attr_text)  # 将选项集的名称和选项映射为Excel名称管理器中的格式
    book.defined_names.append(value_range)  # 加入Excel中的名称管理器
sheet_dic.sheet_state = "hidden"  # 隐藏该页面

"""数据验证设置"""
sheet_table = book.create_sheet(table_name)  # 创建数据表页面

# 一级目录
validation1 = DataValidation(type="list", allow_blank=True, showDropDown=False)  # 数据验证选项
validation1.formula1 = f'=indirect("{name1}")'  # 数据验证表达式
validation1.sqref = f"$A{row_start}:$A{row_start+row_num-1}"  # 数据验证规则的应用区域
sheet_table.add_data_validation(validation1)  # 添加改规则

# 二级目录
validation2 = DataValidation(type="list", allow_blank=True, showDropDown=False)  # 数据验证选项
validation2.formula1 = f'=indirect($A{row_start}:$A{row_start+row_num-1})'  # 数据验证表达式
validation2.sqref = f"$B{row_start}:$B{row_start+row_num-1}"  # 数据验证规则的应用区域
sheet_table.add_data_validation(validation2)  # 添加改规则

"""保存文件"""
book.save(path)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2321887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

excalidraw画图工具——背景画布有无格子设置

服啦找了大半天,愣是没找到 toggle grid : 切换格子… Excalidraw的背景格子 只要右键,将这个勾取消就好了?

计算机组成原理———I\O系统精讲<1>

本篇文章主要介绍输入输出系统的发展概况 一.输入输出系统的发展概况 1.早期阶段 该阶段的特点是I/O设备与主存交换信息都必须通过CPU 当时的I/O设备有如下几个特点: (1)每个I\O设备都必须配有一套独立的逻辑电路与CPU相连,用来…

ENSP学习day9

ACL访问控制列表实验 ACL(Access Control List,访问控制列表)是一种用于控制用户或系统对资源(如文件、文件夹、网络等)访问权限的机制。通过ACL,系统管理员可以定义哪些用户或系统可以访问特定资源&#x…

【C++动态规划 数学】1039. 多边形三角剖分的最低得分|2130

本文涉及知识点 C动态规划 数学 LeetCode1039. 多边形三角剖分的最低得分 你有一个凸的 n 边形,其每个顶点都有一个整数值。给定一个整数数组 values ,其中 values[i] 是第 i 个顶点的值(即 顺时针顺序 )。 假设将多边形 剖分 …

5.go切片和map

切片的概念 数组和切片相比较切片的长度是不固定的,可以追加元素,在追加时可能会使切片的容量增大,所以可以将切片理解成 "动态数组",但是,它不是数组,而是构建在数组基础上的更高级的数据结构。…

【Linux网络-多路转接select】

代码:https://gitee.com/nanyi-c/linux/tree/master/day50 一、I/O多路转接之select 1.初始select 系统提供select函数来实现多路复用输入/输出模型 select系统调用是用来让我们的程序监视多个文件描述符的状态变化的程序会停在select这里等待,直到被…

cmd命令查看电脑的CPU、内存、存储量

目录 获取计算机硬件的相关信息的命令分别的功能结果展示结果说明获取计算机硬件的相关信息的命令 wmic cpu get name wmic memorychip get capacity wmic diskdrive get model,size,mediaType分别的功能 获取计算机中央处理器(CPU)的名称 获取计算机内存(RAM)芯片的容量…

LVS的 NAT 模式实现 3 台RS的轮询访问

使用LVS的 NAT 模式实现 3 台RS的轮询访问 1.配置 RS(NAT模式)2. 配置 LVS 主机(仅主机、NAT模式)2.1 配置仅主机网卡(192.168.66.150/24 VIP )2.2 配置 NAT 网卡(192.168.88.6/24 DIP&#xff…

phpcms版AI自动发文插件,自动创作,自动配图,自动发布,支持多种大模型

phpcms版本的AI自动发文插件1.0.0版,支持自动写文章,自动配图,自动发布。目前支持DeepSeek,豆包,通义千问,文心一言,讯飞星火,KIMI,腾讯混元登大模型AI。同时有自定义字段…

C语言判断闰年相关问题

一、简单闰年问题引入 写一个判断年份是否为闰年的程序? 运行结果: 二、闰年问题进阶 使用switch语句根据用户输入的年份和月份,判断该月份有多少天? 第一种写法(判断年份写在switch的case的里面): 运行结果: 第二种解法(先判断闰年): 运行结果: 三、补充 switch中的ca…

数模转换电路(D/A转换器)

将数字信号转换成模拟信号称为数/模转换, 简称D/A(Digital to Analog)转换,实现 D/A 转换的器件称为D/A转换器,简称 DAC(Digital-Analog Converter)。 将模拟信号转换成数字信号称为模/数转换, 简称A/D&a…

网络基础-路由器和交换机工作配置

三、路由器和交换机的工作原理配置以及华为体系下的小型网络的搭建 3.1路由基础 3.1.1数据转发 通过链路层交换机和网络层路由器进行数据转发 交换机(链路层)mac地址表的数据转发路由器(网络层) ip路由表的数据转发 隔离广播域…

uv包简单使用案例

uv由Charlie Marsh开发,是Astral Tool的一个快速Python包安装器和解析器。它类似于pip和pip-tools,但速度更快。此外,uv还支持虚拟环境管理,替代venv和virtualenv。 参考:https://github.com/astral-sh/uv 安装&#x…

JAVA学习*String类

String类 基本知识 String类的构造方法 String类的构造方法有很多,我们需要掌握常见的构造方法,来赋初识值。 1、new一个String类的对象 String name new String("张三");2、使用字符串常量进行赋值 String name "张三";相当…

Java IO框架体系深度解析:从四基类到设计模式实践

Java IO框架体系深度解析:从四基类到设计模式实践 一、IO流体系架构总览 1.1 四基类设计哲学 Java IO框架以InputStream、OutputStream、Reader、Writer四个抽象类为根基,构建了完整的流式IO体系。这种设计体现了以下核心原则: 抽象分层&a…

【读书笔记】华为《从偶然到必然》

note 华为的成功并非偶然,而是通过IPD体系、投资组合管理、平台战略等系统性工具,将研发投资转化为可持续的商业竞争力。书中强调的“管理即内部因素”理念,揭示了企业规模扩张与管理能力匹配的深层规律,为高科技企业提供了可借鉴…

failed to load steamui.dll”错误:Steam用户的高频崩溃问题解析

当你满心欢喜地双击 Steam 图标,准备进入游戏世界时,屏幕上突然弹出 “failed to load steamui.dll” 的刺眼提示——这是全球数百万 Steam 用户最不愿见到的错误之一。作为 Steam 客户端的核心界面动态链接库文件,steamui.dll 的缺失或损坏会…

Linux多线程详解

Linux多线程详解 一、Linux多线程概念1.1 什么是线程1.2 进程和线程1.3 进程的多个线程共享1.4 进程和线程的关系 二、Linux线程控制2.1 POSIX线程库2.2 线程创建2.3 获取线程ID pthread_self2.4 线程等待pthread_join2.5 线程终止2.6 线程栈 && pthread_t2.7 线程的局…

权限提升—Windows权限提升土豆家族溢出漏洞通杀全系

前言 OK,Java安全更新不下去了,实在是太难啦啊,想起来提权这一块没怎么更新过,接下来都主要是更新提权这一块的文章了,Java安全的话以后有耐心再搞了。 手动提权 今天主要是讲这个手动的提权,手动提权相…

JVM(基础篇)

一.初识JVM 1.什么是JVM JVM全称Java Virtyal Machine,中文译名 Java虚拟机 。JVM本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件(将字节码解释成机器码)。 2.JVM的功能 解释和运行:对字节码文件中的指令号,实时…