TOC with Page Numbers

We have a merged document. I’m trying to put a TOC into the first page and add Page numbers.
Below is my code, the TOC prints but after the TOC it prints it again but in Heading style and the Page Numbers don’t print (I know the code works for a single file). Can you answer these questions with examples please.

  1. How do I remove the header for the TOC pages?
  2. Is there a way I can get the page count for each of the documents so I can put that into the TOC.
  3. How to get the page numbers to work.
    It prints out like
    A …1
    B…1
    C …1
    Then again in header style format without the …1
    Code:
Dim strFileName As String
Dim fileDirectory As String = getSharedPath(Session("ID"), True)
Dim wordFiles As String() = Directory.GetFiles(fileDirectory, "*.docx")
Dim strReportName As String
Dim strReportName2 As String
Dim combineDocName As String
Dim i As Integer
Dim mCount As Integer = 1
'See what format and file to put TOC and PN in
If bPDF Then
    strFileName = "rpt.pdf"
    combineDocName = Path.Combine(fileDirectory, strFileName)
Else
    strFileName = "rpt.docx"
    combineDocName = Path.Combine(fileDirectory, strFileName)
End If
'Create Aspose Doc Object
Dim doc As New Aspose.Words.Document(combineDocName)
Dim builder As New DocumentBuilder(doc)
'Put Toc in First Paragraph
doc.FirstSection.Body.PrependChild(New Aspose.Words.Paragraph(doc))
' Insert a table of contents at the beginning of the doc
builder.MoveToDocumentStart()
'Make it the currect section
Dim currentSection As Aspose.Words.Section = builder.CurrentSection
'Put in TOC
builder.InsertTableOfContents("\o ""1-3"" \h \z \u")
'Get all the file names from the list of documents in the direcotory
For i = 0 To wordFiles.Length - 1
    strReportName = wordFiles(i).Substring(wordFiles(i).LastIndexOf("\") + 1)
    strReportName = strReportName.Substring(0, strReportName.LastIndexOf("."))
    strReportName2 = strReportName.Substring(strReportName.IndexOf("_") + 1)
    If strReportName.ToUpper.IndexOf("rpt") = -1 Then
        builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1
        builder.Writeln(strReportName2 + " " + mCount.ToString())
        mCount = mCount + 1
    End If
Next
'After finishing put a break in
builder.InsertBreak(BreakType.PageBreak)
'Put in Page Numbers
doc.FirstSection.PageSetup.SectionStart = SectionStart.Continuous
doc.FirstSection.PageSetup.RestartPageNumbering = 1
doc.FirstSection.HeadersFooters.LinkToPrevious(False)
builder.RowFormat.Alignment = Tables.RowAlignment.Right
builder.MoveToDocumentEnd()
builder.MoveToHeaderFooter(Aspose.Words.HeaderFooterType.FooterPrimary)
builder.Write("Page: ")
builder.InsertField("PAGE", "")
builder.Write(" of ")
builder.InsertField("NUMPAGES", "")
builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right
doc.UpdateFields()
doc.UpdatePageLayout()
doc.Save(combineDocName)

Hi Jon,

Thanks for your inquiry.

*jtingres:

  1. How do I remove the header for the TOC pages?*

HeaderFooter is a section-level node and can only be a child of Section. There can only be one HeaderFooter or each HeaderFooterType in a Section. Please read following documentation links for your kind reference.

Please insert the Section Break of type NewPage after inserting TOC field instead of page break and remove header/footers of first section of document.

jtingres:
2. Is there a way I can get the page count for each of the documents so I can put that into the TOC.

Document.PageCount Property gets the number of pages in the document as calculated by the most recent page layout operation. It would be great if you please share some more detail about this query.

jtingres:
3. How to get the page numbers to work.

It would be great if you please share following detail for investigation purposes. We will then provide you more information about your query along with code.

  • Please supply us with the input document that is causing the issue (merged document)
  • Please supply us with the output document showing the undesired behavior
  • Please supply us with the expected document showing the desired behavior (You can create this document using Microsoft Word).

I’m still trying to get the final lay out for the TOC but having problems with the Page numbers. I put the page numbers on each individual document, then I combine the document without calling the Page Number code, it sets the Page numbers for the entire document. Say document A is 10 pages, B is 7 and C is 5. I’ll have a combined document of 22 pages when I don’t want it to set the page numbers for the combined document just use the page numbers on the documents that are all ready set. What is weird is when I open the combined document it works for the first page initially then once I go to the second page it resets the page number for the whole document. Were using 13.7.My code is below.

Function MergeWord2() As Boolean
    If Session("AUTO_REFRESH") = "OFF" Then Return True
    Dim fileDirectory As String = getSharedPath(Session("User_ID"), True)
    Dim wordFiles As String() = Directory.GetFiles(fileDirectory, "*.docx")
    Dim i As Integer
    Dim d As Integer = 0
    Dim filename, combineDocName As String
    combineDocName = Path.Combine(fileDirectory, "MERGED_REPORT.docx")
    Dim dstDoc As Aspose.Words.Document
    Dim builder As Aspose.Words.DocumentBuilder
    Dim bAddPageNum As Boolean
    Try
        Array.Sort(wordFiles)
        For i = 0 To wordFiles.Length - 1
            'Add Page Numbers
            If wordFiles(i).IndexOf("MERGED") = -1 Then
                bAddPageNum = AddPageNum(wordFiles(i))
            End If
            'The document that the content will be appended to.
            If i = 0 Then
                dstDoc = New Aspose.Words.Document(wordFiles(i))
            Else
                'The document to append.
                Dim srcDoc As Aspose.Words.Document = New Aspose.Words.Document(wordFiles(i))
                'Append the source document to the destination document.
                'Pass format mode to retain the original formatting of the source document when importing it.
                builder = New Aspose.Words.DocumentBuilder(dstDoc)
                builder.MoveToDocumentEnd()
                builder.InsertBreak(BreakType.PageBreak)
                srcDoc.FirstSection.PageSetup.RestartPageNumbering = False
                dstDoc.AppendDocument(srcDoc, ImportFormatMode.KeepSourceFormatting)
            End If
            If i = wordFiles.Length - 1 Then
                'Save the document.
                dstDoc.Save(combineDocName)
            End If
        Next
    Catch ex As Exception
        Throw New Exception(ex.Message, ex.InnerException)
        Return False
    End Try
End Function
Function AddPageNum(ByVal strFileName As String) As Boolean
    Try
        Dim strReportName As String
        strReportName = strFileName.Substring(strFileName.LastIndexOf("\") + 1)
        strReportName = strReportName.Substring(0, strReportName.LastIndexOf("."))
        strReportName = strReportName.Substring(strReportName.IndexOf("_") + 1)
        strReportName = strReportName.Replace("_", " ")
        Dim doc As New Aspose.Words.Document(strFileName)
        'Page Numbers Add
        Dim builder As New DocumentBuilder(doc)
        ' Set the appended document to appear on a new page.
        doc.FirstSection.PageSetup.SectionStart = SectionStart.Continuous
        doc.FirstSection.PageSetup.RestartPageNumbering = 1
        ' Link the headers and footers in the source document to the previous section.
        ' This will override any headers or footers already found in the source document.
        doc.FirstSection.HeadersFooters.LinkToPrevious(False)
        builder.RowFormat.Alignment = Tables.RowAlignment.Right
        'dstDoc.AppendDocument(doc, ImportFormatMode.KeepSourceFormatting)
        builder.MoveToDocumentEnd()
        builder.MoveToHeaderFooter(Aspose.Words.HeaderFooterType.FooterPrimary)
        'builder.Write("Page: " + strReportName + " - ")
        builder.Write(strReportName + ": ")
        builder.InsertField("PAGE", "")
        builder.Write(" of ")
        builder.InsertField("NUMPAGES", "")
        builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right
        doc.Save(strFileName)
    Catch ex As Exception
        Throw New Exception(ex.Message, ex.InnerException)
        Return False
    End Try
    Return True
End Function

Hi Jon,

Thanks for sharing the detail. Unfortunately, it is difficult to say what the problem is without the documents. Please create a simple application (for example a Console Application Project) that helps us reproduce the same problem on our end and attach it here for testing. Unfortunately, it is difficult to say what the problem is without the Document(s) and simplified application. We need your Document(s) and simple project to reproduce the problem. Please also share your expected output document. I suggest you please read following documentation link for your kind reference.

https://docs.aspose.com/words/net/working-with-fields/

As soon as you get these pieces of information to us we’ll start our investigation into your issue.

Okay,
I think I got the page numbers figure out. But having problems creating a TOC. Below is the code I’m using and attached is the document I’m trying to put the TOC on. It keeps saying no TOC fields found. It should look like the example page attached. I’m trying to see about getting the large text that is in the header that is Bolded. Help would be appreciated

Function CreateTOC()
    Dim strFileName, combineDocName As String
    Dim fileDirectory As String = getSharedPath(Session("User_ID"), True)
    'Dim i As Integer
    'Dim mCount As Integer = 1
    strFileName = "MERGED_REPORT_NoTOC.docx"
    'Get File from Directory
    combineDocName = Path.Combine(fileDirectory, strFileName)
    Dim doc As Aspose.Words.Document = New Aspose.Words.Document(combineDocName)
    Dim builder As New DocumentBuilder(doc)
    doc.FirstSection.Body.PrependChild(New Aspose.Words.Paragraph(doc))
    ' Insert a table of contents at the beginning of the doc
    builder.MoveToDocumentStart()
    'TOC values I've tried to use
    'builder.InsertTableOfContents("\\o \""1-3\"" \\n \\h \\z \\u")
    'builder.InsertTableOfContents("\\t ""NavBar,1,HeaderBar,2"" \\h \\z \\u")
    builder.InsertTableOfContents("\\o \\h \\z \\u")

    builder.InsertBreak(BreakType.PageBreak)
    doc.UpdateFields()
    'doc.UpdatePageLayout()
    doc.Save(combineDocName)
End Function

Hi Jon,

Thanks for sharing the detail. Please note that Aspose.Words mimics the same behavior as MS Word do. If you try to insert the TOC field in your documents by using MS Word, you will get the same output. In your case, MS Word shows the attached informational message (Apply a heading style from the Styles gallery on the Home tab).

However, you can build table of contents from the styles exists in your document. I have used 'Table Title’ and ‘Heading 01’ styles from your document to build TOC. Please use the following line of code to insert TOC filed in your document. You can use the styles according to your requirement in InsertTableOfContents method. Hope this helps you. Please let us know if you have any more queries.

builder.InsertTableOfContents(@"TOC \h \z \t ""Table Title,2,Heading 01,1""");

Thanks, but still can’t it to work. I’m trying to get the value in the header which would be something like this:
builder.InsertTableOfContents("TOC \h \z \t ““Header Bar,2,Navigation Bar,1"””)
Which is the Header in the attached document. Trying to get the big header style as the value which is Header Bar. See the attached example which says it couldn’t create the TOC.
Also I see that it using the page index, can it get the actual page# which is at the bottom of the page.
If this isn’t possible is there a way I can loop through the document, read the header get that style value, then read the footer read that page num value. Put that into a table and insert that as the TOC?

Hi Jon,

Thanks for sharing the detail. You can build table of contents from the styles which exist in your document. I used 'Table Title’ and ‘Heading 01’ styles from your document to build TOC.

Please share your input and excepted output document here for our reference. Please manually create your expected Word document using Microsoft Word and attach it here for our reference. We will investigate, how you want your final Word output be generated like. We will then provide you more information on this along with code.

I already put the expected output (TOC) in my 498134 reply to show the expected output is TOC Example.docx . My previous post jas MERGED_REPORT-asposenowork.docx is what I got (the output document), just delete that first page to try to get the TOC again if needed (then this will be the new input documet). Let me know if you have any more questions. Is there a way to loop through each header and footer of each page of the document. If so how, since I tried below but it didn’t work.

Dim doc As Aspose.Words.Document = New Aspose.Words.Document(combineDocName)
For Each section As Aspose.Words.Section In doc.Sections
    'section.HeadersFooters()
    Dim header As Aspose.Words.HeaderFooter
    Dim footer As Aspose.Words.HeaderFooter
    header = section.HeadersFooters(Aspose.Words.HeaderFooterType.HeaderFirst)
    footer = section.HeadersFooters(Aspose.Words.HeaderFooterType.FooterFirst)
Next
  1. I want to read the Header and Footer text for each page of document
  2. For the header I want to see what style it is (should be two parts to the header with NavigationBar and HeaderBar styles)

Thanks,JT

Hi Jon,

Thanks for your inquiry.

1. I want to read the Header and Footer text for each page of document

Please note that HeaderFooter is a section-level node not page level and can only be a child of Section. There can only be one HeaderFooter or each HeaderFooterType in a Section. If Section does not have a HeaderFooter of a specific type or the HeaderFooter has no child nodes, this header/footer is considered linked to the header/footer of the same type of the previous section in Microsoft Word.

When HeaderFooter contains at least one Paragraph, it is no longer considered linked to previous in Microsoft Word.

Document doc = new Document(MyDir + "in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
foreach (Section section in doc.Sections)
{
    foreach (HeaderFooter hf in section.HeadersFooters)
    {
    }
}
doc.Save(MyDir + "out.docx");

2. For the header I want to see what style it is (should be two parts to the header with NavigationBar and HeaderBar styles)

Please use the following code snippet to get the Paragraphs’s style name of Primary header of each section. Hope this helps you.

Document doc = new Document(MyDir + "in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
foreach (Section section in doc.Sections)
{
    foreach (HeaderFooter hf in section.HeadersFooters)
    {
        if (hf.HeaderFooterType == HeaderFooterType.HeaderPrimary)
        {
            foreach (Paragraph para in hf.Paragraphs)
            {
                if (para.ToString(SaveFormat.Text).Trim() != "")
                {
                    MessageBox.Show(para.ToString(SaveFormat.Text).Trim() + " Style : " + para.ParagraphFormat.StyleName);
                }
            }
        }
    }
}
doc.Save(MyDir + "out.docx");

You can also insert the bookmarks at the start of each section and create hyperlinks to each bookmark by using following code snippet.Please write the hyperlinks text according to your requirement. Hope this helps you. Please let us know if you have any more queries.

int i = 0;
Document doc = new Document(MyDir + "MERGED_REPORT_NoTOC.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
foreach (Section section in doc.Sections)
{
    builder.MoveTo(section.Body.FirstParagraph);
    builder.StartBookmark("Bm" + i);
    builder.Write("Bm" + i);
    builder.EndBookmark("Bm" + i);
    i++;
}
builder.MoveToDocumentStart();
foreach (Bookmark bm in doc.Range.Bookmarks)
{
    // Specify font formatting for the hyperlink.
    builder.Font.Color = Color.Blue;
    builder.Font.Underline = Underline.Single;
    // Insert hyperlink.
    // Switch \o is used to provide hyperlink tip text.
    builder.InsertHyperlink("Hyperlink Text", @"" + bm.Name + @"", true);
    builder.Writeln("");
}
// Clear hyperlink formatting.
builder.Font.ClearFormatting();
doc.Save(MyDir + "out.docx");

Thanks that helped. I’m getting the header as I want. But the footer is not coming. In the below code,
when it get’s the header, the footer primary is the second page of the document. I want to get the page number on the bottom for every new instance of a header. Can you help. Also where is an example to do a manuel TOC from the datatable I created?

Dim strFileName, combineDocName As String
Dim bAddRow As Boolean
Dim HeaderTxt, HeaderTxt2, FooterTxt As String
Dim fileDirectory As String = getSharedPath(Session("User_ID"), True)
strFileName = "MERGED_REPORT.docx"
combineDocName = Path.Combine(fileDirectory, strFileName)
Dim dt As New DataTable()
Dim iCount, iOrder As Integer 'count occurences of :
dt.TableName = "AcceptedMilestone"
Dim dtcol As New DataColumn()
dtcol.DataType = Type.[GetType]("System.String")
dtcol.ColumnName = "Header"
dt.Columns.Add(dtcol)
dtcol = New DataColumn()
dtcol.DataType = Type.[GetType]("System.String")
dtcol.ColumnName = "Page"
dt.Columns.Add(dtcol)
dtcol = New DataColumn()
dtcol.DataType = Type.[GetType]("System.String")
dtcol.ColumnName = "Level"
dt.Columns.Add(dtcol)
dtcol = New DataColumn()
dtcol.DataType = Type.[GetType]("System.String")
dtcol.ColumnName = "Order"
dt.Columns.Add(dtcol)
Dim doc As Aspose.Words.Document = New Aspose.Words.Document(combineDocName)
Dim builder As New DocumentBuilder(doc)
iOrder = 0
For Each section As Aspose.Words.Section In doc.Sections
    For Each hf As Aspose.Words.HeaderFooter In section.HeadersFooters
        'Get Header info for the two header types if available
        If hf.HeaderFooterType = Aspose.Words.HeaderFooterType.HeaderPrimary Then
            For Each para As Aspose.Words.Paragraph In hf.Paragraphs
                If para.ToString(SaveFormat.Text).Trim() <> "" Then
                    iCount = para.ToString(SaveFormat.Text).Trim.Split(":").Length - 1
                    Dim style As String = para.ParagraphFormat.StyleName
                    If style = "Header Bar" Then
                        HeaderTxt = para.ToString(SaveFormat.Text).Trim()
                    End If
                    If style = "Navigation Bar" Then
                        HeaderTxt2 = para.ToString(SaveFormat.Text).Trim()
                    End If
                End If
            Next
        End If
        'Get the page number
        If hf.HeaderFooterType = Aspose.Words.HeaderFooterType.FooterPrimary Then
            For Each para2 As Aspose.Words.Paragraph In hf.Paragraphs
                FooterTxt = para2.ToString(SaveFormat.Text).Trim()
            Next
            'Set the order and can add now
            iOrder = iOrder + 1
            bAddRow = True
        End If
        'Add to datatable to build TOC
        If (bAddRow) Then
            Dim dtrow As DataRow
            dtrow = dt.NewRow()
            dtrow("Header") = IIf(iCount = 0, HeaderTxt, HeaderTxt2)
            dtrow("Page") = FooterTxt
            dtrow("Level") = iCount
            dtrow("Order") = iOrder
            dt.Rows.Add(dtrow)
            bAddRow = False
            HeaderTxt = Nothing
            HeaderTxt2 = Nothing
            FooterTxt = Nothing
        End If
    Next
Next

Hi Jon,

Thanks for your inquiry.

*jtingres:

I want to get the page number on the bottom for every new instance of a header.*

Please note that HeaderFooter is a section-level node not page level and can only be a child of Section. One section may contain one ore more pages. There can only be one HeaderFooter or each HeaderFooterType in a Section.MS Word document is flow document and does not contain any information about its layout into lines and pages. Therefore, technically there is no “Page” concept in Word document. Pages are created by Microsoft Word on the fly.
Aspose.Words uses our own Rendering Engine to layout documents into pages. Please check using the DocumentLayoutHelper sample from the offline samples pack. This sample demonstrates how to easily work with the layout elements of a document and access the pages, lines, rows, spans etc.

*jtingres:

Can you help. Also where is an example to do a manuel TOC from the datatable I created?*

Please check the third example share at this post. You can use the same approach to insert hyperlinks after reading contents from your database. If this does not help you, please share some more detail about your query. We will then provide you more information about your query along with code.

Thanks I’ll look at it. How does the last example show me how to build a TOC manually. Do you have an example on how to build a manuel TOC for the document?
JT

Hi Jon,

Thanks for your inquiry. Please note that Aspose.Words mimics the same behavior as MS Word do. If you try to insert the TOC field in your documents by using MS Word, you will get the same output.

Firstly, I suggest you please read following web link for your kind reference.
http://office.microsoft.com/en-001/word-help/create-a-table-of-contents-or-update-a-table-of-contents-HP010368778.aspx

The third example at following post inserts bookmarks at the start of each section of document. After inserting bookmarks that code example inserts hyperlinks to bookmarks at the start of document. You can modify hyperlink’s text according to your requirements.
https://forum.aspose.com/t/50581

You can create TOC by using styles exist in your document. I have already explain this at my post here:
https://forum.aspose.com/t/50581

Hope this answers your query. Moreover, as requested earlier, please manually create your expected Word document using Microsoft Word. Please insert the TOC at the start of your input document and attach it here for our reference. We will investigate, how you want your final Word output be generated like. We will then provide you more information on this along with code.