Hi,
I have a .dot file containing header and footer.
In this .dot file, the first page is in landscape and has particular header/footer.
Also, in the .dot, there is two bookmarks (Change and Back).
When I found the ‘Change’ bookmark, I have to insert the first page in landscape, and when I found the ‘Back’ bookmark, I have to change the orientation and come back as portrait.
My problem is that after the ‘Change’ bookmark, I have a landscape orientation but not with the ‘first section’ header/footer and the next section has header/footer same as following.
Please find my code and in attachment the .dot file, the result.doc file and the expected result.
Document doc = new Document(new File("D:\Doc2.dot").getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(builder.getCurrentSection());
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section) doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// builder.writeln("After Section break new page");
// Copy the content of the current section to the beginning of the last section.
newSection.prependContent(doc.getSections().get(index + 2));
// Remove the copied section.
doc.getSections().get(index + 2).remove();
// Find the back bookmark to return to portrait
changeOrientation = doc.getRange().getBookmarks().get("Back");
builder.moveTo(changeOrientation.getBookmarkStart());
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Remove the rendering (first section)
doc.getFirstSection().remove();
builder.getDocument().save("D:\Result.doc");
Thanks in advance.
Hi Roseline,
Thanks for your query. I have modified your code. Please see the following code snippet and find output file in attachment.
Document doc = new Document(new File(“D:\Doc2.dot”).getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(builder.getCurrentSection());
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section)doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
//
builder.writeln("After Section break new page");
// Copy the content of the current section to the beginning of the last section.
newSection.prependContent(doc.getSections().get(index + 2));
// Remove the copied section.
doc.getSections().get(index + 2).remove();
// Find the back bookmark to return to portrait
changeOrientation = doc.getRange().getBookmarks().get("Back");
builder.moveTo(changeOrientation.getBookmarkStart());
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
doc.getSections().get(index + 2).getPageSetup().setOrientation(Orientation.PORTRAIT);
// Remove the rendering (first section)
doc.getFirstSection().remove();
builder.getDocument().save("D:\\Result.doc");
Please let us know if you have any more queries.
Hi Tahir,
Thanks for your answer.
I have adapt the code and I’m very close to the expected result.
I add a line to set the ‘landscape’ section’s header and footer not be identical to previous.
and add the header/footer of the next ‘portrait’ section. (The following code has ‘NEW LINE’ comments because I can not highlight the text…)
The last problem is that the ‘text area’ of the landscape section is not in the good section but the next section. Please find in attachment the output.doc file.
My code is :
Document doc = new Document(new File("D:\Doc2.dot").getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section portrait = builder.getCurrentSection(); // NEW LINE
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(portrait);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section) doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
//
builder.writeln("After Section break new page");
// Copy the content of the current section to the beginning of the last section.
newSection.prependContent(doc.getSections().get(index + 2));
// Remove the copied section.
doc.getSections().get(index + 2).remove();
// Find the back bookmark to return to portrait
changeOrientation = doc.getRange().getBookmarks().get("Back");
builder.moveTo(changeOrientation.getBookmarkStart());
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
doc.getSections().get(index + 2).getPageSetup().setOrientation(Orientation.PORTRAIT);
// Copy headers footers from previous portrait section
copyHeadersFootersFromPreviousSection(portraitAgain, portrait); // NEW LINE
// Remove the rendering (first section)
doc.getFirstSection().remove();
builder.getDocument().save("D:\Result.doc");
Thanks in advance
Hi Roseline,
Please use the following code snippet. You can use the same code to work with new sections and header footer.
Document doc = new Document(new File(“D:\ Doc2.dot”).getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section landscape = builder.getCurrentSection(); // NEW LINE
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(landscape);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section)doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
copyHeadersFootersFromPreviousSection(landscape); // NEW LINE
builder.moveTo(doc.getSections().get(index + 1).getBody().getFirstParagraph());
builder.writeln("After Section break new page");
doc.getFirstSection().remove();
builder.getDocument().save("D:\\ Result.doc");
Hi Tahir,
Thanks for your help, this is what I wanted, except that now, the page in portrait miss all header and footer…
Is that normal ? I’m sorry if it is a stupid question…
It is because there is not a lot of differences between your code and mine for the section in portrait…
Hi Roseline,
I have modified the code for both section. Please see the highlighted section of following code snippet.
Document doc = new Document(new File("D:\\ Doc2.dot").getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
// Get HeaderFooter for Portrait layout
builder.moveToBookmark("back");
HeaderFooterCollection hfCollection = builder.getCurrentSection().getHeadersFooters();
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section landscape = builder.getCurrentSection(); // NEW LINE
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(landscape);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section)doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
builder.moveTo(doc.getSections().get(index + 1).getBody().getFirstParagraph());
builder.writeln("After Section break new page");
builder.moveToBookmark("back");
Section portrait = builder.getCurrentSection();
for (HeaderFooter headerFooter : hfCollection)
portrait.getHeadersFooters().add(headerFooter.deepClone(true));
doc.getFirstSection().remove();
builder.getDocument().save("D:\\ Result.doc");
Hi Tahir,
Thanks for your answer, the result is so close to the expected result.
In the doc in attachment, we have the text
After section Page break’ in landscape, but the next text ‘Landscape’ is in portrait (see in attachment the expected result).
So in the code you provided, I had these following lines
builder.writeln("After Section break new page");
// Copy the content of the current section to the beginning of the last section.
newSection.prependContent(doc.getSections().get(index + 2));
// Remove the copied section.
doc.getSections().get(index + 2).remove();
builder.moveToBookmark("back");
Section portrait = builder.getCurrentSection();
for (HeaderFooter headerFooter: hfCollection)
portrait.getHeadersFooters().add(headerFooter.deepClone(true));
…
In this case, I have the following exception :
java.lang.IllegalArgumentException: Cannot insert a node of this type at this location.
What have I missing ? (because the section ‘portrait’ seems to be ok)
Hi Roseline,
Thanks for your query. It would be great if you please share your complete scenario in detail. We will share the code with you according to your requirements. Please read following article.
Working with Sections
Hi Tahir,
I have a .dot file which contains the first section in landscape which contains some text box (to simulate header/footer when print the doc).
In this .dot file, I have some text then a bookmark to change the layout to ‘landscape’ then some other text then an other bookmark to change to the layout at ‘portrait’ and more text.
For example:
There is a section in portrait <<bookmark "Change">>
// This is a bookmark to change the layout at ‘landscape’
This is a section in landscape <<bookmark "Back">>
// This is a bookmark to change the layout at ‘portrait’
And we come back to portrait
When we find the bookmark “Change” we copied the first section (the landscape layout),
then we have to copy the content until we found the bookmark “Back” (with the simulated header/footer as text box).
When we found the bookmark “Back” we have to change the layout at portrait and we have to put the good header/footer and remove the simulated one (text box)
With your help, the result is close to the expected result.
But I still have a problem : When I want to copy the landscape following content, I have a exception. :
// The section is now in landscape
builder.writeln("After Section break new page");
// Copy the content of the current section to the beginning of the
// last section.
newSection.prependContent(doc.getSections().get(index + 2));
// Remove the copied section.
doc.getSections().get(index + 2).remove();
builder.moveToBookmark("back");
In the file : Expected result.doc, the string in red highlight is to be removed, and the string in green highlight is to be added.
Please find in attachment the .dot file, the expected result, the current result and the java code (named .txt).
Sorry for my bad english. Please tell me if you don’t understand.
Thanks in advance
Hi Roseline,
Thanks for sharing the information. I am working over your query and will update you asap.
Hi Roseline,
I have a question about “Expected+result.doc”. Do you want to add only text “Landscape” or full contents of last section which contains two bookmarks?
The following code snippet insert contents of a section after text “After Section break new page”.
Document doc = new Document(new File(“D:\Doc2.dot”).getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
// Get HeaderFooter for Portrait layout
builder.moveToBookmark("back");
HeaderFooterCollection hfCollection = builder.getCurrentSection().getHeadersFooters();
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section landscape = builder.getCurrentSection(); // NEW LINE
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(landscape);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section)doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
builder.moveTo(doc.getSections().get(index + 1).getBody().getFirstParagraph());
builder.writeln("After Section break new page");
Section importsec = doc.getSections().get(index + 2);
insertSection(builder.getCurrentParagraph(), doc, builder, importsec);
doc.getFirstSection().remove();
builder.getDocument().save("D:\\Result.doc");
public static void insertSection(Node insertAfterNode, Document srcDoc, DocumentBuilder builder, Section srcSection) throws Exception
{
// Make sure that the node is either a paragraph or table.
if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH) & (insertAfterNode.getNodeType() != NodeType.TABLE)) {
throw new IllegalArgumentException("The destination node should be either a paragraph or table.");
}
builder.moveTo(insertAfterNode);
// We will be inserting into the parent of the destination paragraph.
CompositeNode dstStory = insertAfterNode.getParentNode();
// This object will be translating styles and lists during the import.
NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
// Loop through all block level nodes (paragraphs and tables) in the body of the section.
for (Node srcNode : (Iterable)srcSection.getBody())
{
// Let's skip the node if it is a last empty paragraph in a section.
if (srcNode.getNodeType() == (NodeType.PARAGRAPH))
{
Paragraph para = (Paragraph)srcNode;
if (para.isEndOfSection() && !para.hasChildNodes())
{
continue;
}
}
// This creates a clone of the node, suitable for insertion into the destination document.
Node newNode = importer.importNode(srcNode, true);
// Insert new node after the reference node.
dstStory.insertAfter(newNode, insertAfterNode);
insertAfterNode = newNode;
}
}
Hi,
Thanks for your message, I will try asap.
For the excepted result, we have to add all text/section found before the ‘Back’ bookmark.
Regards.
Hi Roseline,
I have modified the insertSection method. Please use the following insertSection method in your code.
public static void insertSection(Node insertAfterNode, Document srcDoc, DocumentBuilder builder, Section srcSection) throws Exception
{
// Make sure that the node is either a paragraph or table.
if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH)
& (insertAfterNode.getNodeType() != NodeType.TABLE))
{
throw new IllegalArgumentException("The destination node should be either a paragraph or table.");
}
builder.moveTo(insertAfterNode);
// We will be inserting into the parent of the destination paragraph.
CompositeNode dstStory = insertAfterNode.getParentNode();
// This object will be translating styles and lists during the import.
NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
// Loop through all block level nodes (paragraphs and tables) in the body of the section.
for (Node srcNode: (Iterable) srcSection.getBody())
{
if (srcNode.getNodeType() == (NodeType.BOOKMARK_START))
{
BookmarkStart bms = (BookmarkStart) srcNode;
if (bms.getName().equals("back"))
return;
}
// Let's skip the node if it is a last empty paragraph in a section.
if (srcNode.getNodeType() == (NodeType.PARAGRAPH))
{
Paragraph para = (Paragraph) srcNode;
if (para.isEndOfSection() && !para.hasChildNodes())
{
continue;
}
}
if (srcNode.isComposite() == true)
{
CompositeNode node = (CompositeNode) srcNode;
Node[] bookmark = node.getChildNodes(NodeType.BOOKMARK_START, true).toArray();
for (int i = 0; i <bookmark.length; i++)
{
if (((BookmarkStart) bookmark[i]).getName().equals("Back"))
return;
}
}
// This creates a clone of the node, suitable for insertion into the destination document.
Node newNode = importer.importNode(srcNode, true);
// Insert new node after the reference node.
dstStory.insertAfter(newNode, insertAfterNode);
insertAfterNode = newNode;
}
}
Hi,
Many thanks for your help.
Is it possible to adapt your code to remove the section which is cloned.
Because, in the doc file, there is twice ‘Landscape’ text.(A ‘Landscape’ text in the landscape page and a ‘Landscape’ text in the portrait page).
So I try to remove the section to be cloned but if I do that, I have no more ‘Landscape’ text:
I copied exactly all your code:
//This creates a clone of the node, suitable for insertion into the destination document.
Node newNode = importer.importNode(srcNode, true);
//Insert new node after the reference node.
dstStory.insertAfter(newNode, insertAfterNode);
srcNode.remove();
insertAfterNode = newNode;
Thanks in advance
Hi Roseline,
I have added another method RemoveSectionContents in the following code. This method remove the contents of section before bookmark “Back”. Please find the output document in attachment.
Document doc = new Document(new File("D:\\ Doc2.dot").getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
// Get HeaderFooter for Portrait layout
builder.moveToBookmark("back");
Bookmark changeOrientation = doc.getRange().getBookmarks().get("Change");
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section landscape = builder.getCurrentSection(); // NEW LINE
builder.writeln("Before Section break new page");
// Get the current section index to insert the landscape section after
int index = doc.getSections().indexOf(landscape);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section)doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
builder.moveTo(doc.getSections().get(index + 1).getBody().getFirstParagraph());
builder.writeln("After Section break new page");
Section importsec = (Section)doc.getSections().get(index + 2).deepClone(true);
//CompositeNode cloneNode = (CompositeNode)currNode.deepClone(true);
insertSection(builder.getCurrentParagraph(), doc, builder, importsec);
RemoveSectionContents(doc.getSections().get(index + 2));
doc.getFirstSection().remove();
builder.getDocument().save("D:\\ Result.doc");
public static void RemoveSectionContents(Section srcSection) throws Exception {
ArrayList nodes = new ArrayList();
for (Node srcNode : (Iterable) srcSection.getBody()) {
if(srcNode.isComposite() == true)
{
CompositeNode node = (CompositeNode)srcNode;
Node[] bookmark = node.getChildNodes(NodeType.BOOKMARK_START, true).toArray();
if(bookmark.length > 0)
{
nodes.add(srcNode);
System.out.println(srcNode.getNodeType());
for(int i = 0; i < bookmark.length; i++)
{
if (((BookmarkStart)bookmark[i]).getName().equals("Back"))
{
nodes.remove(nodes.size()-1);
// Now remove all nodes in the sequence.
for (Node noderemove : (Iterable) nodes)
{
noderemove.remove();
}
return;
}
}
}
else
nodes.add(srcNode);
}
}
}
public static void insertSection(Node insertAfterNode, Document srcDoc, DocumentBuilder builder, Section srcSection) throws Exception {
// Make sure that the node is either a paragraph or table.
if ((insertAfterNode.getNodeType() != NodeType.PARAGRAPH)
& (insertAfterNode.getNodeType() != NodeType.TABLE)) {
throw new IllegalArgumentException("The destination node should be either a paragraph or table.");
}
builder.moveTo(insertAfterNode);
// We will be inserting into the parent of the destination paragraph.
CompositeNode dstStory = insertAfterNode.getParentNode();
// This object will be translating styles and lists during the import.
NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.getDocument(), ImportFormatMode.KEEP_SOURCE_FORMATTING);
// Loop through all block level nodes (paragraphs and tables) in the body of the section.
for (Node srcNode : (Iterable) srcSection.getBody()) {
// Let's skip the node if it is a last empty paragraph in a section.
if (srcNode.getNodeType() == (NodeType.PARAGRAPH)) {
Paragraph para = (Paragraph) srcNode;
if (para.isEndOfSection() && !para.hasChildNodes()) {
continue;
}
}
if(srcNode.isComposite() == true)
{
CompositeNode node = (CompositeNode)srcNode;
Node[] bookmark = node.getChildNodes(NodeType.BOOKMARK_START, true).toArray();
for(int i = 0; i < bookmark.length; i++)
{
if (((BookmarkStart)bookmark[i]).getName().equals("Back"))
return;
}
}
// This creates a clone of the node, suitable for insertion into the destination document.
Node newNode = importer.importNode(srcNode, true);
// Insert new node after the reference node.
dstStory.insertAfter(newNode, insertAfterNode);
insertAfterNode = newNode;
}
}
Thank you very much for your help.
It is exactly the result I’ve excepted.
Hi,
With all code that you provided me, the result is ok.
But, if the ‘landscape’ section is in more than a page, then, the ‘text area’ is not copied in the other landscape page…
Can you explain why and how can i resolve it ?
Because I can not copy the collection of header/footer, because there are not header/footer but simulated header/footer in landscape layout.
Please find in attachment the .dot file and the following code.
Document doc = new Document(new File(“C:\Temp\Doc2.dot”).getAbsolutePath());
DocumentBuilder builder = new DocumentBuilder(doc);
builder.moveToBookmark(“back”);
Section portrait = builder.getCurrentSection();
Bookmark changeOrientation = doc.getRange().getBookmarks().get(“Change”);
// Go to the bookmark Change
builder.moveTo(changeOrientation.getBookmarkStart());
Section landscape = builder.getCurrentSection(); // NEW LINE
builder.writeln(“Before Section break new page”);
// Get the current section index to insert the landscape section
// after
int index = doc.getSections().indexOf(landscape);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
// Get the first section which is the rendering of the landscape
Section firstSection = doc.getFirstSection();
// Duplicate the first section
Section newSection = (Section) doc.importNode(firstSection, true);
// Insert the landscape section after the current section
builder.moveToSection(index + 1);
doc.getSections().insert(index + 1, newSection);
// The landscape header/footer is not link to previous
newSection.getHeadersFooters().linkToPrevious(false); // NEW LINE
doc.getSections().get(index + 1).getPageSetup().setOrientation(Orientation.LANDSCAPE);
builder.moveTo(doc.getSections().get(index + 1).getBody().getFirstParagraph());
builder.writeln(“After Section break new page”);
Section importsec = doc.getSections().get(index + 2);
insertSection(builder.getCurrentParagraph(), doc, builder, importsec);
RemoveSectionContents(doc.getSections().get(index + 2));
builder.moveTo(doc.getSections().get(index + 2).getBody().getFirstParagraph());
// Copy headers footers from previous portrait section
copyHeadersFootersFromPreviousSection(builder.getCurrentSection(), portrait);
doc.getFirstSection().remove();
builder.getDocument().save(“C:\Temp\Output.doc”);
Hi Roseline,
Thanks for your query. I will work on your query and will update you asap.
Hi Roseline,
I have modified the code for your scenario and have attached to this post. Hope this helps you. Please let us know if you have any more queries.