1

I'm working on creating a GP tool that simply exports all MXDs in an input folder into an output folder as PDFs. This actually works, but I messed something up with output directories. I coded something incorrectly so where both loops export to different folders, and not to the output folder. Can someone check this and see what I'm doing wrong with my output directories?

This worked well until one of the MXDs has data driven pages enabled, which exports only the first sheet. I believe this is because data driven pages can't be exported using [mapping.ExportToPDF][1], but instead with [datadrivenpages.exportToPDF.][2] To fix this, I test each MXD to see if they have an attribute 'datadrivenpages'. If yes, pass it through the ddp function, else pass it to the normal export function. I messed up my output directories, but I cant figure out how to fix it!

# Broken code here. Working code is below.
# Script takes all .mxd files in a user defined directory and
# exports them to another user defined directory
# This script accounts for map documents with data driven pages
import os, arcpy

# user sets input and output directories
input_dir = arcpy.GetParameterAsText(0)
    #C:\Users\me\Documents\Projects\City Construction\mxd
output_dir = arcpy.GetParameterAsText(1)
    #C:\Users\me\Documents\Projects\City Construction\pdf
arcpy.env.workspace = ws = str(input_dir)

list = arcpy.ListFiles("*.mxd")
mxdnames = []
for item in list:
    print(str(item))
    mxdnames.append(str(item))
print('All Mxds - ' + str(mxdnames))

for mxd in mxdnames:
    input = os.path.join(ws, mxd)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, mxd[:-4]) + ".pdf")
    if hasattr(mxd, "dataDrivenPages"):
        ddp = mxd.dataDrivenPages
        ddp.exportToPDF(output_name, "ALL")
        arcpy.AddMessage('\t' + str(mxd) + str(' exported successfully (Data Driven Pages Enabled).'))
        del mxd
    else:
        arcpy.mapping.ExportToPDF(mxd, output_name)
        arcpy.AddMessage('\t' + str(mxd) + str(' exported successfully.'))
        del mxd

arcpy.AddMessage(('Exports complete!'))
complete = os.startfile(output_dir)
complete


----------


# Solved
# This script prompts a user for an input directory containing MXDs,
# and prompts for an output directory where PDFs are batch exported
# This script exports both normal MXDs and MXDs with data driven pages enabled.

import os, arcpy

# user sets input and output directories
input_dir = arcpy.GetParameterAsText(0)
output_dir = arcpy.GetParameterAsText(1)
arcpy.env.workspace = ws = str(input_dir)
mxdnames = arcpy.ListFiles("*.mxd")

for documentname in mxdnames:
    input = os.path.join(ws, documentname)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, documentname[:-4]) + ".pdf")
    if hasattr(mxd, "dataDrivenPages"):
        ddp = mxd.dataDrivenPages
        ddp.exportToPDF(output_name, "ALL")
        arcpy.AddMessage('\t' + str(mxd) + str(' exported successfully (Data Driven Pages Enabled).'))
        del mxd
    else:
        arcpy.mapping.ExportToPDF(mxd, output_name)
        arcpy.AddMessage('\t' + str(mxd) + str(' exported successfully.'))
        del mxd

arcpy.AddMessage(('Exports complete!'))
complete = os.startfile(output_dir)
complete
````````````````````````````````````
[1]: https://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-mapping/exporttopdf.htm
[2]: http://desktop.arcgis.com/en/arcmap/10.3/analyze/arcpy-mapping/datadrivenpages-class.htm
1
  • Please don’t include answers within the area reserved for questions. It is fine to self-answer in the are reserved for answers (like you have also done).
    – PolyGeo
    Jun 13, 2019 at 22:58

2 Answers 2

5

You are messing with the iterated variable, mxd within the for loop, but worse than that, you are assigning it an object within the loop which is of a completely different class to what the iteration assigns it.

You should use two different variables instead.

So instead of this:

for mxd in mxdnames:
    input = os.path.join(ws, mxd)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, mxd[:-4]) + ".pdf")

Do something like this:

for documentname in mxdnames:
    input = os.path.join(ws, documentname)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, documentname[:-4]) + ".pdf")

The critical part here, is to use the documentname text string, NOT the mxd map document object, when constructing your output_name.

(You could also overcome that particular problem simply by swapping the last two of the above lines, so that you use mxd while it is still a string and before assigning a map object to it. But that would still be poor form to use the same variable for two completely different purposes in the same context.)

Extra:

Your first for loop appears to be redundant. It seems to be converting a list of strings (file names) into a list of strings. You could remove the first for loop and remove the list variable altogether and just assign you ListFiles() result directly to mxdnames:

mxdnames = arcpy.ListFiles("*.mxd")
for documentname in mxdnames:
    input = os.path.join(ws, documentname)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, documentname[:-4]) + ".pdf")
0
0

Functioning Code with help from @Son-of-a-Beach:

# This script prompts a user for an input directory containing MXDs,
# and prompts for an output directory where PDFs are batch exported
# This script exports both normal MXDs and MXDs with data driven pages enabled.

import os, arcpy

# user sets input and output directories
input_dir = arcpy.GetParameterAsText(0)
output_dir = arcpy.GetParameterAsText(1)
arcpy.env.workspace = ws = input_dir
mxdnames = arcpy.ListFiles("*.mxd")

for documentname in mxdnames:
    input = os.path.join(ws, documentname)
    mxd = arcpy.mapping.MapDocument(input)
    output_name = (os.path.join(output_dir, documentname[:-4]) + ".pdf")
    if hasattr(mxd, "dataDrivenPages"):
        ddp = mxd.dataDrivenPages
        ddp.exportToPDF(output_name, "ALL")
        arcpy.AddMessage('\t' + str(documentname) + ' DDP enabled mxd exported successfully.')
        del mxd
    else:
        arcpy.mapping.ExportToPDF(mxd, output_name)
        arcpy.AddMessage('\t' + str(documentname) + ' exported successfully.')
        del mxd

arcpy.AddMessage(('Exports complete!'))
complete = os.startfile(output_dir)
complete
1
  • 1
    You're welcome. Note that you are using the str() function in a few places where it is not necessary. Ie, you are using it to convert strings to strings. You don't need to use str() at str(input_dir). Just use input_dir as arcpy.GetParameterAsText() already returns a string. Similarly for + str(' exported sucessfully...') (x 2). Jun 12, 2019 at 5:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.