Kae Travis

Generate a PDF using PowerShell and Microsoft Edge

Posted on by in PowerShell
Tags:

Here we describe how to generate a PDF using PowerShell and Microsoft Edge.

It’s been a while since i knocked this script up, but i recall having issues printing to the PDF printer using System.Drawing.Printing.PrintDocument . It required creating a handler and calculating document dimensions etc. It seemed like too much faff for what should really be a trivial task.

Since I have a background in web technologies I thought about generating some HTML and converting it to a PDF instead. And luckily, Microsoft Edge has a parameter to do just that!

Try running this:

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --print-to-pdf=c:\alkane\alkane.pdf --disable-extensions --print-to-pdf-no-header --disable-popup-blocking --run-all-compositor-stages-before-draw --disable-checker-imaging https://www.google.co.uk

This will generate a PDF of the Google homepage and write it to c:\alkane\alkane.pdf ! We can obviously take this a step further by generating our own HTML locally (for a bespoke report, for example) and creating a PDF from that instead!


$reportPath = "c:\alkane\"
$reportname = "alkanereport"
$htmlPath = "$reportPath$reportname.html"
$pdfPath = "$reportPath$reportname.pdf"
if (test-path $pdfPath) {
remove-item $pdfPath -Force
}
if (test-path $htmlPath) {
remove-item $htmlPath -Force
}
#Create sample data
$people = @()
$obj = New-Object PSObject                
$obj | Add-Member -MemberType NoteProperty -Name "Name" -Value "John"
$obj | Add-Member -MemberType NoteProperty -Name "Age" -Value "51"
$obj | Add-Member -MemberType NoteProperty -Name "Gender" -Value "Male"
$people += $obj
$obj = New-Object PSObject                
$obj | Add-Member -MemberType NoteProperty -Name "Name" -Value "Carol"
$obj | Add-Member -MemberType NoteProperty -Name "Age" -Value "36"
$obj | Add-Member -MemberType NoteProperty -Name "Gender" -Value "Female"
$people += $obj
$obj = New-Object PSObject                
$obj | Add-Member -MemberType NoteProperty -Name "Name" -Value "Laura"
$obj | Add-Member -MemberType NoteProperty -Name "Age" -Value "26"
$obj | Add-Member -MemberType NoteProperty -Name "Gender" -Value "Female"
$people += $obj
$obj = New-Object PSObject                
$obj | Add-Member -MemberType NoteProperty -Name "Name" -Value "Peter"
$obj | Add-Member -MemberType NoteProperty -Name "Age" -Value "72"
$obj | Add-Member -MemberType NoteProperty -Name "Gender" -Value "Male"
$people += $obj
#Generate HTML for PDF
$html = "<html<head>"
$html = $html + "<style>"
$html = $html + "body {"
$html = $html + "    font-family:arial;"
$html = $html + "    font-size:14px;"
$html = $html + "    margin:0px;"
$html = $html + "}"
$html = $html + "table, th, td {"
$html = $html + "    font-size:14px;"
$html = $html + "    border: 1px solid black;"
$html = $html + "    border-collapse: collapse;"
$html = $html + "    text-align:center;"
$html = $html + "    padding: 5px 40px 5px 40px;"
$html = $html + "}"
$html = $html + "th {"
$html = $html + "    background-color: #618a2a;"
$html = $html + "    color: #fff;"
$html = $html + "}"
$html = $html + ".header {"
$html = $html + "    text-align:left;"
$html = $html + "    background-color: #618a2a;"
$html = $html + "}"
$html = $html + ".red {"
$html = $html + "    background-color: red;"
$html = $html + "}"
$html = $html + ".wrapper {"
$html = $html + "    margin:20px;"
$html = $html + "}"
$html = $html + ".logo {"
$html = $html + "    height: 40px;"
$html = $html + "    margin: 20px 0px 20px 20px;"
$html = $html + "}"
$html = $html + "p {"
$html = $html + "    margin: 0px 0px 30px 0px;"
$html = $html + "}"
$html = $html + "</style>"
$html = $html + "</head><body>"
$html = $html + "<div class='header'>"
$html = $html + "<img class='logo' src='data:image/png;base64,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'/>"
$html = $html + "</div>"
$html = $html + "<div class='wrapper'>"
$html = $html + "<h1>Monthly Report</h1>"
$html = $html + "<p>Please find below your report.</p>"
$html = $html + "<table>"
$html = $html + "<tr><th>Name</th><th>Age</th><th>Gender</th></tr>"
foreach($person in $people) {
$html = $html + "<tr>"
$html = $html + "<td>" + $person.Name + "</td>"
$html = $html + "<td>" + $person.Age + "</td>"
$html = $html + "<td>" + $person.Gender + "</td>"
$html = $html + "</tr>"
}
$html = $html + "</div>"
$html = $html + "</table></body></html>"
$html | Out-File $htmlPath -Force
Start-Process "msedge.exe" -ArgumentList @("--headless","--print-to-pdf=""$pdfPath""","--disable-extensions","--print-to-pdf-no-header","--disable-popup-blocking","--run-all-compositor-stages-before-draw","--disable-checker-imaging", "file:///$htmlPath")
#wait for PDF creation
while (!(Test-Path $pdfPath)) { Start-Sleep 2 }
#remove HTML file
if (test-path $htmlPath) {
remove-item $htmlPath -Force
}
#open PDF
Start-Process $pdfPath

The above example creates some sample data (an array of people’s name, age and gender), writes it to a HTML file with custom CSS styling, generates a PDF from the HTML file using Microsoft Edge, and then removes the HTML file.

Generate a PDF using PowerShell and Microsoft Edge
Generate a PDF using PowerShell and Microsoft Edge

Leave a Reply