Creating a Table of Contents in Word Using PowerShell

Continuing on from my last article, this one will show you how to build a Table of Contents in Word using PowerShell. We will be using the same techniques and some of the same code to set up our word document and I will be pointing out some areas of interest that will be used to help create a table of contents.

First off, let’s go ahead and get our Word object ready to go:

 
$Word = New-Object -ComObject Word.Application
$Word.Visible = $True
$Document = $Word.Documents.Add()
$Selection = $Word.Selection
New-WordText -Text "$($Env:Computername)" -Style 'Title'
New-WordText -Text "Report compiled at $(Get-Date)."

image

The New-WordText is not a built-in function or cmdlet that you can use natively in PowerShell. It is simply a helper function that I have in a different script that works well for what I want to do here. The source code for it is here:

 
Function New-WordText {
    Param (
        [string]$Text,
        [int]$Size = 11,
        [string]$Style = 'Normal',
        [Microsoft.Office.Interop.Word.WdColor]$ForegroundColor = "wdColorAutomatic",
        [switch]$Bold,
        [switch]$Italic,
        [switch]$NoNewLine
    )  
    Try {
        $Selection.Style = $Style
    } Catch {
        Write-Warning "Style: `"$Style`" doesn't exist! Try another name."
        Break
    }

    If ($Style -notmatch 'Title|^Heading'){
        $Selection.Font.Size = $Size  
        If ($PSBoundParameters.ContainsKey('Bold')) {
            $Selection.Font.Bold = 1
        } Else {
            $Selection.Font.Bold = 0
        }
        If ($PSBoundParameters.ContainsKey('Italic')) {
            $Selection.Font.Italic = 1
        } Else {
            $Selection.Font.Italic = 0
        }          
        $Selection.Font.Color = $ForegroundColor
    }

    $Selection.TypeText($Text)

    If (-NOT $PSBoundParameters.ContainsKey('NoNewLine')) {
        $Selection.TypeParagraph()
    }
}

Using this function will make writing text to the word document simpler and save on code later on. With this done, now we can focus on building out the Table of Contents in the word document. Because I want this to be at the front of the document, I need to build it out now rather than later on in the document or after I am finished.

In order to do this I will be using the $Document.TablesOfContents.Add() method which has a single required parameter: Range and several other optional parameters that you can supply if you want extra configuration of the table of contents. For more information, you can check out the Add() method information here. I won’t be using any of those here and will just focus on the default configuration of the table of contents so only the Range is important to me. The range is nothing more than a selection of where I want the table of contents to be at.  Speaking of the range, I can pull that information by using the following code:

 
$range = $Selection.Range

With that out of the way, I can now create the table of contents. When I do this, I need to keep the resulting object that is outputted when using the Add() method.

 
$toc = $Document.TablesOfContents.Add($range)
$Selection.TypeParagraph()

image

Nothing to worry about here. This is just letting use know that while the table of contents has been created, we haven’t actually defined anything  that should appear there yet. That will change shortly as we begin adding data to the word document.

A quick view of the table of contents object shows some nice information such as the Update() method. This may be useful at some point in time to us.

image

Moving on, we now need to set up a way to have specific items appear in the table of contents. But what do we need to do in order for this to happen? The answer lies in the Heading style that exists in Word. Depending on your Word configuration, you may have a set number of heading styles available to use. In my case, I have quite a few.

image

I actually have 6 heading styles but the other one is on the second row. Regardless of that, I now know what I can work with in my document and at the end, we can see how this affects the table of contents.

With that, I am going to randomly create some heading styles with random values so we can have some data available.

 
For($i=0;$i-lt 8;$i++) {
    New-WordText -Text "Main Heading $i" -Style 'Heading 1'
    For($i=0;$i-lt 8;$i++) {
        New-WordText -Text "Secondary Heading $i" -Style 'Heading 2'
        For($i=0;$i-lt 8;$i++) {
            New-WordText -Text "Third Heading $i" -Style 'Heading 3'
        }
    }
}

Now I have about 5 pages of useless information in my document! Now comes the fun part where I tell the table of contents to update itself based on all of the heading information and see what happens!

 
$toc.Update()

You won’t actually see anything return after you run this, so it is assumed that if no errors occurred, then it at least made the attempt to catalog all of the heading styles and constructed a table of contents. In this case, it worked like a champ and we can now see the table of contents listed at the top of the document.

image

I have truncated the rest of the output shown here as it spans a couple of pages to support the five pages of heading information, but you can get the idea of what it can do. This provides a great way to add some additional configuration to a report that is generated via a script which is especially useful if you have large amounts of data that covers a lot of pages and helps whoever views it to navigate more quickly to the information that they may need to see.

Hopefully you find this information useful in your future Word reporting needs!

This entry was posted in powershell and tagged , , , . Bookmark the permalink.

1 Response to Creating a Table of Contents in Word Using PowerShell

  1. Babu says:

    Hi Boe,
    In excel, how to do this. Getting all the sheet names as Index page with hyperlink to that individual page.

    Thanks,
    Babu

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s