如何用Openpyxl提取Excel名称管理器中的定义名称及作用域?
解决openpyxl提取Excel所有定义名称(含作用域)的问题
获取所有定义名称(含同名不同作用域)
你之前用list(wb.defined_names)得到的是去重后的名称字符串,因为DefinedNameDict的迭代器返回的是名称键,同名的会被覆盖。要获取所有含作用域的定义名称,直接访问wb.defined_names.definedName,这是一个包含所有DefinedName对象的列表,不会去重。
提取作用域字符串
每个DefinedName对象包含以下关键属性:
name: 定义名称的字符串scope: 作用域索引(int),工作簿级作用域为Nonevalue: 名称对应的引用或常量值
将作用域索引转换为工作表名称字符串的逻辑:如果scope为None则是工作簿级,否则用wb.sheetnames[scope]获取对应的工作表名称。
完整代码示例
from openpyxl import load_workbook # 加载Excel文件,xlsm格式需指定keep_vba=True保留宏 excel_file_path = r"C:\Users\EI34ZU\Desktop\PVW Migration\AD_test.xlsm" wb = load_workbook(excel_file_path, keep_vba=True) # 获取所有定义名称对象(不含去重) all_defined_names = wb.defined_names.definedName # 遍历提取每个名称的详细信息 for name_obj in all_defined_names: name_str = name_obj.name # 转换作用域为字符串 if name_obj.scope is None: scope_str = "工作簿级" else: scope_str = wb.sheetnames[name_obj.scope] name_value = name_obj.value # 输出或存储信息 print(f"名称: {name_str}, 作用域: {scope_str}, 内容: {name_value}")
筛选特定名称和作用域
如果你需要定位特定名称(比如Print_Area)和作用域(比如SW)的对象,直接遍历筛选即可,无需使用报错的get()方法:
# 筛选目标名称和作用域 target_name = "Print_Area" target_scope = "SW" matched_names = [ obj for obj in all_defined_names if obj.name == target_name and obj.scope is not None and wb.sheetnames[obj.scope] == target_scope ] # 输出匹配结果 for obj in matched_names: print(f"匹配到的内容: {obj.value}")
关于get()方法报错的原因
你遇到的TypeError是因为旧版本的openpyxl中,DefinedNameDict.get()确实不支持scope关键字参数。即使在新版本中,该方法也只能返回第一个匹配的同名名称,无法区分作用域,因此直接遍历definedName列表是更可靠的方案。
内容的提问来源于stack exchange,提问作者Lukassss
相关产品推荐
相关产品推荐

