How to findout Pageno of "Run" Node

Hi,
I am using evaluation version of ASPOSE. I need to find out page no of each “Run” node that is present in Word Document. I found following piece of code from ASPOSE forum. I have a Document of 250 pages, while processing this document with this code it took long time to process. Because in this code we are inserting “Field” and updating page layout for each “Run” node. I require code to retrieve page no of run node in effective way. Please suggest me if there is any other way to achieve this.
Code:

private int GetPageNumber(Node node)
{
    string number;
    int pageNum = 0;
    Field field;
    Document doc = (Document)node.Document;
    DocumentBuilder builder = new DocumentBuilder(doc);
    builder.MoveTo(node);
    field = builder.InsertField(" PAGE ");
    doc.UpdatePageLayout();
    number = field.Result;
    if (!string.IsNullOrEmpty(number))
        pageNum = int.Parse(number);
    field.Remove();
    return pageNum;
}

Thanks.

Hi Sarath,
Thanks for your inquiry.
MS Word documents are flow documents and are not natively laid out into lines and pages so currently there is no direct way to find the page numbers of given nodes. I have linked your request to the appropriate issue, you will be informed as soon as this is availliable.
However in the mean time you can try using the work around class that I have attached to this post. You can use it like below:

  • GetPage(Node) - Gets the page number of the specific node
  • GetPageEnd(Node) - Gets the end page number (if a node is large and its content spans across more than one page).
  • PageSpan(Node) - As explained above returns how many pages a node spans across. Returns 0 if the node starts and ends on the same page.
  • RetrieveAllNodesOnPages(int, int) - Returns a list of all document body nodes contained on the specified page range.
Document doc = new Document("Document.doc");
PageNumberFinder finder = new PageNumberFinder(doc);
int pageNum = finder.GetPage(doc.FirstSection.Body.FirstParagraph.Runs[0]);

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

Hi aske012,
where can i find “PageNumberFinder” class. i cant find any attachment with this post.
Thanks.

Hi there,
Thanks for your inquiry. I have attached the file in my previous post.
Thanks,

Thank you for uploading PageFinder. Is it possible to use PageFinder in an IFieldMergingCallback method? If I invoke RetrieveAllNodesOnPage or GetPage in the callback I get an exception.

" at Aspose.Words.DocumentBuilder.MoveTo(Node node)\r\n at PageFinder.PageNumberFinder.FindPagesOfNodes(Document doc) in C:\satellite\ACTT\Website\FACTS\Aspose\PageFinder.cs:line 84"

node

{xe86f37adaccef1c3.x456f385d9443dbb8}
[xe86f37adaccef1c3.x456f385d9443dbb8]: {xe86f37adaccef1c3.x456f385d9443dbb8}
Document: {Aspose.Words.Document}
IsComposite: false
NextSibling: null
NodeType: System
ParentNode: {Aspose.Words.Body}
PreviousSibling: {Aspose.Words.Paragraph}
Range: {Aspose.Words.Range}
void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
{
    if (mBuilder == null)
        mBuilder = new DocumentBuilder(e.Document);

    PageNumberFinder pageFinder = new PageNumberFinder(mBuilder.Document);
    pageFinder.RetrieveAllNodesOnPage(1, true);
}

Hi there,
Thanks for your inquiry.
Yes you should beable to achieve this during mail merge by cloning the document and removing all system related nodes then find the pages of the cloned document.
Please see the code below:

Document cloneDoc = doc.Clone();

// Remove any temporary mail merge related nodes which will cause an exception during update.
foreach (Node systemNode in cloneDoc.GetChildNodes(NodeType.System, true).ToArray())
    systemNode.Remove();
PageNumberFinderNew finder = new PageNumberFinderNew(cloneDoc);

If you have any troubles could please attach your document here for testing?
Thanks,

Hi Aske012,
by this statement “I have linked your request to the appropriate issue, you will be informed as soon as this is availliable” you mean that the GetPage method / PageNumberFinder class will be available in the next release?
Thanks

Hi Emi,

Thanks for your inquiry

No, actually the PageNumberFinder class is a work around for the time being which retrieves page numbers of each node by taking advantage of the rendering engine and PAGE field. You can find the code for this in the attachment of this post here.

The linked issue represents adding the proper functionality to the Aspose.Words API. As soon as this issue is resolved, this functionality will be built-in to the Aspose.Words DLL so it wouldn’t require any work around code.

We will inform you as soon as there are any developments regarding this issue.

Thanks,

Has this functionality been built into Aspose.Words yet, or do we still need to use this workaround?

Hi Fred,

