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
with comtypes.client.GetModule
like this
GetModule(GetLibPath() + "esriArcMapUI.olb") GetModule(GetLibPath() + "esriFramework.olb") GetModule(GetLibPath() + "esriCarto.olb")
Then comes the code
import arcpy 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' pMapDoc.Open(path) 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) pMapDoc.Save()
Notice how QuerySize()
shows you the current layout size instantly. Also notice setting the unit, for more option use this link. You can always test something more using this link.