Batch Printing ArcMap MXD Documents
It seems like right clicking on an MXD file in Windows Explorer and trying to print never works right. Here's a simple utility that lets a user select a whole bunch of MXD files and sends them all to the printer without having to open ArcMap. Fast and easy.
This was written in Visual Basic using Visual Studio 2008 and requires that ArcMap 9.3 or later is already installed on the machine.
Here's the full Visual Studio Project:
And here's an installer if you just want the executable:
Here's some sample code that shows how the actual printing function works:
Private Function PrintMXD(ByVal FullFileName As String) As Integer
'Function PrintMXD
'
'This opens an MXD file specified by FullFileName and sends it to the printer
'The map will be sent to whatever printer is specified in the MXD document's settings
'
'Function returns value 1 for success, 0 for failure
'-------------------------------------------------------------------------------------------------------------
'Verify that the file exists
Dim aFileInfo As FileInfo
Dim DocName As String
aFileInfo = New FileInfo(FullFileName)If aFileInfo.Exists Then
'Create a short string to send to the printer laterDocName = aFileInfo.Name
ElseMessageBox.Show(FullFileName & " does not exist", "File not found", MessageBoxButtons.OK, MessageBoxIcon.Error)
PrintMXD = 0
Exit Function
End If
'------------------------------------------------------------------------------------------------------------- 'Get this Application's hWndDim aHWnd As Long
Dim m As System.Reflection.Module
m = Me.GetType.ModuleaHWnd = System.Runtime.InteropServices.Marshal.GetHINSTANCE(m)
'------------------------------------------------------------------------------------------------------------- 'Make a MapDocument and open the specified file 'If this fails, exit the function with error codeDim aDoc As IMapDocument = Nothing
TryWhile aDoc Is Nothing
aDoc = New MapDocumentEnd While
aDoc.Open(FullFileName)
Catch ex As Exception
MessageBox.Show("Unable to start ArcMap..." & vbNewLine & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
PrintMXD = 0
Exit Function
End Try
'------------------------------------------------------------------------------------------------------------- 'When using IMapDocument, it it necessary to Activate the Page Layout and each Map to update the displaysDim i As Integer
Dim pActiveView As IActiveView
'Activate each mapFor i = 0 To aDoc.MapCount - 1
pActiveView = aDoc.Map(i)
pActiveView.Activate(aHWnd)
Next 'Activate the Page Layout and keep a reference to itpActiveView = aDoc.PageLayout
pActiveView.Activate(aHWnd)
'------------------------------------------------------------------------------------------------------------- ' Get the printer's hDC, so we can use the Win32 GetDeviceCaps fuction to ' get Printer's Physical Printable Area x and y margins ' If this fails for some reason, batch printing won't workDim pPrinter As IPrinter
Dim hInfoDC As Integer
Dim dpi As Double
TrypPrinter = aDoc.Printer
hInfoDC = CreateDC(pPrinter.DriverName, pPrinter.Paper.PrinterName, "", IntPtr.Zero)dpi = pPrinter.Resolution
Catch ex As Exception
MessageBox.Show("There was a problem with the printer settings for " & FullFileName & vbNewLine & _"Please manually open and print this document.", "Print Settings Error", MessageBoxButtons.OK, MessageBoxIcon.Hand)
PrintMXD = 0
Exit Function
End Try
'-------------------------------------------------------------------------------------------------------------Dim docPrinterBounds As ESRI.ArcGIS.Geometry.IEnvelope
Dim VisibleBounds As ESRI.ArcGIS.Geometry.IEnvelope
docPrinterBounds = New EnvelopeClass() VisibleBounds = New EnvelopeClass() 'Put the printer's physical bounds into docPrinterBoundsaDoc.PageLayout.Page.GetDeviceBounds(pPrinter, 0, 0, dpi, docPrinterBounds)
'userRect is used to specify the area on the page layout that is to be printedDim userRECT As tagRECT
userRECT.left = CType((docPrinterBounds.XMin - GetDeviceCaps(hInfoDC, 112)), Integer)
userRECT.right = CType((docPrinterBounds.XMax - GetDeviceCaps(hInfoDC, 112)), Integer)
userRECT.bottom = CType((docPrinterBounds.YMax - GetDeviceCaps(hInfoDC, 113)), Integer)
userRECT.top = CType((docPrinterBounds.YMin - GetDeviceCaps(hInfoDC, 113)), Integer)
' Transfer offsetted PrinterBounds envelope back to the userRECTdocPrinterBounds.PutCoords(0, 0, userRECT.right - userRECT.left, userRECT.bottom - userRECT.top)
aDoc.PageLayout.Page.GetPageBounds(pPrinter, 0, 0, VisibleBounds)
'------------------------------------------------------------------------------------------------------------- 'Send the Page Layout to the printerDim hDc As Long
TryhDc = pPrinter.StartPrinting(docPrinterBounds, 0)
pPrinter.SpoolFileName = DocName
pActiveView.Output(hDc, Nothing, userRECT, VisibleBounds, Nothing)
pPrinter.FinishPrinting()
Catch ex As Exception
MessageBox.Show(FullFileName & vbNewLine & ex.Message, "Print Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)PrintMXD = 0
Exit Function
End Try
PrintMXD = 1
End Function