Thanks for your request. No, the latest version of Aspose.Words still does not have a public API that allows to determine the page number where the particular node is located. We will let you know once this feature is available.

Best Regards,

Hi aske012,
I want to get the infomation of navigation pane. But when test your code with the attachment by calling GetPage(Node) function, it works incorrectly here.
Please pay your attention to the bold and green text below.

other question:
I have inserted page field into MS word. You insert another page field into the document on fly by documentbuilder.InsertField() function. This is not convenient and it works in bad performance. How can I Get page field result directly?

Please let me know if you have any idea about these questions.
---------------
My Test Code:
======

public static void GetNavigationMapInfo()
{
    Document doc = new Document(strFilePath);
    DocumentBuilder dbuilder = new DocumentBuilder(doc);

    // iterate all sections
    int i = 0;
    foreach (Section sec in doc.Sections)
    {
        Console.WriteLine("section:{0}", i);
        i++;
        Console.WriteLine("PageStartingNumber:" + sec.PageSetup.PageStartingNumber.ToString());
        Console.WriteLine("sec.PageSetup.PageStartingNumber:" + sec.PageSetup.PageNumberStyle.ToString());
        Console.WriteLine("sec.PageSetup.RestartPageNumbering:" + sec.PageSetup.RestartPageNumbering.ToString());
        Console.WriteLine("sec.PageSetup.PageNumberStyle:" + sec.PageSetup.PageNumberStyle.ToString());
        Console.WriteLine();
        Console.WriteLine();
    }

    NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
    foreach (Paragraph parag in paragraphs)
    {
        if (
        // (true == parag.ParagraphFormat.Style.BuiltIn)
        // && 
        (true == parag.ParagraphFormat.StyleName.StartsWith("标题 "))
        ||
        (true == parag.ParagraphFormat.StyleName.StartsWith("Heading")))
        {
            Console.WriteLine("parag Text:" + parag.Range.Text);
            Console.WriteLine("parag OutlineLevel:" + parag.ParagraphFormat.OutlineLevel.ToString());

            PageNumberFinder finder = new PageNumberFinder(doc);
            int pageNum = finder.GetPage(parag.Runs[0]);
            int pageNodeEnd = finder.GetPageEnd(parag);
            Console.WriteLine("parag page number:" + pageNum.ToString());
            Console.WriteLine("parag end page number:" + pageNodeEnd.ToString());

            Console.WriteLine();
            Console.WriteLine();
        }
    }

    return;
}


Test Result:
===========

section:0
PageStartingNumber:1
sec.PageSetup.PageStartingNumber:Arabic
sec.PageSetup.RestartPageNumbering:False
sec.PageSetup.PageNumberStyle:Arabic

parag Text:目标
parag OutlineLevel:Level1
parag page number:4
parag end page number:4

**parag Text:工程类型
parag OutlineLevel:Level1
parag page number:5
parag end page number:5

parag Text:流程描述
parag OutlineLevel:Level1
parag page number:5
parag end page number:5**

parag Text:系统设计
parag OutlineLevel:Level2
parag page number:6
parag end page number:6

parag Text:实施
parag OutlineLevel:Level2
parag page number:7
parag end page number:7

parag Text:试运行
parag OutlineLevel:Level2
parag page number:9
parag end page number:9

aske012:
Hi Sarath,
Thanks for your inquiry.
MS Word documents are flow documents and are not natively laid out into lines and pages so currently there is no direct way to find the page numbers of given nodes. I have linked your request to the appropriate issue, you will be informed as soon as this is availliable.
However in the mean time you can try using the work around class that I have attached to this post. You can use it like below:

  • GetPage(Node) - Gets the page number of the specific node
  • GetPageEnd(Node) - Gets the end page number (if a node is large and its content spans across more than one page).
  • PageSpan(Node) - As explained above returns how many pages a node spans across. Returns 0 if the node starts and ends on the same page.
  • RetrieveAllNodesOnPages(int, int) - Returns a list of all document body nodes contained on the specified page range.
Document doc = new Document("Document.doc");
PageNumberFinder finder = new PageNumberFinder(doc);
int pageNum = finder.GetPage(doc.FirstSection.Body.FirstParagraph.Runs[0]);

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

Hi Yanlin,

Thanks for your inquiry. While using the latest version of Aspose.Words i.e. 11.11.0 I was unable to reproduce this issue on my side. I would suggest you please upgrade to the latest version of Aspose.Words. You can download it from the following link:
https://releases.aspose.com/words/net

Secondly, I am afraid there is no direct method to get number of page or page field result without rebuilding the page layout of the document. We will inform you as soon as the layout information of nodes is exposed. We apologize for your inconvenience.

Best regards,

