Example:
Shows ways of traversing a document's layout entities.
public void layoutEnumerator() throws Exception {
// Open a document that contains a variety of layout entities
// Layout entities are pages, cells, rows, lines and other objects included in the LayoutEntityType enum
// They are defined visually by the rectangular space that they occupy in the document
Document doc = new Document(getMyDir() + "Layout entities.docx");
// Create an enumerator that can traverse these entities like a tree
LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);
Assert.assertEquals(doc, layoutEnumerator.getDocument());
layoutEnumerator.moveParent(LayoutEntityType.PAGE);
Assert.assertEquals(LayoutEntityType.PAGE, layoutEnumerator.getType());
Assert.assertThrows(IllegalStateException.class, () -> System.out.println(layoutEnumerator.getText()));
// We can call this method to make sure that the enumerator points to the very first entity before we go through it forwards
layoutEnumerator.reset();
// "Visual order" means when moving through an entity's children that are broken across pages,
// page layout takes precedence and we avoid elements in other pages and move to others on the same page
System.out.println("Traversing from first to last, elements between pages separated:");
traverseLayoutForward(layoutEnumerator, 1);
// Our enumerator is conveniently at the end of the collection for us to go through the collection backwards
System.out.println("Traversing from last to first, elements between pages separated:");
traverseLayoutBackward(layoutEnumerator, 1);
// "Logical order" means when moving through an entity's children that are broken across pages,
// node relationships take precedence
System.out.println("Traversing from first to last, elements between pages mixed:");
traverseLayoutForwardLogical(layoutEnumerator, 1);
System.out.println("Traversing from last to first, elements between pages mixed:");
traverseLayoutBackwardLogical(layoutEnumerator, 1);
}
/// <summary>
/// Enumerate through layoutEnumerator's layout entity collection front-to-back, in a DFS manner, and in a "Visual" order.
/// </summary>
private void traverseLayoutForward(LayoutEnumerator layoutEnumerator, int depth) throws Exception {
do {
printCurrentEntity(layoutEnumerator, depth);
if (layoutEnumerator.moveFirstChild()) {
traverseLayoutForward(layoutEnumerator, depth + 1);
layoutEnumerator.moveParent();
}
} while (layoutEnumerator.moveNext());
}
/// <summary>
/// Enumerate through layoutEnumerator's layout entity collection back-to-front, in a DFS manner, and in a "Visual" order.
/// </summary>
private void traverseLayoutBackward(LayoutEnumerator layoutEnumerator, int depth) throws Exception {
do {
printCurrentEntity(layoutEnumerator, depth);
if (layoutEnumerator.moveLastChild()) {
traverseLayoutBackward(layoutEnumerator, depth + 1);
layoutEnumerator.moveParent();
}
} while (layoutEnumerator.movePrevious());
}
/// <summary>
/// Enumerate through layoutEnumerator's layout entity collection front-to-back, in a DFS manner, and in a "Logical" order.
/// </summary>
private void traverseLayoutForwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception {
do {
printCurrentEntity(layoutEnumerator, depth);
if (layoutEnumerator.moveFirstChild()) {
traverseLayoutForwardLogical(layoutEnumerator, depth + 1);
layoutEnumerator.moveParent();
}
} while (layoutEnumerator.moveNextLogical());
}
/// <summary>
/// Enumerate through layoutEnumerator's layout entity collection back-to-front, in a DFS manner, and in a "Logical" order.
/// </summary>
private void traverseLayoutBackwardLogical(LayoutEnumerator layoutEnumerator, int depth) throws Exception {
do {
printCurrentEntity(layoutEnumerator, depth);
if (layoutEnumerator.moveLastChild()) {
traverseLayoutBackwardLogical(layoutEnumerator, depth + 1);
layoutEnumerator.moveParent();
}
} while (layoutEnumerator.movePreviousLogical());
}
/// <summary>
/// Print information about layoutEnumerator's current entity to the console, indented by a number of tab characters specified by indent.
/// The rectangle that we process at the end represents the area and location thereof that the element takes up in the document.
/// </summary>
private void printCurrentEntity(LayoutEnumerator layoutEnumerator, int indent) throws Exception {
String baseString = "\t";
String tabs = StringUtils.repeat(baseString, indent);
if (tabs.equals(layoutEnumerator.getKind())) {
System.out.println(MessageFormat.format("{0}-> Entity type: {1}", tabs, layoutEnumerator.getType()));
} else {
System.out.println(MessageFormat.format("{0}-> Entity type & kind: {1}, {2}", tabs, layoutEnumerator.getType(), layoutEnumerator.getKind()));
}
// Only spans can contain text
if (layoutEnumerator.getType() == LayoutEntityType.SPAN) {
System.out.println(MessageFormat.format("{0} Span contents: \"{1}\"", tabs, layoutEnumerator.getText()));
}
Rectangle2D leRect = layoutEnumerator.getRectangle();
System.out.println(MessageFormat.format("{0} Rectangle dimensions {1}x{2}, X={3} Y={4}", tabs, leRect.getWidth(), leRect.getHeight(), leRect.getX(), leRect.getY()));
System.out.println(MessageFormat.format("{0} Page {1}", tabs, layoutEnumerator.getPageIndex()));
}