如何用pywin32提取Visio分组形状中的目标文本?
问题:Visio组合形状中文本提取失败
我正在解析多个Visio文件,目标提取特定形状上的文本。基于现有脚本扩展后,代码如下:
for shp in shps: if shp.Type == 2: parse_names(shp, 2) print(shp.Name+" is group, which contain shapes:") print("-----------------------------------------") for sshp in shp.Shapes: sshpListName.append(sshp.Name) sshpListText.append(sshp.Text) sshpListShape.append(sshp.Shapes) sshpListType.append(sshp.Type) parse_names(sshp, 1) print("-----------------------------------------") else: parse_names(shp, 0)
运行输出:
My Shape.62 My Shape.62 is group, which contain shapes: ----------------------------------------- Sheet_green_frame.5 Sheet_frameID.9 Sheet_funID.6 -----------------------------------------
目标形状是绿色矩形,左下角有一个可见的文本区,但提取后Text列表全为空或空格:
Names = ['Sheet_green_frame.5', 'Sheet_frameID.9', 'Sheet_funID.6'] Text = ['', ' ', ' '] Shape = [<win32com.gen_py.Microsoft Visio 16.0 Type Library.IVShapes instance at 0x1552579577936>, <win32com.gen_py.Microsoft Visio 16.0 Type Library.IVShapes instance at 0x1552579687424>, <win32com.gen_py.Microsoft Visio 16.0 Type Library.IVShapes instance at 0x1552579577024>] Type = [3, 3, 3]
其他形状能正常提取文本,但这个组合形状里的文本找不到存储位置。
解决方案
1. 递归遍历嵌套子形状
从Type=3可知这些是基础形状,但文本可能藏在它们的子形状里。需要递归遍历所有层级的形状:
def extract_text_recursive(shp): # 先尝试获取当前形状的文本 current_text = shp.Text.strip() if current_text: return current_text # 递归遍历子形状 for sub_shp in shp.Shapes: sub_text = extract_text_recursive(sub_shp) if sub_text: return sub_text return "" # 修改原遍历逻辑,替换文本提取部分 for shp in shps: if shp.Type == 2: print(f"{shp.Name} is group, which contain shapes:") print("-----------------------------------------") for sshp in shp.Shapes: sshpListName.append(sshp.Name) # 使用递归函数提取文本 sshpListText.append(extract_text_recursive(sshp)) sshpListShape.append(sshp.Shapes) sshpListType.append(sshp.Type) parse_names(sshp, 1) print("-----------------------------------------") else: parse_names(shp, 0)
2. 直接读取Characters属性
如果shp.Text无法获取内容,试试访问底层的Characters对象,这是Visio存储文本的核心方式:
def get_shape_text(shp): try: return shp.Characters.Text.strip() except Exception: return ""
将sshp.Text替换为get_shape_text(sshp)即可。
3. 检查自定义属性
部分Visio形状的文本会存在自定义属性中,可尝试读取:
def get_custom_prop_text(shp): for prop in shp.CustomProperties: # 根据实际属性名调整,比如"Label"或"Content" if prop.Name in ["Text", "Label"]: return str(prop.Value).strip() return ""
内容的提问来源于stack exchange,提问作者AhmadShahMassoud
相关产品推荐
相关产品推荐

