Move Figures to Even Pages and Content to Odd Pages in Word DOCX

Hi,

I have a DOCX file which was generated from HTML using Aspose.Words.

Now I want to modify this DOCX so that:

  • Figures (images with captions) only appear on even-numbered pages.
  • Other content (paragraphs, tables, etc.) should only appear on odd-numbered pages.
  • There can be scenarios where a paragraph or table exceeds the page size. In such cases, the text content should:
    • start on an odd page,
    • leave the following even page blank, and
    • continue the remaining content on the next odd page.

In other words, the requirement is:

  • Odd pages → text only
  • Even pages → figures only (or blank if no figure follows)

Could you please suggest the best way to implement this with Aspose.Words for Java?

Thanks,
Lasanga

@lasanga

To achieve the layout you described in your DOCX file using Aspose.Words for Java, follow these steps:

  1. Cause: You need to rearrange the content of your document to ensure that text appears on odd pages and images on even pages, while maintaining proper formatting and structure.

  2. Solution:

    • Iterate through the document: Go through each paragraph and figure in the document to determine their types (text or image).
    • Create a new document: Initialize a new document to hold the rearranged content.
    • Add content to odd and even pages:
      • For each paragraph or table (text content), add it to the new document and check if it exceeds the page size. If it does, insert a page break to ensure it starts on an odd page, leaving the next even page blank.
      • For images, add them to the new document but ensure they are placed only on even-numbered pages.
    • Handle page breaks: Use the DocumentBuilder to insert page breaks as needed to maintain the odd/even page structure.

Here’s a minimal code example to illustrate this:

import com.aspose.words.*;

public class RearrangeContent {
    public static void main(String[] args) throws Exception {
        Document originalDoc = new Document("input.docx");
        Document newDoc = new Document();
        DocumentBuilder builder = new DocumentBuilder(newDoc);

        for (Node node : originalDoc.getChildNodes(NodeType.ANY, true)) {
            if (node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE) {
                // Check if the content exceeds the page size
                if (builder.getCurrentParagraph().getParagraphFormat().getPageBreakBefore()) {
                    builder.InsertBreak(BreakType.PAGE_BREAK);
                }
                builder.insertNode(node.deepClone(true));
                // Check if the next node is an image
                if (node.getNextSibling() != null && node.getNextSibling().getNodeType() == NodeType.SHAPE) {
                    builder.InsertBreak(BreakType.PAGE_BREAK); // Leave even page blank
                }
            } else if (node.getNodeType() == NodeType.SHAPE) {
                // Insert images on even pages
                builder.InsertBreak(BreakType.PAGE_BREAK);
                builder.insertNode(node.deepClone(true));
            }
        }

        newDoc.save("output.docx");
    }
}

Key Points:

  • Use NodeType.ANY to iterate through all nodes and check their types.
  • Use deepClone(true) to maintain formatting when moving nodes.
  • Insert page breaks appropriately to manage odd/even page requirements.
  1. Next Steps: Implement the provided code in your Java environment, ensuring you have the Aspose.Words library included. Test the output document to verify that the layout meets your requirements.

If you have any further questions or need additional assistance, please feel free to ask!

Hi,

Thanks for the suggestion. I tried the code you shared, but had to make some modifications due to compilation/runtime errors. Unfortunately, I did not get the expected results.

I am attaching:

  • Sample input DOCX (generated from HTML).
    input.docx (256.0 KB)

  • Output DOCX that I got from the modified code.
    output.docx (243.7 KB)

  • Expected Output
    expected_output.docx (263.5 KB)

  • Code I used (pasted below).

import com.aspose.words.*;

public class RearrangeContent {
    public static void main(String[] args) throws Exception {
        Document originalDoc = new Document("input.docx");
        Document newDoc = new Document();
        DocumentBuilder builder = new DocumentBuilder(newDoc);

        NodeCollection nodes = originalDoc.getChildNodes(NodeType.ANY, true);

        for (int i = 0; i < nodes.getCount(); i++) {
            Node node = nodes.get(i);
            Node imported = newDoc.importNode(node, true, ImportFormatMode.KEEP_SOURCE_FORMATTING);
            if (node.getNodeType() == NodeType.PARAGRAPH || node.getNodeType() == NodeType.TABLE) {
                // Check if the content exceeds the page size
                if (builder.getCurrentParagraph().getParagraphFormat().getPageBreakBefore()) {
                    builder.insertBreak(BreakType.PAGE_BREAK);
                }

                builder.getCurrentParagraph().getParentNode().insertAfter(imported, builder.getCurrentParagraph());

                // Check if the next node is an image
                if (node.getNextSibling() != null && node.getNextSibling().getNodeType() == NodeType.SHAPE) {
                    builder.insertBreak(BreakType.PAGE_BREAK); // Leave even page blank
                }
            } else if (node.getNodeType() == NodeType.SHAPE) {
                // Insert images on even pages
                builder.insertBreak(BreakType.PAGE_BREAK);
                builder.insertNode(imported);
            }
        }

        newDoc.save("output.docx");
    }
}

Issue:

  • Figures and text are not aligning correctly on odd/even pages.
  • Extra blank pages are being inserted, and sometimes text continues on even pages instead of odd.

Expected:

  • Odd pages → text only.
  • Even pages → figures only (or blank if no figure follows).
  • If a paragraph/table flows over a page, it should always continue on the next odd page (leaving the even page blank).

Could you please check my code and suggest the right way to achieve this?

Thanks

@lasanga You should note that MS Word documents are flow by their nature. This means there is no “page” concept. The consumer application reflows the document content into pages on the fly.

Though, you can try using the following code:

Document doc = new Document("C:\\Temp\\in.docx");
// Insert page break before and after images to make them appear on separate pages.
Run pageBreak = new Run(doc, ControlChar.PAGE_BREAK);
for (Shape s : (Iterable<Shape>)doc.getChildNodes(NodeType.SHAPE, true))
{
    // Skip shapes, which are not in the main document body and nested shapes.
    if (s.getAncestor(NodeType.BODY) == null || !s.isTopLevel())
        continue;

    s.getParentNode().insertBefore(pageBreak.deepClone(true), s);
    s.getParentNode().insertAfter(pageBreak.deepClone(true), s);
}
// Remove blank pages
doc.removeBlankPages();

// Split document into pages and rejoin with appropriate section starts.
Document result = (Document)doc.deepClone(false);
for (int i = 0; i < doc.getPageCount(); i++)
{
    Document page = doc.extractPages(i, 1);
    // Set appropriate section start of the first section of each "page".
    Node firstChild = page.getFirstSection().getBody().getFirstParagraph().getFirstChild();
    if (firstChild != null && firstChild.getNodeType() == NodeType.SHAPE)
        page.getFirstSection().getPageSetup().setSectionStart(SectionStart.EVEN_PAGE);
    else
        page.getFirstSection().getPageSetup().setSectionStart(SectionStart.ODD_PAGE);

    for (Section s : page.getSections())
    {
        result.appendChild(result.importNode(s, true, ImportFormatMode.USE_DESTINATION_STYLES));
    }
}

result.save("C:\\Temp\\out.docx");