Add image to word document's each page

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,

Thank you very much, Adam!
It seems that everything works fine right now.

Hi Adam, we might have found a bug in the code:

The code that retrieves all nodes on page is not returning items (paragraphs) which are on the first line/row one a page for pages above 1.

So basically it gives me the correct values for the first line of page 1, but for pages after page 1 it will not return paragraph node for the first line on the page.

List pageNodes = pageFinder.RetrieveAllNodesOnPage(pageNum, true);

Let me know if this makes sense.

Brian

Hi Brian,
Thanks for your inquiry. Yes this makes sense but could attach the document you are having trouble with here so I can test it directly. I will take a closer look into it for you.
Thanks,

Hi Adam, sure attached is the test document.

If I open that doc on my system in MS Word 2010 I will see 2 pages, Aspose will only show it on 1 page. First line from second page in MS Word will be shown at the bottom on first page in aspose.

Not sure if there is much that can be done about this.

Thanks

Hi Brian,

Thank you for additional information. I managed to reproduce the problem on my side. It seems there is some problem with our rendering engine. For example, if you try saving your document to PDF you will get the same result. Your request has been linked to the appropriate issue. You will be notified as soon as it is resolved.
Best regards,

Hi Adam, your code does not work in aspose 10. It worked in previous versions ok.

The code now returns the whole file content, not the individual page.

Any chance you could have a look at it to see if you can get it working with aspose 10?

Thanks

Hi there,
Thanks for your inquiry.
You’re correct, this was a small bug on my end which is now fixed and reattached.
Thanks,