Batch Print PDF Attachments in Outlook
This article was written by Sean Tsai, a data warehousing expert and good friend of the How-To Geek
Have you ever wanted to print every attachment you receive in your Outlook email box? Let’s say you subscribed to a free fax to PDF email service and you want them to be printed out automatically just like an old fashioned fax machine.
Here is a quick way to achieve that if you are comfortable with a little bit of VB (macro) programming.
What we showing here is to create a rule in Outlook and move the incoming fax emails into a separate subfolder. Using VB code we create a macro for you to run a print job against every email in that subfolder so you don’t have to open up the email and print the attachments one by one.
Step 1
Create a subfolder named “Batch Prints” under “Mailbox - YourName” in Outlook.
Step 2
Create a rule (from menu Tools/Rules and Alerts) in Outlook that looks like this:
Place the email address from your fax vendor in the field “email@myfaxservice.com.” In the subject line, place the persistent text that is sent from the fax vendor every time (don’t put in the text that will be altered periodically). The 3rd field “Batch Prints” is the subfolder you just created in the first step.
Step 3
Create a VB macro. First bring up the VB editor by going to Tools/Macro/Visual Basic Editor. You should see the VB editor looks like this:
Step 4
From the left side Project window, right click on the Project1 item and insert a module named “Module1”:
Step 5
Once the Module1 is created, copy the code below into the window on the right side as shown in the bullet #3.
Public Sub PrintAttachments()
Dim Inbox As MAPIFolder
Dim Item As MailItem
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Batch Prints")
For Each Item In Inbox.Items
For Each Atmt In Item.Attachments
‘ all attachments are first saved in the temp folder C:Temp. Be sure to create this folder.
FileName = "C:Temp\" & Atmt.FileName
Atmt.SaveAsFile FileName
‘ please change the program folder accordingly if the Acrobat Reader is not installed on drive C:
Shell """C:Program FilesAdobeReader 8.0Readeracrord32.exe"" /h /p """ + FileName + """", vbHide
Next
Item.Delete ‘remove this line if you don’t want the email be deleted automatically
Next
Set Inbox = Nothing
End Sub
Note that you might need to change the line of code that calls Acrobat to match the path on your system.
Step 6
Now the setup is complete. All the emails from your fax vendor will be moved to your “Batch Prints” when they come in. Please note, in the example, we are expecting all attachments are in PDF format so we use Acrobat acrord32.exe to print every attachment.
Using the Macro
Now, when you want to print all attachments, simply go to the macro and run the macro PrintAttachments and all attachments will be printed sequentially. Email will be deleted and moved into trash bin once it has printed.
Note: the prints are routed to your default printer so you have to make sure a valid printer driver is setup and selected.
Hope this is useful!


I need to be able to print to a pdf/convert to a pdf emails WITH their attachments showing underneath the body of the email. I know how to convert the email and attachments seperately but I need them to be in one document. Is there a plug-in or anything to do this?
Can I do this if Fax to PDF emails come in online shared mailboxes (the ones that you can add in Exchange Sever settings under Advanced tab, "Open these additional mailboxes")? We have Inbox in an additional mailbox where all of our Faxes come in and I would like the script to print those attachments and then move the files to the "Completed" folder. I would greatly appreciate if you could help me out with this.
Nino
Nino,
Yes, you should be able to print any folder you want. The trick is to set the folder statement:
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Batch Prints")
to whatever the folder you want to print. Use the “Parent” method to find your folder in the hierarchy.
To move the email to other folder, simply use the method “Move” as follow:
‘Item.Move GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Another Folder")
As you can see the pattern here, GetNamespace("MAPI").GetDefaultFolder(olFolderInbox) can get you to the default inbox folder. Using “Parent” or “Folder” method will allow you to traverse through the folder hierarchy.
Question,
The statement Item.Delete, I want to delete after the user confirms all attachments printed OK. I made this little routine using your doe. but it's leaving one item in "Batch Print" folder in Outlook. Why is it not deleting all the items inthe folder?
Here's my code.
Private Sub cmdYes_Click()
Dim Inbox As MAPIFolder
Dim Item As MailItem
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Batch Print")
For Each Item In Inbox.Items
Item.Delete
Next
Set Inbox = Nothing
Kill "c:\Batch Print\*.*"
Unload frmConfirmDelete
End Sub
It sounds like a timing issue. The print job might still be taking place while you are trying to delete the items.
Sean,
Very good article.We have a similar requirement.
We have a outlook VBA which checks the incoming mails and if it matches with particular sendername & subject name it process the mail and automatically generating a document.
In our outlook we have two mailboxes one is Personal mailbox and another one is shared mailbox.
Application_NewMail fired whenever mail comes to "Personal Mailbox" .Actually we need to process the "Shared Mailbox" whenever new mail comes into it.
Is it possible? I tried via Outlook Startup & Quit it works fine. But we want to automate this one, like whenever a mail comes into shared mailbox the macro code should be executed.
Can anybody help me?
–Anand
Thanks, Geek. Your solution worked perfectly for me, but only after I had replaced all the missing backslashes from the file paths after copying and pasting your code. Fortunately you have a screenshot above so I could spotted the problem quickly.
Anand,
You can achieve that simply with rules by running a script (macro) as soon as the item is identified. Here is the code snippet.
Sub AutoPrintAttachments(Item As Outlook.MailItem)
' this loop goes through all attachments and print them all
For Each Atmt In Item.Attachments
FileName = "C:\Temp\" & Atmt.FileName
Atmt.SaveAsFile FileName
Shell """C:\Program Files\Adobe\Reader 8.0\Reader\acrord32.exe"" /h /p """ + FileName + """", vbHide
Next
' Uncomment the line below if you want to delete the email after print
' Item.Delete
' Uncomment the line below If you like to save the email in another folder (move the email)
‘ Remember to change the folder name “Another Folder” to the name of your destination folder
‘Item.Move GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Another Folder")
End Sub
It is very similar to batch print but the function declaration (Sub AutoPrintAttachments(Item As Outlook.MailItem)) is a bit different. Outlook will pass down the email that satisfiies your rule to this subroutine and you can process the item by accessing the "Item" object.
Hope this helps.
So does "AutoPrintAttachments" require the same dim statements as the original macro?
And this long name "AutoPrintAttachments(Item As Outlook.MailItem)" seems to confuse the VB editor.
Could you repost the second macro in its entirety, with all necessary code?
Thanks.
Also, when I run the original macro from the macro menu, I get a VB error: "sub or function not defined." However, if I press the little triangle button in the VB editor for "Run Sub/User Form," the macro works fine…
OK, last but not least, no matter which printer I print to (there are a variety around), none of them knows the paper type that Acrobat seems to be sending them, which is variously reported as "Monarch" or "Free Plain" depending on the printer.
I've receiving the error 'Cannot save the attachment. Path does not exist. Make sure the path is correct'
I have created the c:\Temp directory, so I'm not sure what is up.
Sean,
This seems to be exactly what I need but I have one question- does this macro need to be run manually. I'd like to schedule it to run every few minutes or print the faxes (email attachments) as they are received or moved into the "Batch Prints" folder.
Is there a way to automate this? Thanks!
Sean,
Also, one other question. How should I modify the following statement to accomodate the fact my email is stored in a .PST file. In other words, my mail is stored in a PST (Personal Folder). For example, my Inbox is nestled as follows: "Personal Folders" –> "Inbox" –> "Batch Prints" :
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Batch Print")
Thanks again.
Michael
I am recieving the same 'Cannot save the attachment. Path does not exist. Make sure the path is correct' message as Michael. I also created the c:temp directory and cannot figure out where I am going wrong. Please help…
Very helpful article.
I am having an issue with the GetNameSpace statement.
it looks like the method needs and expression in front (see http://msdn2.microsoft.com/en-us/library/aa220108(office.11).aspx):
expression.GetNameSpace(Type)
expression Required. An expression that returns an Application object.
Type Required String. The type of name space to return.
how do i make this work?
I have learned a lot from this article and the FUP comments — I am not a programmer but I need to find a way to batch print PDFs. I set up the rule in Outlook without issue, following the sample above. However, I am still having trouble getting the macro to run. The first error that I was getting was "Compile error: For without Next" and so I added back in the line for Next Item.Delete (don't know if this will fix it, though). Tthe next error is "Run-time error '2147221233 (8004010f)': The operation failed. An object could not be found." I click debug and the debugger is now highlighting the Set Inbox= line. NOTE: My inbox is is my Personal Folder… my code so far is:
Public Sub PrintAttachments()
Dim Inbox As MAPIFolder
Dim Item As MailItem
Dim Atmt As Attachment
Dim FileName As String
Dim i As Integer
Set Inbox = GetNamespace("MAPI").GetDefaultFolder(olFolderInbox).Parent.Folders.Item("Batch Prints")
For Each Item In Inbox.Items
For Each Atmt In Item.Attachments
FileName = "C:\Temp\" & Atmt.FileName
Atmt.SaveAsFile FileName
Shell """C:\Program Files\Adobe\Acrobat 8.0\Acrobat\Acrobat.exe"" /h /p """ + FileName + """", vbHide
Next
Item.Delete
Next
Set Inbox = Nothing
End Sub
I have tried the codes and it work wonderfully for pdf attachments. I would also like to print files with html attachments and would like to have the codes. Please help.