Using the newest version of aspose.word(version 11.11), It works incorrectly again on my side with the same code and the same Demo.doc file.

code and Demo.doc were posted here.

To awais.hafeez: Did the conclusion result from my code and Demo.doc file?

Here is my test result, please pay your attention to the colored line.

parag Text:目标
parag OutlineLevel:Level1
parag page number:4
parag end page number:4

parag Text:工程类型
parag OutlineLevel:Level1
parag page number:5 —>>> It should be page number 4 instead of page number 5 here
parag end page number:5

parag Text:流程描述
parag OutlineLevel:Level1
parag page number:5
parag end page number:5

Hi Yanlin,

Thanks for the additional information. Please find attached a Word document containing the results produced by your code on my side.

Could you please also double check if you are using the latest version (11.11.0)? You can dynamically check if you’re referencing the correct DLL by using the following code snippet:

System.Reflection.Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (System.Reflection.Assembly assembly in assemblies)
{
    System.Reflection.AssemblyName assemblyName = assembly.GetName();
    if (assemblyName.Name.Contains("Aspose.Words"))
        Console.WriteLine("Aspose.Words Version Number: " + assemblyName.Version.ToString());
}

If we can help you with anything else, please feel free to ask.

Best regards,

Why does it work fine on your side?

I test it with the same Demo.doc file.The attachment is my test solution.
platform : .net 4.0 vs2010
windows server 2003(Simplified Chinese)
aspose.word.dll(11.11.0.0)
office 2007(Simplified Chinese)

It is nothing different between my twice test results.


my code:
–>>

public static void GetNavigationMapInfo()
{
    Document doc = new Document(strFilePath);
    DocumentBuilder dbuilder = new DocumentBuilder(doc);

    // print the version of aspose.word.dll
    System.Reflection.Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach (System.Reflection.Assembly assembly in assemblies)
    {
        System.Reflection.AssemblyName assemblyName = assembly.GetName();
        if (assemblyName.Name.Contains("Aspose.Words"))
        {
            Console.WriteLine("Aspose.Words Version Number: " + assemblyName.Version.ToString());
            Console.WriteLine();
            Console.WriteLine();
        }
    }

    // iterate all sections
    int i = 0;
    foreach (Section sec in doc.Sections)
    {
        Console.WriteLine("section:{0}", i);
        i++;
        Console.WriteLine("PageStartingNumber:" + sec.PageSetup.PageStartingNumber.ToString());
        Console.WriteLine("sec.PageSetup.PageStartingNumber:" + sec.PageSetup.PageNumberStyle.ToString());
        Console.WriteLine("sec.PageSetup.RestartPageNumbering:" + sec.PageSetup.RestartPageNumbering.ToString());
        Console.WriteLine("sec.PageSetup.PageNumberStyle:" + sec.PageSetup.PageNumberStyle.ToString());
        Console.WriteLine();
        Console.WriteLine();
    }

    NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
    foreach (Paragraph parag in paragraphs)
    {
        if (
        // (true == parag.ParagraphFormat.Style.BuiltIn)
        // && 
        (true == parag.ParagraphFormat.StyleName.StartsWith("标题 "))
        ||
        (true == parag.ParagraphFormat.StyleName.StartsWith("Heading")))
        {
            Console.WriteLine("parag Text:" + parag.Range.Text);
            Console.WriteLine("parag OutlineLevel:" + parag.ParagraphFormat.OutlineLevel.ToString());

            PageNumberFinder finder = new PageNumberFinder(doc);
            int pageNum = finder.GetPage(parag.Runs[0]);
            int pageNodeEnd = finder.GetPageEnd(parag);
            Console.WriteLine("parag page number:" + pageNum.ToString());
            Console.WriteLine("parag end page number:" + pageNodeEnd.ToString());

            Console.WriteLine();
            Console.WriteLine();
        }
    }

    return;
}

test result:
–>>
Aspose.Words Version Number: 11.11.0.0

section:0
PageStartingNumber:1
sec.PageSetup.PageStartingNumber:Arabic
sec.PageSetup.RestartPageNumbering:False
sec.PageSetup.PageNumberStyle:Arabic

parag Text:目标
parag OutlineLevel:Level1
parag page number:4
parag end page number:4

parag Text:工程类型
parag OutlineLevel:Level1
parag page number:5 // should be 4 here
parag end page number:5

parag Text:流程描述
parag OutlineLevel:Level1
parag page number:5
parag end page number:5

parag Text:系统设计
parag OutlineLevel:Level2
parag page number:6
parag end page number:6

parag Text:实施
parag OutlineLevel:Level2
parag page number:7
parag end page number:7

