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;
}
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,
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"
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
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 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.
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;
}
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,
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.
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.
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
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.
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.