Add image to word document's each page

Hi there,
Thanks for your inquiry.
Could you please attach the template which the issue is occuring in for testing.
Thanks,

Hi, thank for your reply.
Here is the doc file

Hi there,
Thanks for your inquiry.
You’re right, it seems the page number is not being populated for some reason when the field is inserted into a shape. The rest of the shapes work correctly though.
For now I think you can avoid this issue by adding this peice of code:
bool isInCorrectPosition = (!HasSiblingOfNodeType(node, NodeType.BookmarkStart) && !HasSiblingOfNodeType(node, NodeType.FieldStart) && node.GetAncestor(NodeType.HeaderFooter) == null && node.GetAncestor(NodeType.Shape) == null);
Also note, I’ve had plans to create a more efficent and general work around for finding the page number of nodes. This should make what you are trying to achieve a lot easier. I have not had any time to create this yet though. I will inform you when this is ready.
Thanks

Thank you very much Adam.
It would be great if you’ll find some time to achieve a new version of GetPages

aske012:
Hi there,
Thanks for your inquiry.
You’re right, it seems the page number is not being populated for some reason when the field is inserted into a shape. The rest of the shapes work correctly though.
For now I think you can avoid this issue by adding this peice of code:
bool isInCorrectPosition = (!HasSiblingOfNodeType(node, NodeType.BookmarkStart) && !HasSiblingOfNodeType(node, NodeType.FieldStart) && node.GetAncestor(NodeType.HeaderFooter) == null && node.GetAncestor(NodeType.Shape) == null);
Also note, I’ve had plans to create a more efficent and general work around for finding the page number of nodes. This should make what you are trying to achieve a lot easier. I have not had any time to create this yet though. I will inform you when this is ready.
Thanks

Hi there!
I have another problem with GetPages() method. See the doc file in attachments.
Did you developed a new version of this method?

Hi there,
Thanks for your inquiry.
My apologises for the delay, I have not forgotten about you. I will code this for you in the weekend. For now please hang tight with this error, it will be fixed when I restructure the code.
Thanks,

Hi, thanks for your reply.
Can you provide a specific date or time? Because we have a really BIG problem with that issue and our customers from some government structure are very dissapoint. We need to fix it yesterda…

Hi there,
I will try do this as soon as possible. Sorry for the delay.
Thanks,

Hi, thanks that you still with me:)
Sorry for persistence… the ‘soon as possible’ is day, week, month?

Hi there,
Thanks for your inquiry.
I will provide you with some code within a weeks time. Thanks for your patience.
Thanks,

I have no choice but to wait.
Thanks Adam

Hi Adam,
We have made an official query to Aspose too.
Thank you for your cooperation.

Hi there,
Thanks for your patience.
Please find attached a new version of requested code. This one should run much faster and should not encounter any problems. It should not take much longer than how long it takes to layout the document (e.g render it to PDF).
You can pass the document that you want to find the page numbers from to the constructor of the PageNumberFinder class and then use the methods 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).
  • GetPageSpan(Node) - As explained above returns how many pages a node spans across. Returns 0 if the node starts and ends on the same page.
  • GetAllNodesOnPages(int, int) - Returns a list of all nodes of the document body contained on the specified page.

In your situation you would want to do something like this:

Document doc = new Document("Document.doc");
PageNumberFinder finder = new PageNumberFinder(doc);
for (int page = 1; page <= doc.PageCount; page++)
{
    ArrayList pageNodes = pageFinder.RetrieveAllNodesOnPage(page, page, NodeType.Paragraph);
    AddTextBoxToPage(pageNodes, pageNum);
}
doc.Save("Document Out.docx");

Where AddTextBoxToPage() is a method similar to before but where this time you can choose any appropriate node from the list to insert the Shape at i.e a child of paragraph.
If you have any troubles please feel free to ask.
Thanks,

Hi Adam.
First of all, thanks for your help and time! I am very thankful to you.

The question is - how to use it? I need to add an image to each doc’s page. It means to go through every page and add image to it.
But in your code there are two loops… Its confusing me

Hi there,
Thanks for your inquiry.
I gave a short code example on my previous post. The call to the attached class will return all nodes found on the specified page. In your implementation of AddTextboxToPage you can choose any appropriate node to insert a textbox at. Please see the simple code example below.

public void AddTextBoxToPage(ArrayList nodeList, int pageNum)
{
    Paragraph para = (Paragraph) nodeList[0];

    // Create textbox shape.
    // Add as a child to this paragraph.
    // Inserted a textbox for this page so we've finished here, break and return;
}

Thanks,

But the problem was that there was no ability to get pages number, and Document.PageCount was giving wrong value every time. That’s why I started to user your solution.

Hi there,
You can call doc.UpdatePageLayout (pre AW 9.6) or doc.UpdateFields (post AW 9.6) before running the code to ensure that the PageCount property is up to date. This will not slow down how long it takes to retrieve the page numbers.
In either case the RetrieveAllNodesOnPages method will return an empty array list if the passed page number does not exist in the document, so you can just check for an empty list and stop processing there.
Thanks,

And what type of node should I use?
I’ve tried body and run - without success. The paragraph is not suitable for me because I need to insert image on each page.

Here is my code:

Document doc = new Document(sourceStream);

PageNumberFinder pageFinder = new PageNumberFinder(doc);
List<Node> pages;
Node page;

Shape layer;
Paragraph layerParagraph;

foreach (KeyValuePair<int, byte[]> kvp in layersContent)
{
    pages = pageFinder.RetrieveAllNodesOnPage(kvp.Key + 1, true);
    if (pages != null)
    {
        foreach (Node p in pages)
        {
            page = p;

            if (page.NodeType == NodeType.Body)
            {
                layerParagraph = new Paragraph(doc);
                layer = new Shape(doc, ShapeType.Image);
                layer.ImageData.SetImage(kvp.Value);
                layer.WrapType = WrapType.None;
                layer.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
                layer.HorizontalAlignment = HorizontalAlignment.Center;
                layer.RelativeVerticalPosition = RelativeVerticalPosition.Page;
                layer.VerticalAlignment = VerticalAlignment.Center;
                layer.Left = 0;
                layer.BehindText = false;
                layer.Width = Width;
                layer.Height = Height;
                layerParagraph.AppendChild(layer);
                (p as Body).AppendChild(layerParagraph);
            }
        }
    }
}

doc.Save(resultStream, (SaveFormat)outputFormat);
result = resultStream.ToArray();

Thanks

Adam,
one more detail: in case the document have only one page - the RetrieveAllNodesOnPage return a node aith Body type. But when the pages quantity more then one - the only nodes that are returned by this method is type of paragraph and run

Hi there,
Remember that a shape node can only be a child of a paragraph. Please see details on the Document Object Model here for clarifications.
You cannot insert the paragraph to the end of the body as the body of the section may span across many pages. Instead you need to insert it before or after one of the nodes found on the current page (the nodes in the list).
Please see the changes to your code below.

foreach(KeyValuePair <int, byte[]> kvp in layersContent)
{
    pages = pageFinder.RetrieveAllNodesOnPage(kvp.Key + 1, true);
    if (pages != null)
    {
        foreach(Node p in pages)
        {
            page = p;
            if (page.NodeType == NodeType.Paragraph)
            {
                layerParagraph = new Paragraph(doc);

                layer = new Shape(doc, ShapeType.Image);
                layer.ImageData.SetImage(kvp.Value);
                layer.WrapType = WrapType.None;
                layer.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
                layer.HorizontalAlignment = HorizontalAlignment.Center;
                layer.RelativeVerticalPosition = RelativeVerticalPosition.Page;
                layer.VerticalAlignment = VerticalAlignment.Center;
                layer.Left = 0;
                layer.BehindText = false;
                layer.Width = Width;
                layer.Height = Height;

                layerParagraph.AppendChild(layer);
                (p as Paragraph).ParentNode.InsertBefore(layerParagraph, p);
                break;
            }
        }
    }
}

Regarding your other query, if a body takes up more than one page (which it most likely does) then it wont be returned on that list as it cannot be contained on the one page, that is why only the paragraphs that make up the page are included.
Thanks,