You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:45:41