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: https://pbpython.com/windows-com.html
- MS Excel not Visio
- but 50% of the information needed
(2) PowerShell => COM => MS Visio
How to access Microsoft Visio using the COM-Interface https://www.powershellstation.com/2016/01/20/powershell-and-visio-1
- 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: https://docs.microsoft.com/en-us/office/vba/api/overview/visio 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
Methods
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']
Properties
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: https://docs.microsoft.com/en-us/office/vba/api/overview/visio
Start drawing
Page-Object
A good starting point might be the „Page“-Object: https://docs.microsoft.com/en-us/office/vba/api/visio.page
Well add „Shapes“ to the „Page“(-Object) using Methods of the Page-Object:
https://docs.microsoft.com/en-us/office/vba/api/visio.page.drawrectangle or https://docs.microsoft.com/en-us/office/vba/api/visio.page.drawoval – both Methods will return an „Shape“-Object.
#https://docs.microsoft.com/en-us/office/vba/api/visio.page.drawrectangle
rect1 = page.DrawRectangle(1,1,2,2)
rect2 = page.DrawRectangle(4,4,5,5)
#
#https://docs.microsoft.com/en-us/office/vba/api/visio.page.drawoval
oval1 = page.DrawOval(1,4,2,5)
oval2 = page.DrawOval(4,1,5,2)
Shape Object
Look at https://docs.microsoft.com/en-us/office/vba/api/visio.shape – there’s a „Text“-Property:
#https://docs.microsoft.com/en-us/office/vba/api/visio.shape
#https://docs.microsoft.com/en-us/office/vba/api/visio.shape.text
rect1.Text="Rect1"
rect2.Text="Rect2"
oval1.Text="Oval1"
oval2.Text="Oval2"
Result
>>> len(shapes)
4