One-click Save as PDF from Word: two useful macros

One of the most common word-processing related task for academics is to generate PDF versions of documents — for sharing with colleagues, for submission to a journal, for uploading to a publication page, et cetera. In LaTex, creating PDFs is a question of one simple command (plus a bit of fiddling with settings). In recent versions of Word, it is also pretty simple: just Save as… and select PDF. But that option is buried in the ribbon interface and involves quite a number of clicks. I generate PDFs practically everyday, so I wanted something easier. Enter Word macros.

The macros below do only one thing: they save the currently open file as PDF, by default in the same folder, with the same file name. The first will provide you with the option to change file name and location, the second is a straight export, no questions asked. Pick whichever one you like and add it to Word. Some steps for adding it as a button to a toolbar follow below.

Hang on, where do I put this code?, you ask. You can find out how to add a macro to Word here. Basically you create a new macro and paste the below code into it, then save. I could provide you with a downloadable .dot(x) file but that would only get you into trouble with all sorts of security restrictions in your browser or in Word, so doing it this way is easier.

Macro 1: Using the ‘Save as…’ window

This macro essentially just calls up the ‘Save as…’ window and pre-selects the PDF format. It will suggest a filename, which you can change; and it will warn you when you’re about to overwrite an existing file.


Sub Save_to_PDF()
'
' Save_to_PDF Macro
'
'
  With Dialogs(wdDialogFileSaveAs)
        .Format = wdFormatPDF
        .Show
    End With
    
End Sub

Macro 2: No questions asked

This macro (from here, with helpful amendments by readers) goes straight for exporting. It won’t ask you anything and won’t warn you if a file is overwritten (which to me is precisely the point — I want the PDF always to correspond to the most recent version of the document).


Sub Silent_save_to_PDF()
'
' Silent Save_to_PDF Macro
'
    ActiveDocument.ExportAsFixedFormat OutputFileName:= _
        Replace(ActiveDocument.FullName, ".docx", ".pdf") , _
        ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
        wdExportOptimizeForPrint, Range:=wdExportAllDocument, Item:= _
        wdExportDocumentContent, IncludeDocProps:=False, KeepIRM:=True, _
        CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
        BitmapMissingFonts:=True, UseISO19005_1:=False
End Sub


Advanced users will note that they can customize the output somewhat by changing the export settings. For instance, if you use it mainly for journal submissions, you might want to set IncludeDocProps to False.

Adding your macro to the Quick Access Toolbar

Now we want to pick one of the macros and add it to a menu for true one-click access. I like the ‘quick access toolbar’ best for this purpose — this is where my Zotero buttons are as well. Here’s how:

  1. Right-click the quick access toolbar, choose ‘Customize Quick Access Toolbar’
  2. In the menu that appears, under “Choose commands from”, pick “Macros”. You’ll see your macro appear in the list.
  3. Select your macro (either version 1 or version 2) and click the Add >> button. With the up and down buttons on the right you can position it further; I like mine just next to the normal Save button.
  4. It’ll already work this way. If you’re a perfectionist like me, select your macro in the right column, click ‘Modify…’ and select an icon you like.

Voilá! You have your one-click “Save to PDF” button in Word.

