Get page number from footer and Append to Barcode

I have an application where I need to append the page number to an Aspose barcode. Below is the code I am using. The PageNum.Result is not returning values. Do you have a recommendation how I can get the page number from the footer so I can append it to the bar code?

Dim PageNum As Field = builder.InsertField("PAGE * MERGEFORMAT")

’ Update this particular field in the document so we can get the FieldResult.
PageNum.Update()

Dim bb As BarCodeBuilder = New BarCodeBuilder()
bb.CodeText = "1234567_" & PageNum.Result
bb.SymbologyType = Symbology.Code128
Dim mStream As System.IO.MemoryStream = New System.IO.MemoryStream()
bb.BarCodeImage.Save(mStream, System.Drawing.Imaging.ImageFormat.Png)
Dim bmpImage As System.Drawing.Bitmap = bb.BarCodeImage
builder.InsertImage(bmpImage)

Hi Jim,
Thanks for your inquiry.
Most likely this issue is occuring because you cannot get the page number from a field in the header or footer, it will always return the same value as the total number of pages.
You could instead try using the field in the body and see if that returns the value you are looking for.
Thanks,

I am still not able to get the page number. I tried getting it from the body. Obviously I am doing something wrong. Would you have a code snippet that shows how I might retrieve the page number from the body?

Thanks!

Hi

Thanks for your inquiry. I think, you can achieve what you need using code suggested by Adam in the following thread:
https://forum.aspose.com/t/65265
You should just using this code to get number of page where DocumentBuidler cursor is located and them insert this page number in your barcode.
Also, it would be great if you show us your current output and the expected output. This will help us to better understand your requirements.
Best regards,

Here is the code that I am using. The code highlighted in red is now returning a page number but it is is just the first page number which is 1 for all pages. Attached is a screenshot of the issue. Any suggestions on how to get the page number for each page would be greatly appreciated!

Thanks!

Dim license As Aspose.Words.License = New Aspose.Words.License()
license.SetLicense("Aspose.Words.lic")
Dim rootPath As String = Server.MapPath("~")
Dim ProgresscardPath As String = rootPath & "/BubblesheetTemplates/Let Your Voice RUBRIC UPDATED 2010 BUBBLES.docx"
Dim srcDoc As Document = New Document(ProgresscardPath)

Dim pageCount As Integer = srcDoc.PageCount

For Each section As Section In srcDoc
’ Up to three different footers are possible in a section (for first, even and odd pages).
’ We check and delete all of them.
Dim footer As HeaderFooter

footer = section.HeadersFooters(HeaderFooterType.FooterFirst)
If footer IsNot Nothing Then
footer.Remove()
End If

’ Primary footer is the footer used for odd pages.
footer = section.HeadersFooters(HeaderFooterType.FooterPrimary)
If footer IsNot Nothing Then
footer.Remove()
End If

footer = section.HeadersFooters(HeaderFooterType.FooterEven)
If footer IsNot Nothing Then
footer.Remove()
End If
Next section

Dim dt As DataTable
dt = myDS.ds.Tables(0)

Dim nRow As Integer

Dim dstDoc As Document = srcDoc.Clone()

dstDoc.Sections.Clear()

Dim PageNumber As Integer = 0
Dim PrevStudentID As String = ""
For nRow = 0 To dt.Rows.Count - 1
If PrevStudentID <> dt.Rows.Item(nRow).Item("StudentID") Then
PageNumber = 1
End If

PrevStudentID = dt.Rows.Item(nRow).Item("StudentID")

Dim categoryDoc As Document = DirectCast(srcDoc.Clone(True), Document)
Dim categoryRow As DataRow

categoryRow = dt.Rows(nRow)

categoryDoc.MailMerge.Execute(categoryRow)

Dim builder As New DocumentBuilder(categoryDoc)

Dim currentSection As Section = builder.CurrentSection

Dim pageSetup As PageSetup = currentSection.PageSetup

Dim field As Field = builder.InsertField(" PAGE ")
categoryDoc.UpdatePageLayout()
Dim number As String = field.Result

pageSetup.DifferentFirstPageHeaderFooter = False
pageSetup.PageStartingNumber = 1
pageSetup.RestartPageNumbering = True

builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary)
builder.StartTable()

’ Calculate table width as total page width with left and right marins subtracted.
Dim tableWidth As Double = pageSetup.PageWidth - pageSetup.LeftMargin - pageSetup.RightMargin
builder.InsertCell()
’ Set first cell to 1/3 of the page width.
builder.CellFormat.Width = tableWidth / 3

builder.InsertField("PAGE", "")

