This is a small solution I have been looking for a long time. I can now programmatically change the size of a map layout without opening the mxd in ArcMap. Python lets you handle the programs and codes that runs behind the application without altering the map, symbols and labels in it.
Taking this solution in mind, I started with ArcGIS Desktop 10.3.1 in a Windows XP VM. To change the page size and orientation of the layout we use to use ‘Page and Print setup’ dialog box. To access this box we need to gain access to
ArcObject through Python. This isn’t as geeky as it sounds!
First we need to install
comtypes library through PIP.
pip install comtypes
pip install https://github.com/enthought/comtypes/archive/master.zip
After that download the
snippets102.py from this link created by Mark Cederholm. Remember this snippet is updated for ArcGIS 10.2 only. For 10.1 and the versions before that follow this link. You may also want to read this solution and this one very carefully. Though I won’t be using 10.2 either in this unethical world of pirated software, so I needed to hack this snippet to meet my appetite. To match the snippet version of 10.2 with 10.3.1 I opened the snippet with ST3 and replaced all ‘10.2’ with ‘10.3’… done! Next I put the path of the python file to the PYTHONPATH.
To learn more about the technology working behind these lines check out the presentations called ‘Extend Python Using C++ and ArcObjects‘ and ‘ArcMap and Python: Closing the VBA Gap‘ by Mark Cederholm.
The final stage of preparing our machine is to recreate the cache of
comtypes.client.GetModule like this
GetModule(GetLibPath() + "esriArcMapUI.olb")
GetModule(GetLibPath() + "esriFramework.olb")
GetModule(GetLibPath() + "esriCarto.olb")
Then comes the code
from snippets102 import *
from comtypes.client import GetModule, CreateObject
import comtypes.gen.esriFramework as esriFramework
import comtypes.gen.esriArcMapUI as esriArcMapUI
import comtypes.gen.esriCarto as esriCarto
pMapDoc = CreateObject(esriCarto.MapDocument, interface=esriCarto.IMapDocument)
path = r'D:\my.mxd'
pageLayoutActiveView = CType(pMapDoc.PageLayout, esriCarto.IActiveView)
p = pMapDoc.PageLayout.Page
# checked "Scale map elements proportionally to changes in page size" to resize all symbols with page size
p.StretchGraphicsWithPage = True
# setting the size manually suppresses the default behavior of "Use Printer Paper Settings"
p.QuerySize() = (width, height)
p.Orientation = 2 # orientation 1 = portrait, 2 = landscape
p.Units = 1 # 1 is for Inches
p.PutCustomSize(16.54, 11.69) # sizes of a3, (width, height)