parag Text:试运行
parag OutlineLevel:Level2
parag page number:9
parag end page number:9

Hi Yanlin,

Thanks for the additional information. Please ensure you have set the license as described in the instructions here before instantiating the Document object. Moreover, I have attached a sample application here for your reference; you can run this application to verify that running Aspose.Words with a valid license set produces correct results. I hope, this helps.

Best regards,

Thank you for your reply.

It works using the right license Aspose.Words.lic.

Hi Yanlin,

Thanks for your feedback on this. Please let us know any time you have any further queries. We’re always glad to help you.

Best regards,

Hi,

I Have another quetion:
How to get the list number of heading ?
What about the list number when ListFormat.ListLevel.NumberStyle is Bullet?

such as :

  1. How
  2. to
  • get
  • list
  • number
  • when

There is someting wrong in my result:

section:{0}
PageStartingNumber:1
sec.PageSetup.PageStartingNumber:Arabic
sec.PageSetup.RestartPageNumbering:False
sec.PageSetup.PageNumberStyle:Arabic
parag.ListFormat.ListLevelNumber:0
parag.ListFormat..ListLevel.NumberStyle:Arabic
parag.ListFormat..ListLevel.StartAt:1
parag Text:目标 //should be 1目标 here, as the blue lines show.
parag OutlineLevel:Level1
parag page number:4
parag end page number:4
parag.ListFormat.ListLevelNumber:0
parag.ListFormat..ListLevel.NumberStyle:Arabic
parag.ListFormat..ListLevel.StartAt:1
parag Text:2工程类型
parag OutlineLevel:Level1
parag page number:4
parag end page number:4
parag.ListFormat.ListLevelNumber:0
parag.ListFormat..ListLevel.NumberStyle:Arabic
parag.ListFormat..ListLevel.StartAt:1
parag Text:3流程描述
parag OutlineLevel:Level1
parag page number:4
parag end page number:4

-----

PS:
1.Document tested was posted here.
2.My code:

public static void GetNavigationMapInfo2()
{
    Document doc = new Document(strFilePath);
    DocumentBuilder builder = new DocumentBuilder();

    // iterate all sections
    int i = 0;
    foreach (Section sec in doc.Sections)
    {
        builder.Writeln("section:{" + i + "}");
        i++;

        builder.Writeln("PageStartingNumber:" + sec.PageSetup.PageStartingNumber.ToString());
        builder.Writeln("sec.PageSetup.PageStartingNumber:" + sec.PageSetup.PageNumberStyle.ToString());
        builder.Writeln("sec.PageSetup.RestartPageNumbering:" + sec.PageSetup.RestartPageNumbering.ToString());
        builder.Writeln("sec.PageSetup.PageNumberStyle:" + sec.PageSetup.PageNumberStyle.ToString());

        builder.Writeln();
        builder.Writeln();
    }

    NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
    foreach (Paragraph parag in paragraphs)
    {
        if ((true == parag.ParagraphFormat.StyleName.StartsWith("标题 "))
        ||
        (true == parag.ParagraphFormat.StyleName.StartsWith("Heading")))
        {
            if (true == parag.IsListItem)
            {
                builder.Writeln("parag.ListFormat.ListLevelNumber:" + parag.ListFormat.ListLevelNumber.ToString());
                builder.Writeln("parag.ListFormat…ListLevel.NumberStyle:" + parag.ListFormat.ListLevel.NumberStyle.ToString());
                builder.Writeln("parag.ListFormat…ListLevel.StartAt:" + parag.ListFormat.ListLevel.StartAt.ToString());
                builder.Writeln("parag Text:" + parag.ListLabel.LabelString + parag.Range.Text);
            }
            else
            {
                builder.Writeln("parag Text:" + parag.Range.Text);
            }
            builder.Writeln("parag OutlineLevel:" + parag.ParagraphFormat.OutlineLevel.ToString());

            PageNumberFinder finder = new PageNumberFinder(doc);
            int pageNum = finder.GetPage(parag.Runs[0]);
            int pageNodeEnd = finder.GetPageEnd(parag);
            builder.Writeln("parag page number:" + pageNum.ToString());

            builder.Writeln("parag end page number:" + pageNodeEnd.ToString());

            builder.Writeln();
            builder.Writeln();
        }
    }

    builder.Document.Save(strDocDir + @"result.docx");

    return;
}

Hi Yanlin,

Thanks for your inquiry. I suppose you should just call Document.UpdateListLabels method to update list label properties such as LabelValue and LabelString for each ListLabel object in the document. Secondly, to get the value of a list item you can use the ListLabel class and the ListLabel.LabelValue member. I hope, this helps.

Best regards,