如何用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
相关产品推荐
相关产品推荐