32 thoughts on “One-click Save as PDF from Word: two useful macros

  1. Thank you. Thank you. Great tool. It reduces the frustration level of using Office’s brain-dead File, Save screens.

  2. Your second macro fails if the path has a period. Change to:

    .ExportAsFixedFormat OutputFileName:=Mid(ActiveDocument.FullName, 1, InStrRev(ActiveDocument.FullName, “.”)) & “.pdf”, _

  3. @Tom, fixed, thanks!

    Your version of the macro would be as follows:

    Sub Silent_save_to_PDF()
    '
    ' Silent Save_to_PDF Macro
    '
    With ActiveDocument
    .ExportAsFixedFormat OutputFileName:=Mid(ActiveDocument.FullName, 1, InStrRev(ActiveDocument.FullName, “.”)) & “.pdf”, _
    ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, _
    OptimizeFor:=wdExportOptimizeForPrint, Range:=wdExportAllDocument, _
    Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
    BitmapMissingFonts:=True, UseISO19005_1:=False
    End With

    End Sub

  4. Hi. I have been looking for EXACTLY this! But when I run the second macro i get this error message “Application-defined of object-defined error”. I use 2011 for mac, if that has any relevance.

  5. For me the second version fails.
    I’ve solved it like this:


    Sub Print_to_PDF()

    ActiveDocument.ExportAsFixedFormat OutputFileName:= _
    Replace(ActiveDocument.FullName, ".docx", ".pdf") , _
    ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
    wdExportOptimizeForPrint, Range:=wdExportAllDocument, Item:= _
    wdExportDocumentContent, IncludeDocProps:=False, KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
    BitmapMissingFonts:=True, UseISO19005_1:=False

    End Sub

  6. Hi,

    This is really excellent, but how could I add a certain location the .pdf will be saved to? The thing is that a part of my job is to open external files and save them to .pdf format in order to process them further. So, I’d like to skip the step of saving the .doc/.docx format by adding a location string to the macro, so it would be saved there as .pdf. But I don’t know how, yet.

  7. Try the “Silent_save_to_PDF()” macro also mentioned in the post. This will save a PDF file in the same folder as where your .docx is. Then Google for how to set file location — I don’t know it from the top of my head but it can’t be hard.

  8. Dear Mark,
    Thank you for your excellent post !
    I get this error, and do not understand why:
    Run-time error ‘-2147467259 (80004005)’ :
    The export failed because this feature is not installed.

    Do you have any idea ?
    Regards,

  9. Hi André — sorry, no idea. Sounds like you may not have the right support for creating Adobe PDF on your system.

  10. Thanks a lot,
    please i would also that the file is opened automatically in the default pdf reader .How can i do this ?

  11. Hi,

    Thanks! It helped a lot.

    Need further help how exported Pdf could be password protected.

  12. here’s one I pieced together from several that I found and added a little myself, it will save to network location as PDF, add the date to the file name, and email it automatically.
    strPath = “Enter network location to save to”
    StrDate = Trim(Format(Now(), “ddmmyyyy”))
    strName = Left(ActiveDocument.FullName, Len(ActiveDocument.FullName) – 4)
    strName = strName & StrDate & “.PDF”
    docName = “Enter Document name ” & StrDate
    strAtta = strPath & docName
    Dim outl As Object
    Dim Mail As Object
    ActiveDocument.SaveAs
    ActiveDocument.ExportAsFixedFormat OutputFileName:=strPath & docName, _
    ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:=wdExportOptimizeForPrint, _
    Range:=wdExportAllDocument, Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
    BitmapMissingFonts:=True, UseISO19005_1:=True
    Set outl = CreateObject(“Outlook.Application”)
    Set Mail = outl.CreateItem(0)
    Mail.Subject = “Enter Subject” & StrDate
    Mail.Body = “Enter text” & StrDate
    Mail.To = “Enter Recipient”
    Mail.CC = “Enter Recipient”
    Mail.Attachments.Add strAtta & “.PDF”
    Mail.Display *can be set to send*

  13. I created a macro to save the document in PDF so that each page is stored separately, the file name given is the same as the name of the Word + the page number.

    Sub SaveOneToPDF()
    ‘ Save one page to one document
    Dim NumPages As Long
    Dim i As Long
    ‘ How many pages in the document
    i = 1
    NumPages = ActiveDocument.ComputeStatistics(wdStatisticPages)

    Dim pathName As String
    Dim o As Document
    Set o = ActiveDocument
    If InStrRev(o.Name, “.”) 0 Then
    pathName = Left(o.Name, InStrRev(o.Name, “.”) – 1)
    Else
    pathName = o.Name
    End If
    ‘ Each page is saved as a PDF
    While NumPages >= i ‘ “i” use as pagenumber
    ‘ OpenAfterExport:=False OR true
    ActiveDocument.ExportAsFixedFormat OutputFileName:= _
    ActiveDocument.Path & “\” & pathName & “.p” & i & “.pdf”, ExportFormat:= _
    wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
    wdExportOptimizeForPrint, Range:=wdExportFromTo, From:=i, To:=i, Item:= _
    wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
    BitmapMissingFonts:=True, UseISO19005_1:=False
    i = i + 1
    Wend
    End Sub

  14. Thank you so much! I wish MS Word didn’t make simple, useful tasks take so many clicks in Word! Your macro is a real time saver! Thanks!

  15. I liked (and used!) Alex’s work above (THANKS!), but there were some typo and font issues. Here’s a cleaned up version to save each page to a separate PDF–helpful with MailMerges of invoices, or similar:

    Sub SaveEachPgToPDF()
    ‘ Save each page of the current DOC to a PDF document
    Dim NumPages, i As Long
    Dim pathName As String
    Dim o As Document
    NumPages = ActiveDocument.ComputeStatistics(wdStatisticPages)
    Set o = ActiveDocument
    If InStrRev(o.Name, “.”) > 0 Then
    pathName = Left(o.Name, InStrRev(o.Name, “.”) – 1)
    Else
    pathName = o.Name
    End If
    ‘ PDF files will use existing doc name, with .p1, .p2, etc appended
    For i = 1 To NumPages
    OutFileName = o.Path & “\” & pathName & “.p” & i & “.pdf”
    o.ExportAsFixedFormat _
    OutputFileName:=OutFileName, _
    ExportFormat:=wdExportFormatPDF, _
    OpenAfterExport:=False, _
    OptimizeFor:=wdExportOptimizeForPrint, _
    Range:=wdExportFromTo, From:=i, To:=i, _
    Item:=wdExportDocumentContent, _
    IncludeDocProps:=True, _
    KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, _
    DocStructureTags:=True, _
    BitmapMissingFonts:=True, _
    UseISO19005_1:=False
    Next i
    End Sub

  16. Thank you for the scripts. Also for the suggestion to change the icon of the added macros.

  17. Hi,
    Is there anyone who can make example 2 with these changes for me?

    1. Save to chosen path
    2. Save only current page
    3. Name of PDF – DateandTime+CustomerName (taken form a mergefield)

    Thanks a lot

  18. Would there be a way to set the options for creating the PDF? I regularly create estimates in word and page one is my worksheet while pages 2/3 are what I want to save as a PDF. Your macro works great but this step would save a lot of extra steps deleting the page from the PDF. I could use the one with the save as dialogue but that would be more steps again.
    Great work I must say. Thanks for this even as it is now.

  19. HI

    I have a word document that has 2 pages,

    currently the 1st page; will save to convert to pdf, save to sharepoint, email group email and single email. I just need a hand identifing where i need to insert, the code for a single page and then the document.

    1st page is to be pdf’d separately and saved to sharepoint folder and emailed to a group
    the 1st and second pages are to be emailed as a word document to a email address.

    how do i go about identifying the separate pages.

    see below for the code for the 1st page as it is at the moment.
    the change is the addition of the 2nd page and sending via email as a word. the 2nd page can not go on the first email out.

    Option Explicit

    Dim strFilename As String

    Sub SaveAndSend()

    Dim strDate As String
    Dim strNoti As String
    Dim strTitle As String

    strDate = ActiveDocument.SelectContentControlsByTag(“EventDate”).Item(1).Range.Text

    If IsDate(strDate) Then
    strDate = Format(strDate, “yyyy-mm-dd”)
    Else
    MsgBox “Please select an event date.”, vbExclamation, “Date Error”
    Exit Sub
    End If

    strNoti = ActiveDocument.SelectContentControlsByTag(“NotificationNumber”).Item(1).Range.Text
    strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text

    If Not IsNumeric(strNoti) Or Len(strNoti) 9 Then
    MsgBox “Please enter a valid notification number.”, vbExclamation, “Notification Error”
    Exit Sub
    End If

    If Left(strTitle, 5) = “Enter” Then
    MsgBox “Please enter short text.”, vbExclamation, “Title Not Entered”
    Exit Sub
    End If

    strFilename = strDate & ” ” & strNoti & ” ” & strTitle & “.pdf”

    ActiveDocument.SaveAs FileName:= _
    “https://spo.bhpb.com/sites/COLMTAmacdata/Event%20Notifications/” & strFilename, FileFormat:=wdFormatPDF

    ActiveDocument.SaveAs FileName:= _
    “\\necmacfil01\bcc_data\Transfer\Events\” & strFilename, FileFormat:=wdFormatPDF

    Call SendDocumentAsAttachment

    End Sub

    Sub SendDocumentInMail()

    Dim oOutlookApp As Outlook.Application
    Dim oItem As Outlook.MailItem

    On Error Resume Next

    ‘Start Outlook if it isn’t running
    Set oOutlookApp = GetObject(, “Outlook.Application”)
    If Err 0 Then
    Set oOutlookApp = CreateObject(“Outlook.Application”)
    End If

    ‘Create a new message
    Set oItem = oOutlookApp.CreateItem(olMailItem)

    ‘Copy the open document

    Selection.WholeStory
    Selection.Copy
    Selection.End = True

    ‘Set the WordEditor
    Dim objInsp As Outlook.Inspector
    Dim wdEditor As Word.Document

    Set objInsp = oItem.GetInspector
    Set wdEditor = objInsp.WordEditor

    ‘Count Characters in Signature
    Dim lngCharCount As Long
    lngCharCount = wdEditor.Characters.Count

    ‘Paste Doc at start of email
    wdEditor.Characters(1).PasteAndFormat (wdFormatOriginalFormatting)

    ‘Insert a page break prior to signature
    wdEditor.Characters(wdEditor.Characters.Count – lngCharCount + 1).InsertBreak Type:=wdPageBreak

    ‘Set Subject and recipients
    oItem.Subject = strFilename
    oItem.To = “DL-COL-NEC-MACEventNotification@bhpb.com”
    ‘oItem.To = “daniel.h.smith@bhpb.com”

    ‘Display the message
    oItem.Display

    ‘Clean up
    Set oItem = Nothing
    Set oOutlookApp = Nothing
    Set objInsp = Nothing
    Set wdEditor = Nothing

    End Sub
    Sub SendDocumentAsAttachment()
    Dim strDate As String
    Dim strNoti As String
    Dim strTitle As String

    strDate = ActiveDocument.SelectContentControlsByTag(“EventDate”).Item(1).Range.Text

    If IsDate(strDate) Then
    strDate = Format(strDate, “yyyy-mm-dd”)
    Else
    MsgBox “Please select an event date.”, vbExclamation, “Date Error”
    Exit Sub
    End If

    strNoti = ActiveDocument.SelectContentControlsByTag(“NotificationNumber”).Item(1).Range.Text
    strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text

    If Not IsNumeric(strNoti) Or Len(strNoti) 9 Then
    MsgBox “Please enter a valid notification number.”, vbExclamation, “Notification Error”
    Exit Sub
    End If

    If Left(strTitle, 5) = “Enter” Then
    MsgBox “Please enter short text.”, vbExclamation, “Title Not Entered”
    Exit Sub
    End If

    strFilename = strDate & ” ” & strNoti & ” ” & strTitle & “.pdf”

    Dim bStarted As Boolean

    Dim oOutlookApp As Outlook.Application

    ‘You’ll need to add the Outlook Object Library to VBA Tools References

    Dim oItem As Outlook.MailItem
    strTitle = ActiveDocument.SelectContentControlsByTag(“ShortText”).Item(1).Range.Text

    On Error Resume Next

    If Len(ActiveDocument.Path) = 0 Then ‘Document has not been saved

    ‘so save it
    ‘ ActiveDocument.Save

    End If

    ‘see if Outlook is running and if so turn your attention there

    Set oOutlookApp = GetObject(, “Outlook.Application”)

    If Err 0 Then ‘Outlook isn’t running

    ‘So fire it up

    Set oOutlookApp = CreateObject(“Outlook.Application”)

    bStarted = True

    End If

    ‘Open a new e-mail message

    Set oItem = oOutlookApp.CreateItem(olMailItem)

    With oItem ‘and add the detail to it

    .To = “DL-COL-NEC-MACEventNotification@bhpb.com” ‘send to this address
    .CC = “”
    ‘.BCC = “”

    .Subject = strDate & ” ” & strNoti & ” ” & strTitle ‘This is the message subject

    .Attachments.Add Source:=”\\necmacfil01\bcc_data\Transfer\Events\” & strFilename
    .Display

    End With

    ‘If bStarted Then ‘If the macro started Outlook, stop it again.

    ‘ oOutlookApp.Quit

    ‘End If

    ‘Clean up

    Set oItem = Nothing

    Set oOutlookApp = Nothing

    End Sub

  20. Thank you so much for these codes. I tried using the “record Macro” function and could not get this to work at all. The code for Macro 1 worked well. The Macro 2 needed a little tweaking since it was a little off from the reference page.

    With ActiveDocument
    .ExportAsFixedFormat OutputFileName:=Split(.FullName, “.”)(0) & “.pdf”, _
    ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, _
    OptimizeFor:=wdExportOptimizeForPrint, Range:=wdExportAllDocument, _
    Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
    CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
    BitmapMissingFonts:=True, UseISO19005_1:=False
    End With

  21. Hi!

    One person on stackoverflow helped to modify your macros so it automatically exports word as PDF to the same folder (no questions asked). But I was wondering whether it is possible to also export it as secure / locked for editing PDF. Any suggestions?

    Here is the modified version (works in Word 2011 and 2016 on Mac):

    Sub SaveActiveDocAsPDF()

    On Error Resume Next

    Dim saveName As String
    saveName = ActiveDocument.FullName
    saveName = Left(saveName, Len(saveName) – 5) & “.pdf”

    ActiveDocument.SaveAs FileName:=saveName, _
    FileFormat:=wdFormatPDF
    End Sub

Leave a Reply

Your email address will not be published. Required fields are marked *