Dim bb As BarCodeBuilder = New BarCodeBuilder()
bb.CodeText = "1234567_" & number
bb.SymbologyType = Symbology.Code128
Dim mStream As System.IO.MemoryStream = New System.IO.MemoryStream()
bb.BarCodeImage.Save(mStream, System.Drawing.Imaging.ImageFormat.Png)
Dim bmpImage As System.Drawing.Bitmap = bb.BarCodeImage
builder.InsertImage(bmpImage)

’ Align this text to the left.
builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Left
builder.InsertCell()

’ Set the second cell to 2/3 of the page width.
builder.CellFormat.Width = tableWidth * 2 \ 3

’ Align this text to the right.
builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Right
builder.EndRow()
builder.EndTable()

dstDoc.AppendDocument(categoryDoc, ImportFormatMode.UseDestinationStyles)

Next
dstDoc.Save(Response, "Test.pdf", ContentDisposition.Attachment, Nothing)

Hi Jim,
Thanks for this additional information.
The basis of your code is correct, the reason why you are getting a result of 1 every time is because you are not positioning your builder before inserting the field which means it’s inserted in the body of the first section each time. You need to move the DocumentBuilder to your barcode before inserting the field but keep in mind you cannot accomplish this correctly if the barcode is in the header or footer.
As Alexey suggested, could you attach your template and expected output here for testing? We will then provide you with some further suggestions.
Thanks,

I attached the template which has three pages and the PDF that is being generated. In the PDF, the page number that is inserted in the footer is correct however I need to get the page number in the barcode.Currently in the PDF, it always gets page number 1 in the barcode. I’m not too clear where the builder should go in order to get the correct page number appended to the barcode. Your help on this is greatly appreciated!!!

Dim dt As DataTable
dt = myDS.ds.Tables(0)

Dim nRow As Integer

Dim dstDoc As Document = srcDoc.Clone()
dstDoc.Sections.Clear()
Dim PageNumber As Integer = 0
Dim PrevStudentID As String = ""
For nRow = 0 To dt.Rows.Count - 1

Dim categoryDoc As Document = DirectCast(srcDoc.Clone(True), Document)
Dim categoryRow As DataRow

categoryRow = dt.Rows(nRow)
Dim builder As New DocumentBuilder(categoryDoc)

categoryDoc.FirstSection.PageSetup.RestartPageNumbering = True

Dim field As Field = builder.InsertField(" PAGE ")
categoryDoc.UpdatePageLayout()

Dim number As String = field.Result

Dim bb As BarCodeBuilder = New BarCodeBuilder()
bb.CodeText = "PageNumber_" & number
bb.SymbologyType = Symbology.Code128
Dim mStream As System.IO.MemoryStream = New System.IO.MemoryStream()
bb.BarCodeImage.Save(mStream, System.Drawing.Imaging.ImageFormat.Png)
Dim bmpImage As System.Drawing.Bitmap = bb.BarCodeImage

builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary)

builder.InsertImage(bmpImage)

builder.Writeln("Page Number: ")
builder.InsertField("PAGE", "")

categoryDoc.MailMerge.Execute(categoryRow)
categoryDoc.UpdateFields()
dstDoc.AppendDocument(categoryDoc, ImportFormatMode.UseDestinationStyles)

Exit For
Next
dstDoc.Save(Response, "Test.pdf", ContentDisposition.Attachment, Nothing)

Hi Jim,
Thanks for attaching your template here.
As described in the previous messages doing this is not possible inside headers or footers. Each section in a document can contain different headers and footers. Each header and footer are repeated over many pages, so you cannot find the page number of a header or footer as there is no single page number for it.
Also note due to this same behaviour it means you cannot have the same barcode in the footer displaying different text over different pages (unless you include the text in the footer instead of the barcode image itself).
There are a few solutions to what you are looking to achieve:

  1. Remove the page number from the barcode text and instead include it under the barcode in the actual footer using Aspose.Words. i.e just like how you have "Page Number: " along with the { PAGE } field right now.
  2. Make each page a different section, generate a barcode with the appropriate page number and insert it into the appropriate footer.

Thanks,

This is beginning to make sense, I really appreciate your help. I need to do #2, make each page a different section. I am struggling with how to make each page a different section. Can this be done programmatically or do the sections get manually created in the Word template? Do you have a code sample on how to do this that you could point me to?

Thanks!!!

