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

如何用Python(win32com/comtypes)将Excel数据导入Visio生成流程图?

用Python自动化Visio从Excel生成流程图

原代码存在的问题

  • 模板调用错误:Documents.Add("Blank Drawing.vst")不符合Visio默认模板命名规范,正确的空白绘图创建方式应为Documents.Add("")或使用流程图专用模板
  • 数据导入逻辑错误:DataRecordsets.Add与GetRecordset的调用不符合Visio COM API要求,需通过OLEDB连接字符串正确导入Excel数据
  • 核心流程缺失:仅完成数据链接,未根据Excel中的Shape type创建对应形状、未通过Next step ID建立连接线,也未处理Connector label等关键字段

修正后的实现代码(使用win32com)

import win32com.client as win32
import os

def visio_flowchart_from_excel(excel_path, output_vsdx):
    # 初始化Visio应用
    visio = win32.Dispatch("Visio.Application")
    visio.Visible = True

    # 创建基于基本流程图模板的文档
    # 若使用空白文档,替换为 doc = visio.Documents.Add("")
    doc = visio.Documents.Add("Basic Flowchart.vst")
    page = doc.Pages.Item(1)

    # Excel数据连接字符串(适配xlsx格式)
    conn_str = (
        f"Provider=Microsoft.ACE.OLEDB.12.0;"
        f"Data Source={excel_path};"
        f"Extended Properties='Excel 12.0 Xml;HDR=YES;'"
    )

    try:
        # 导入Excel数据到DataRecordset
        data_recordset = page.DataRecordsets.Add(
            conn_str,
            win32.constants.visDataRecordsetNoExternalData,
            "Process Flow Data",
            "SELECT * FROM [Sheet1$]"
        )

        # 映射Excel列到形状属性(可选,用于数据链接)
        data_recordset.SetDataRowLinkedColumn("Process step ID", "Prop.ProcessID")
        data_recordset.SetDataRowLinkedColumn("Process step description", "Prop.ProcessDescription")

        # 形状类型与Visio大师的映射(根据实际模板调整)
        shape_master_map = {
            "Process": "Process",
            "Decision": "Decision",
            "Start/End": "Terminator",
            "Connector": "Dynamic connector"
        }

        # 存储形状ID与Visio形状对象的映射,用于后续连接
        shape_id_map = {}
        y_pos = 60  # 初始Y坐标,用于垂直排列形状
        x_offset = 200  # 水平间距

        # 遍历数据记录生成形状
        record_count = data_recordset.RecordCount
        for i in range(1, record_count + 1):
            # 获取当前记录的字段值
            step_id = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Process step ID"))
            step_desc = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Process step description"))
            shape_type = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Shape type"))
            next_step_id = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Next step ID"))
            connector_label = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Connector label"))

            # 获取对应的形状大师
            master = doc.Masters.ItemU(shape_master_map.get(shape_type, "Process"))
            # 在页面上添加形状
            shape = page.Drop(master, x_offset, y_pos)
            # 设置形状文本
            shape.Text = step_desc
            # 存储形状ID映射
            shape_id_map[step_id] = shape

            # 向下移动Y坐标,避免形状重叠
            y_pos -= 100

        # 根据Next step ID创建连接线
        for step_id, shape in shape_id_map.items():
            # 获取当前步骤的下一个步骤ID
            for i in range(1, record_count + 1):
                current_id = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Process step ID"))
                if current_id == step_id:
                    next_id = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Next step ID"))
                    conn_label = data_recordset.GetRowData(i, data_recordset.GetColumnIndex("Connector label"))
                    break
            if next_id in shape_id_map:
                # 创建连接线
                connector_master = doc.Masters.ItemU("Dynamic connector")
                connector = page.Drop(connector_master, 0, 0)
                # 连接两个形状
                connector.CellsU("BeginX").GlueTo(shape.CellsU("PinX"))
                connector.CellsU("BeginY").GlueTo(shape.CellsU("PinY"))
                connector.CellsU("EndX").GlueTo(shape_id_map[next_id].CellsU("PinX"))
                connector.CellsU("EndY").GlueTo(shape_id_map[next_id].CellsU("PinY"))
                # 设置连接线标签
                if conn_label:
                    connector.Text = conn_label

        # 自动布局流程图(可选,调用Visio的布局命令)
        visio.ActiveWindow.SelectAll()
        visio.ActiveWindow.ShapeLayout(
            win32.constants.visLayoutDirTopToBottom,
            win32.constants.visLayoutRouteStraight,
            0, 0, 0, 0,
            win32.constants.visLayoutAdjustNone
        )

        # 保存文档
        doc.SaveAs(output_vsdx)
        print(f"流程图已生成并保存至:{output_vsdx}")

    except Exception as e:
        print(f"执行出错:{str(e)}")
    finally:
        # 关闭Visio
        visio.Quit()

# 示例调用
if __name__ == "__main__":
    excel_file = os.path.abspath("process_flow.xlsx")
    output_file = os.path.abspath("generated_flowchart.vsdx")
    visio_flowchart_from_excel(excel_file, output_file)

关键说明

  • 模板选择:使用Basic Flowchart.vst确保能调用流程图专用形状大师,若需自定义模板,替换为对应路径即可
  • 形状映射:shape_master_map需根据Excel中Shape type的实际值与Visio模板中的大师名称对应调整
  • 自动布局:调用ShapeLayout实现自动排版,可根据需求修改布局方向(如visLayoutDirLeftToRight)和路由方式
  • 数据连接:使用ACE OLEDB驱动确保兼容xlsx格式,若系统未安装需先匹配Python版本安装对应位数的Microsoft Access Database Engine

内容的提问来源于stack exchange,提问作者Nazmul Hasan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:11:00