Insert Unique QRCode in Word document at each page using Java

Good morning,

I’m using ASPOSE WORDS 19.10 for JAVA and I’ve to put in every page of every processed documents a unique QR code as a floating image next to bottom right corner of the page. I’ve already taken a look at Working with Images in Java|Aspose.Words for Java but the “How to Insert Barcode on each Page of a Document” example doesn’t work…
The only way I found (thanks to stackoverflow) to do that is to create, for every document section and for every document pages, an IF statement like this:

for(int j = 0; j < doc.getSections().getCount(); j++){
	builder.moveToSection(j);
	builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);

    builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);

    builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);
	
}

private static void insertQRCodeImage(DocumentBuilder builder, String qrCodeIdentifier, int numPages) throws Exception {
        Field field = null;

    for (int i = 1; i <= numPages; i++) {
        field = builder.insertField("IF ");
        builder.moveTo(field.getSeparator());
        builder.insertField("PAGE");
        builder.write(" = " + i);
        builder.write(" \" ");

        PageSetup ps = builder.getPageSetup();
        Shape image = builder.insertImage(LiscorAsposeExpression.createBarcode(qrCodeIdentifier, i, numPages));
        
        //put the qr code next to bottom right corner of the page
        image.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
        image.setLeft(ps.getPageWidth() - image.getSizeInPoints().getX() -2);
        image.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
        image.setTop(ps.getPageHeight() - image.getSizeInPoints().getY() - 2);
        image.setWrapType(WrapType.NONE);

        image.setBehindText(false);
        builder.write(" \" ");
    }
    field.update();
}

In this way I’m sure that the generated QR code will be put in every document page. I tried with a little complex document (with 14 pages, 3 sections and different headers) but the performarce are pretty bad… more than 2 minutes against 3 seconds without QR code generation.
I saw that the only set of statements:

field = builder.insertField("IF ");
builder.moveTo(field.getSeparator());
builder.insertField("PAGE");
builder.write(" = " + i);
builder.write(" \" ");

took about 1.5 second, and the statement

field.update();

took about 1 second

So… is there a smarter way to do that?

Thanks

@voxopake

To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please attach the output Word file that shows the undesired behavior.
  • Please attach the expected output Word file that shows the desired behavior.
  • Please create a simple Java application ( source code without compilation errors ) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

The document is created correctly. My question is: “Is there another (smarter) way to create an image for every pages?”.
Because right now I create an “if” statement for every sections, for every headers type, for every pages and put in it the rendered image.
Here a snippet code about the algorithm

for(int j = 0; j < doc.getSections().getCount(); j++){
	builder.moveToSection(j);
	builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);

    builder.moveToHeaderFooter(HeaderFooterType.HEADER_FIRST);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);

    builder.moveToHeaderFooter(HeaderFooterType.HEADER_EVEN);
    insertQRCodeImage(builder, qrCodeIdentifier, numPages);
	
}

private static void insertQRCodeImage(DocumentBuilder builder, String qrCodeIdentifier, int numPages) throws Exception {
        Field field = null;

    for (int i = 1; i <= numPages; i++) {
        field = builder.insertField("IF ");
        builder.moveTo(field.getSeparator());
        builder.insertField("PAGE");
        builder.write(" = " + i);
        builder.write(" \" ");

        PageSetup ps = builder.getPageSetup();
        Shape image = builder.insertImage(LiscorAsposeExpression.createBarcode(qrCodeIdentifier, i, numPages));
        
        //put the qr code next to bottom right corner of the page
        image.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
        image.setLeft(ps.getPageWidth() - image.getSizeInPoints().getX() -2);
        image.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
        image.setTop(ps.getPageHeight() - image.getSizeInPoints().getY() - 2);
        image.setWrapType(WrapType.NONE);

        image.setBehindText(false);
        builder.write(" \" ");
    }
    field.update();
}

Thanks

@voxopake

You can insert the image on each page of document and set its position according to your requirement using layout APIs. In this case, we suggest you following solution. Hope this helps you.

  1. Iterate over paragraphs of Body node and get the page number of them using LayoutCollector.GetStartPageIndex method.
  2. When this method returns the next page number, please move the cursor to the first paragraph and insert the desired image.

In this way, you can insert the image on each page of document.

@voxopake

You can get an idea from the following code example to insert an image on each page of document. Hope this helps you.

Document doc = new Document(MyDir + "input.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

ParagraphCollection nodes = doc.FirstSection.Body.Paragraphs;
LayoutCollector collector = new LayoutCollector(doc);

int pageIndex = 1;
foreach (Paragraph paragraph in nodes)
{
    if (collector.GetStartPageIndex(paragraph) == pageIndex)
    {
        builder.MoveTo(paragraph);
        Shape shape = builder.InsertImage(MyDir + "19945_3.png");
        shape.IsLayoutInCell = false;

        shape.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
        shape.RelativeVerticalPosition = RelativeVerticalPosition.Page;

        shape.Width = 300;
        shape.Height = 70;
        shape.HorizontalAlignment = Aspose.Words.Drawing.HorizontalAlignment.Left;
        shape.VerticalAlignment = VerticalAlignment.Bottom;

        shape.WrapType = WrapType.None;
        pageIndex++;
    }
}

doc.Save(MyDir + "20.2.docx");

Thanks!
Seems to work if saved as docx, but if I save the output file in PDF format, the image isn’t show up…I tried with your code and this word example document

java.zip (246.4 KB)

Probably I resolved with calling doc.updatePageLayout(); before doc.save

Thanks!

@voxopake

Yes, please call Document.updatePageLayout method before saving document to PDF. This method formats a document into pages and updates the page number related fields in the document such as PAGE, PAGES, PAGEREF and REF.