How to insert a text at the start of every page of a document

Hi Team,

I have to add a (continue…) word at start of every page of a doc.

I am using 22.1 version of Apose.Word.

I tried with the below code, but the output is not as expected.
It works on some pages but not on all pages, for some pages - text getting added at the end of page and on some pages is it not getting added.

Attached sample input and output docs. sample-input-output-doc.zip (110.7 KB)

public static void main(String[] args) {
    String inputFilePath = "c:\\dev\\Input.docx";
    String outputFilePath = "c:\\dev\\Output.docx";

    try {
        //applyLicense();
        Document doc = new Document(inputFilePath);
        addContinueWord(doc);
        doc.save(outputFilePath);
        System.out.println("Doc saved successfully");
    } catch (Exception e) {
        //Log Error
    }
}

       
public static void addContinueWord(Document doc) throws Exception {
    DocumentBuilder documentBuilder = new DocumentBuilder(doc);
    int curPageIndex = 1;
    int pageCount = doc.getPageCount();

    while (curPageIndex <= pageCount){
        Node[] runs = doc.getChildNodes(NodeType.RUN, true).toArray();

        for (Node node : runs) {
            Run run = (Run) node;
            int length = run.getText().length();

            Run currentNode = run;
            for (int x = 1; x < length; x++) {
                currentNode = splitRun(currentNode, 1);
            }
        }

        NodeCollection<Run> smallRuns = doc.getChildNodes(NodeType.RUN, true);
        LayoutCollector collector = new LayoutCollector(doc);
        try {
            for (Run run : smallRuns) {
                if (collector.getStartPageIndex(run) == curPageIndex) {
                    documentBuilder.moveTo(run);
                    documentBuilder.insertHtml("<p style='font-weight:bold'>(continued...)</p>");
                    curPageIndex++;
                    break;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

private static Run splitRun(Run run, int position) {
    Run afterRun = (Run) run.deepClone(true);
    afterRun.setText(run.getText().substring(position));
    run.setText(run.getText().substring((0), (position)));
    run.getParentNode().insertAfter(afterRun, run);
    return afterRun;
}

@vipinm I think in your case it would be easier to use Document.extractPages method to achieve what you need. For example see the following code:

Document doc = new Document("C:\\Temp\\in.docx");

// Extract the first page of the document and use it as a target.
Document target = doc.extractPages(0,1);
Document remainingPages = doc.extractPages(1, doc.getPageCount()-1);

while (remainingPages.getPageCount()>1)
{
    addContinueWord(remainingPages);
    target.appendDocument(remainingPages.extractPages(0,1), ImportFormatMode.USE_DESTINATION_STYLES);
    remainingPages = remainingPages.extractPages(1, remainingPages.getPageCount()-1);
}

addContinueWord(remainingPages);
target.appendDocument(remainingPages, ImportFormatMode.USE_DESTINATION_STYLES);

target.save("C:\\Temp\\out.docx");
private static void addContinueWord(Document doc)
{
    Paragraph continuationPara = new Paragraph(doc);
    continuationPara.appendChild(new Run(doc, "(continued...)"));
    continuationPara.getRuns().get(0).getFont().setBold(true);
    doc.getFirstSection().getBody().prependChild(continuationPara);
}

Thanks @alexey.noskov, suggested code works for the above case where on every page we have to add continued word.

Now I am working on another case where we have a document which has multiple sections, and each section may have one or multiple pages. Each section has one unique title (Heading 1) which is at the start page of the section.

Now the requirement is if section contains multiple pages, then every page of that section except first page should have continue word (Section 1 continued), (Section 2 continued), etc.

Note: Sections can be (Section Break - Next Page) and (Section Break - Continuous).

@vipinm Could you please attach your input and expected output documents here for our reference? We will check the documents and provide you more information.

Hi @alexey.noskov, please find the attached input and expected out file.

sample-input-output.zip (74.8 KB)

@vipinm You can modify the code like this:

Document doc = new Document("C:\\Temp\\in.docx");

// Extract the first page of the document and use it as a target.
Document target = doc.extractPages(0, 1);
Document remainingPages = doc.extractPages(1, doc.getPageCount() - 1);

while (remainingPages.getPageCount() > 1)
{
    addContinueWord(remainingPages, getLastHeading(target));
    target.appendDocument(remainingPages.extractPages(0, 1), ImportFormatMode.USE_DESTINATION_STYLES);
    remainingPages = remainingPages.extractPages(1, remainingPages.getPageCount() - 1);
}

addContinueWord(remainingPages, getLastHeading(target));
target.appendDocument(remainingPages, ImportFormatMode.USE_DESTINATION_STYLES);

target.save("C:\\Temp\\out.docx");
private static void addContinueWord(Document doc, String lastHeading)
{
    // Do not add "continued" if document starts from heading paragraph.
    if(doc.getFirstSection().getBody().getFirstParagraph().getParagraphFormat().isHeading())
        return;

    Paragraph continuationPara = new Paragraph(doc);
    continuationPara.appendChild(new Run(doc, lastHeading + " (continued...)"));
    continuationPara.getRuns().get(0).getFont().setBold(true);
    doc.getFirstSection().getBody().prependChild(continuationPara);
}
private static String getLastHeading(Document doc) throws Exception
{
    NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true);
    for (int i=paragraphs.getCount()-1; i>=0; i--)
    {
        Paragraph para = (Paragraph) paragraphs.get(i);
        if(para.getParagraphFormat().getStyleIdentifier() == StyleIdentifier.HEADING_1)
            return para.toString(SaveFormat.TEXT).trim();
    }

    return "";
}

Thanks @alexey.noskov, after modifying the code it is working but not as per the expected output.
I have attached the sample input and generated output file using modified code, at Section 7 it is not working as expected.

sample-input-generated-output.zip (49.6 KB)

@vipinm I have tested your input on my side and the output produced by the above provided code is correct. Here is the output document produced on my side: out.docx (55.0 KB)

I see in your output document there is continue section break before “Section 7 (continued…)”. You can explicitly set new page section start so the Section 7 (continued…) always start on the new page:

while (remainingPages.getPageCount() > 1)
{
    addContinueWord(remainingPages, getLastHeading(target));
    remainingPages.getFirstSection().getPageSetup().setSectionStart(SectionStart.NEW_PAGE);
    target.appendDocument(remainingPages.extractPages(0, 1), ImportFormatMode.USE_DESTINATION_STYLES);
    remainingPages = remainingPages.extractPages(1, remainingPages.getPageCount() - 1);
}

In general the problem on your side might occur because the fonts used in the document are not available in the environment where document is processed. To build the document layout and split the document into pages Aspose.Words requires the fonts. If Aspose.Words cannot find the fonts used in the document the fonts are substituted. This might lead into the layout difference, since substitution fonts might have different font metrics. You can implement IWarningCallback to get a notification when font substitution is performed.

Thanks @alexey.noskov.

We cannot explicitly set new page to section 7, but I will try to check font issue suggested by you.

Thanks again for the help. I will get back to you if anything comes related to the same issue.

@vipinm You do not need to explicitly set new page to section 7. What I have suggested is explicitly set new page section start so the Section 7 (continued…) always starts on the new page. See the code I have provided above.