Skip to content

Instantly share code, notes, and snippets.

@mkoertgen
Last active November 23, 2023 18:15
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkoertgen/2087bacda9cff0fa68aa to your computer and use it in GitHub Desktop.
Save mkoertgen/2087bacda9cff0fa68aa to your computer and use it in GitHub Desktop.
A powershell automating Word to generate Pdf
A powershell automating Word to generate Pdf
*.docx
*.docx
*.pdf
@echo off
setlocal
set input=%1
if "%input%"=="" set input=*.docx
for %%a in (%input%) do powershell -f doc2pdf.ps1 "%%a" "%%~dpna.pdf"
)
endlocal
# cf.:
# - http://blog.coolorange.com/2012/04/20/export-word-to-pdf-using-powershell/
# - https://gallery.technet.microsoft.com/office/Script-to-convert-Word-f702844d
# http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/24/weekend-scripter-convert-word-documents-to-pdf-files-with-powershell.aspx
param([string]$DocInput, [string]$PdfOutput = '.\output.pdf')
Add-type -AssemblyName Microsoft.Office.Interop.Word
#
# - optimize for screen/print: wdExportOptimizeForOnScreen / wdExportOptimizeForPrint
# - content only/include markups & comments: wdExportDocumentContent / wdExportDocumentWithMarkup
# - create bookmarks: wdExportCreateHeadingBookmarks / wdExportCreateWordBookmarks
function WordToPdf([string]$wdSourceFile, [string]$wdExportFile) {
$wdExportFormat = [Microsoft.Office.Interop.Word.WdExportFormat]::wdExportFormatPDF
$wdOpenAfterExport = $false
$wdExportOptimizeFor = [Microsoft.Office.Interop.Word.WdExportOptimizeFor]::wdExportOptimizeForOnScreen
$wdExportRange = [Microsoft.Office.Interop.Word.WdExportRange]::wdExportAllDocument
$wdStartPage = 0
$wdEndPage = 0
$wdExportItem = [Microsoft.Office.Interop.Word.WdExportItem]::wdExportDocumentContent
$wdIncludeDocProps = $true
$wdKeepIRM = $true
$wdCreateBookmarks = [Microsoft.Office.Interop.Word.WdExportCreateBookmarks]::wdExportCreateHeadingBookmarks
$wdDocStructureTags = $true
$wdBitmapMissingFonts = $true
$wdUseISO19005_1 = $false
$wdApplication = $null;
$wdDocument = $null;
# How to: Programmatically Close Documents (without changes)
# http://msdn.microsoft.com/en-us/library/af6z0wa2.aspx
$doNotSaveChanges = [Microsoft.Office.Interop.Word.WdSaveOptions]::wdDoNotSaveChanges
try
{
$wdApplication = New-Object -ComObject "Word.Application"
$wdDocument = $wdApplication.Documents.Open($wdSourceFile)
$wdDocument.ExportAsFixedFormat(
$wdExportFile,
$wdExportFormat,
$wdOpenAfterExport,
$wdExportOptimizeFor,
$wdExportRange,
$wdStartPage,
$wdEndPage,
$wdExportItem,
$wdIncludeDocProps,
$wdKeepIRM,
$wdCreateBookmarks,
$wdDocStructureTags,
$wdBitmapMissingFonts,
$wdUseISO19005_1
)
}
catch
{
$wshShell = New-Object -ComObject WScript.Shell
$wshShell.Popup($_.Exception.ToString(), 0, "Error", 0)
$wshShell = $null
}
finally
{
if ($wdDocument)
{
$wdDocument.Close([ref]$doNotSaveChanges)
$wdDocument = $null
}
if ($wdApplication)
{
$wdApplication.Quit()
$wdApplication = $null
}
[GC]::Collect()
[GC]::WaitForPendingFinalizers()
}
}
$FullInput = (Get-Item ${DocInput}).FullName
# http://stackoverflow.com/questions/3038337/powershell-resolve-path-that-might-not-exist
$FullOutput = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(${PdfOutput})
Write-Host "Converting ${FullInput} to ${FullOutput}..."
WordToPdf ${FullInput} ${FullOutput}
@mkoertgen
Copy link
Author

Usage: On the command line prompt, type

powershell -f doc2pdf.ps1 <your word file.docx>

You need to have Microsoft Word installed, though.

@mkoertgen
Copy link
Author

Sometimes you want to use Create bookmarks using headings.

You can do this by

$wdCreateBookmarks = [Microsoft.Office.Interop.Word.WdExportCreateBookmarks]::wdExportCreateHeadingBookmarks

See WdExportCreateBookmarks Enumeration (MSDN, Office 2010)

@mkoertgen
Copy link
Author

Note that the default is to export only document content leaving out comments, i.e.

$wdExportItem = [Microsoft.Office.Interop.Word.WdExportItem]::wdExportDocumentContent

If you want to include markup, comments, etc. use

$wdExportItem = [Microsoft.Office.Interop.Word.WdExportItem]::wdExportDocumentWithMarkup

See:

@mkoertgen
Copy link
Author

Default is 'optimized for screen'. For 'print' use

$wdExportOptimizeFor = [Microsoft.Office.Interop.Word.WdExportOptimizeFor]::wdExportOptimizeForPrint

See:

@cvisigalli
Copy link

Good ps script. A question: It works if I run the .bat or .ps1 directly on the Windows Server 2019 with Office 2016 installed but it does not complete (winword is executed) if I try to run it from another machine (Ubuntu) in ssh. I've installed on Windows the app OpenSSH SSH server and I'm able to run remotely a simple .bat that copies a file. I've enable PowerShell loggin but no errors are logged, just the start of the script. Any idea? Thanks a lot.

@dcazacu21
Copy link

Great Script. I am running it fine locally, even if I start cmd as a service account. However, if I am using an automation solution (RPA) which is running as the service account (service installed in windows) it will simply get stuck. I can't capture stderr either so I don't know how to troubleshoot it. Any pointers on how I could troubleshoot this? Would be very happy making it work after 2 weeks of pulling my hair out 👍

@mkoertgen
Copy link
Author

Hi @dcazacu21,

Service Account will probably run headless. I am not sure that this kind of Excel automation will work in this context.

@dcazacu21
Copy link

Hi mkoertgen, thank you very much for your reply! We actually made the script running by making sure in C:\windows\system32\config\systemprofile we have a folder called Desktop.

I think this is because most likely the script is being ran as system account? (correct me if I'm wrong).

It seems the script is running fine now, so thank you very much for this one, it's great!

I am now in talks with support for the RPA solution we use as it seems it is issuing commands now as system, instead of our service account. Don't know why but I hope the will tell me.

Thank you again for your work! very good script

@dcazacu21
Copy link

Hi mkoerthen, I have another question related to this script. Is there such a granularity where we can export documents with markups, but not include comments and formatting?

Or is there a possibility to include a macro in your script which would hide comments and formatting?

Thanks in advance!
Dan

@XianhuaZeng
Copy link

Hi @mkoertgen,

Is there a option to have all bookmarks collapsed in the resulting PDF?

Thanks,
Xianhua

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment