Using HTML to create PDF Reports (Part 3)

by Oct 11, 2022

 HTML can be a simple way of formatting data for output reports. In this last part we illustrate how you convert the final HTML report to PDF so you can easily pass it on to colleagues and team members.

Here is the script where we left part 2:

$path = "$env:temp\report.html"

# get data from any cmdlet you wish
$data = Get-Service | Sort-Object -Property Status, Name

# helper function to convert arrays to string lists
function Convert-ArrayToStringList
        [Parameter(Mandatory, ValueFromPipeline)]
        $Property = $PipelineObject.psobject.Properties | 
                        Where-Object { $_.Value -is [Array] } | 
                        Select-Object -ExpandProperty Name
        foreach ($item in $Property)
            $PipelineObject.$item = $PipelineObject.$item -join ','

        return $PipelineObject

# compose style sheet
$stylesheet = "
    body { background-color:#AAEEEE;
    font-size:10pt; }
    table,td, th { border:1px solid blue;}
    th { color:#00008B;
    font-size: 12pt;}
    table { margin-left:30px; }
    h2 {

# output to HTML
$data | 
# make sure you use Select-Object to copy the objects
Select-Object -Property * |
Convert-ArrayToStringList |
ConvertTo-Html -Title Report -Head $stylesheet | 
Set-Content -Path $path -Encoding UTF8

Invoke-Item -Path $path

The result is a HTML report located in the file location specified in $Path. Now what’s missing is a way to convert the HTML file to a PDF file.

There are many routes to achieve this yet one of the most convenient comes with the Chrome browser. For the conversion to work, though, you need to install the Chrome browser (if you haven’t done so already).

Here is the final code that takes an existing HTML file and converts it to PDF:

# path to existing HTML file
$path = "$env:temp\report.html"

# determine installation path for Chrome
$Chrome = ${env:ProgramFiles(x86)}, $env:ProgramFiles |
ForEach-Object { "$_\Google\Chrome\Application\chrome.exe" } |
Where-Object { Test-Path -Path $_ -PathType Leaf } |
Select-Object -First 1
if ($Chrome.Count -ne 1) { throw "Chrome not installed." }
# compose destination path by changing file extension to PDF
$destinationPath =  [System.IO.Path]::ChangeExtension($Path, '.pdf')

# doing the conversion 
& $Chrome --headless --print-to-pdf="$destinationPath" "$Path"

# (this is async so it may take a moment for the PDF to be created)
    Write-Host '.' -NoNewline
    Start-Sleep -Seconds 1
} Until (Test-Path -Path $destinationPath)

Invoke-Item -Path $destinationPath

Twitter This Tip! ReTweet this Tip!