Hi Jim,
Thanks for your inquiry.
Sure, I’m afraid since documents loaded into Aspose.Words are flow documents this means there is no easy way to find where a page starts and ends.
The easiest way to do this is to insert the section breaks manually in MS Word, however this can be done programmatically if your document is based off a general structure that you can work with.
For example, please see the code below which splits each table in the document into a new section. This appears to be the general layout of your document so hopefully you can achieve this using a technique similar to this.

Document doc = new Document("Let+Your+Voice+RUBRIC+UPDATED+2010+BUBBLES.docx");
// Clone the first section to retain formatting of the section.
Section baseSection = (Section)doc.FirstSection.Clone(true);
// Sections are to appear continuously
baseSection.PageSetup.SectionStart = SectionStart.Continuous;
// Clone children to copy over headers and footers but remove all content from the body.
baseSection.Body.RemoveAllChildren();
// All tables found in the body of the first section.
TableCollection tables = doc.FirstSection.Body.Tables;
foreach (Table table in tables.ToArray())
{
    // Move all but the first table into a new section and add this to the end of the document.
    if (tables.IndexOf(table) != 0)
    {
        Section newSection = (Section)baseSection.Clone(true);
        newSection.Body.AppendChild(table);
        doc.AppendChild(newSection);
    }
}

If you have any further inqueries, please feel free to ask.
Thanks,

I believe the best method is to insert the page breaks manually in Word to insure the breaks are occurring at the correct place. If I do this, what is the best way to identify where the page breaks are in Word?

I attached a Document Map from the Document Explorer app. Is it to iterate all the run nodes something like the following?

Dim runs As NodeCollection = srcDoc.GetChildNodes(NodeType.Run, True)
For Each run As Run In runs
If run.Text.Contains("SectionBreak") Then
Dim aaaa As String = "Found Break"
End If
Next

I tried this but it didn’t find the section break in the Word document. My thought is when the Word sectionbreak is found, insert an Aspose SectionBreak. Is this a good approach?

Thanks again!

Hi Jim,
Thanks for this additional information.
Actually in Aspose.Words a section is imported as a Section node, in which the other content is imported as children of the section. Please find further details about this in the article here. It appears from your screenshot you are inserting a page break. Are you able to structure the document in sections using MS Word first? This would avoid unneeded coding on your side.
As long as you have structured your document as sections and not with page breaks you can work with them straight away. Please see the code in this API page here which shows how to insert content into the header and footer of different sections in the document.
Thanks,

I believe I am on the right track now. I can get the barcode in each
page with the correct page number. The issue I am having is every time I
add the barcode in the footer, it keeps appending the new barcode for
all footers. Attached is an example. There should be one barcode on
each page. Here is the code I am using. How do I get each section to have its own footer with just one barcode?

Thanks!

Dim categoryDoc As Document = DirectCast(srcDoc.Clone(True), Document)
Dim PrevStudentID As String = ""

For nRow = 0 To dt.Rows.Count - 1
Dim categoryRow As DataRow
categoryRow = dt.Rows(nRow)
categoryDoc.MailMerge.Execute(categoryRow)
categoryDoc.UpdateFields()
PrevStudentID = ""
For Each section As Section In categoryDoc
If PrevStudentID <> dt.Rows.Item(nRow).Item("StudentID") Then
PageNumber = 1
End If

Dim builder As New DocumentBuilder(categoryDoc)
Dim currentSection As Section = builder.CurrentSection
currentSection = builder.CurrentSection

Dim bb As BarCodeBuilder = New BarCodeBuilder()
bb.CodeText = "PageNumber_" & PageNumber
bb.SymbologyType = Symbology.Code128
Dim mStream As System.IO.MemoryStream = New System.IO.MemoryStream()
bb.BarCodeImage.Save(mStream, System.Drawing.Imaging.ImageFormat.Png)
Dim bmpImage As System.Drawing.Bitmap = bb.BarCodeImage

builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary)
builder.InsertImage(bmpImage)
PageNumber = PageNumber + 1
PrevStudentID = dt.Rows.Item(nRow).Item("StudentID")
Next section

dstDoc.AppendDocument(categoryDoc, ImportFormatMode.UseDestinationStyles)

Next

Hi

Thanks for your request. Maybe you should just unlink header/footer. You can achieve this using LinkToPrevious method.
https://reference.aspose.com/words/net/aspose.words/headerfootercollection/linktoprevious/
Please see the following code:

section.HeadersFooters.LinkToPrevious(HeaderFooterType.FooterPrimary, false);

Hope this helps.
Best regards,

The issues you have found earlier (filed as WORDSNET-2978) have been fixed in this .NET update and this Java update.

This message was posted using Notification2Forum from Downloads module by aspose.notifier.
(27)