Visio Diagrams with Python using COM

Visualize Data from Python in Visio

I needed to illustrate some data discovered by a python script in Microsoft Visio.

As a starting-point i found two sources of infomation in the Internet:

(1) Python => COM => MS Excel

How to access a Windows COM-Application from Python:

  • MS Excel not Visio
  • but 50% of the information needed

(2) PowerShell => COM => MS Visio

How to access Microsoft Visio using the COM-Interface

  • PowerShell
  • the other 50% needed.

Result: „Python => COM => MS Visio“

Putting both pieces together, will allow a Python-Script to control MS Visio.

(3) MS Visio „Object Model“

Without the original documentation provided by Microsoft: there is _no chance_ to get anything to work.

  • the next 50% 😉

The Basics

(1) Python „PyWin32“

Install „PyWin32“-Library

C:\RH>pip install pywin32
Collecting pywin32
  Downloading pywin32-300-cp38-cp38-win_amd64.whl (9.3 MB)
     |████████████████████████████████| 9.3 MB 2.2 MB/s
Installing collected packages: pywin32
Successfully installed pywin32-300

Access Windows/COM from Python

  • open the Visio-Application
    • „visio“-object: stores a pointer to access application-Level functions
  • add a document
    • „document“-object
  • fetch the active Visio-Page
    • „page“-object
  • fetch the list of all Shapes at this page
    • „shapes“-object
import win32com.client as win32
visio = win32.gencache.EnsureDispatch('Visio.Application')
document = visio.Documents.Add("")
page = visio.ActivePage
shapes = page.Shapes

(2) Explore the Visio-Object-Model


Object-Methods could get discovered using the Python „dir“, notice for example

  • DrawOval
  • DrawRectangle
>>> dir(page)
['AddDataVisualization', 'AddGuide', 'AutoConnectMany', 'AutoSizeDrawing', 'AvoidPageBreaks', 'BoundingBox', 'CLSID', 'CenterDrawing', 'CreateDataVisualizerDiagram', 'CreateSelection', 'Delete', 'DrawArcByThreePoints', 'DrawBezier', 'DrawCircularArc', 'DrawLine', 'DrawNURBS', 'DrawOval', 'DrawPolyline', 'DrawQuarterArc', 'DrawRectangle', 'DrawSpline', 'Drop', 'DropCallout', 'DropConnected', 'DropContainer', 'DropIntoList', 'DropLegend', 'DropLinked', 'DropMany', 'DropManyLinkedU', 'DropManyU', 'Duplicate', 'Export', 'GetCallouts', 'GetContainers', 'GetFormulas', 'GetFormulasU', 'GetResults', 'GetShapesLinkedToData', 'GetShapesLinkedToDataRow', 'GetTheme', 'GetThemeVariant', 'Import', 'InsertFromFile', 'InsertObject', 'Layout', 'LayoutChangeDirection', 'LayoutIncremental', 'LinkShapesToDataRows', 'OpenDrawWindow', 'Paste', 'PasteSpecial', 'PasteToLocation', 'Print', 'PrintTile', 'ResizeToFitContents', 'SetFormulas', 'SetResults', 'SetTheme', 'SetThemeVariant', 'ShapeIDsToUniqueIDs', 'SpatialSearch', 'SplitConnector', 'UniqueIDsToShapeIDs', 'VisualBoundingBox', '_ApplyTypes_', '__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__int__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_get_good_object_', '_get_good_single_object_', '_oleobj_', '_prop_map_get_', '_prop_map_put_', 'coclass_clsid', 'old_Paste', 'old_PasteSpecial']


But Object-Parameters won’t and if you don’t want to guess required parameters of Object-Methods, it’s time to bookmark the original documentation provided by Microsoft:

Start drawing


A good starting point might be the „Page“-Object:

Well add „Shapes“ to the „Page“(-Object) using Methods of the Page-Object: or – both Methods will return an „Shape“-Object.

rect1 = page.DrawRectangle(1,1,2,2)
rect2 = page.DrawRectangle(4,4,5,5)
oval1 = page.DrawOval(1,4,2,5)
oval2 = page.DrawOval(4,1,5,2)

Shape Object

Look at – there’s a „Text“-Property:



>>> len(shapes)

Schreibe einen Kommentar