Open XML SDK: Continuous section break in the middle of a paragraph
In my last post I described how to achieve a continuous section break in Word Open XML. In this post, I go into how to force the continuous section break in the middle of a paragraph.
Section breaks are inserted by creating a SectionProperties element within a Paragraph element. The SectionType determines whether the break will be Continuous, Next Page, Even Page or Odd Page. Only the first of these can be located within a paragraph. That this presents a logical problem is clear, since the SectionProperties must be a child element of a Paragraph.
Building on the XML in my previous post, you can see that I’ve added the Run and Text child elements to the first paragraph with the text “Before section break”. This is followed by an additional paragraph. Inside the Run you can see the element <w:lastRenderedPageBreak/>. The Open XML SDK documentation doesn’t even hint that the LastRenderedPageBreak is also used to trigger the visual display of a continuous section break within a paragraph…
<w:p><w:pPr><w:sectPr w:rsidR=”0008038F” w:rsidSect=”00C26E80″>
<w:type w:val=”continuous”/>
<w:pgSz w:w=”11906″ w:h=”16838″/>
<w:pgMar w:gutter=”0″ w:footer=”708″ w:header=”708″ w:left=”1417″ w:bottom=”1134″ w:right=”1417″ w:top=”1417″/>
<w:cols w:space=”708″/><w:docGrid w:linePitch=”360″/>
</w:sectPr></w:pPr>
<w:r><w:t>Before section break </w:t></w:r></w:p>
<w:p>
<w:r>
<w:lastRenderedPageBreak/>
<w:t xml:space=”preserve”> after section break</w:t
></w:r>
</w:p>
Here’s the result of the XML…
…and here is the code used to add such a section break to an existing document. It does not produce the sample XML code, above. It inserts a continuous section break after the first run of the first paragraph in the document.
private void btnContSecBrk_Click(object sender, EventArgs e)
{
string fileName = @"C:\Test\DocSecBreaks.docx";
using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(fileName, true))
{
Body b = pkgDoc.MainDocumentPart.Document.Body;
//The type of following section break determines
//the type of preceding section break.
SectionProperties secNext = b.Descendants
SectionType secType = secNext.Elements
if (secType==null) {
secType = new SectionType { Val=SectionMarkValues.Continuous};
secNext.InsertAt(secType, 0); }
else {
secType.Val = SectionMarkValues.Continuous; }
Paragraph pFirst = b.Descendants
//In order to position the section break within a paragraph, there
//actually needs to be a new paragraph that follows the section break.
//That, in combination with LastRenderedPageBreak,
//creates a section break within a paragraph.
//Make a copy of the first paragraph, then break it into two parts.
//After splitting the paragraph for the section break
//the original will be deleted.
Paragraph pNew1 = (Paragraph) pFirst.CloneNode(true);
Paragraph pNew2 = new Paragraph();
pFirst.InsertAfterSelf(pNew2);
//First para contains the first run of the original paragraph,
//which consists of multiple runs.
Run rFirstWord = pNew1.Elements
pNew2.Append(rFirstWord.CloneNode(true));
//Add the continuous section break to the first paragraph.
SectionProperties secProps = new SectionProperties(new SectionType
{ Val = SectionMarkValues.Continuous },
new PageSize { Height = 16838, Width = 11906 });
ParagraphProperties pProps =
pNew2.Elements
if (pProps == null)
{
pProps = new ParagraphProperties();
pNew2.InsertAt(pProps, 0);
}
pProps.Append(secProps);
//Second paragraph contains all but first run of original,
//So that first run original with its child elements
//can be removed from the cloned paragraph.
rFirstWord.RemoveAllChildren();
rFirstWord.Remove();
//The LastRenderedPageBreak will be inserted
//before the first Run of the cloned paragraph.
Run r = pNew1.Elements
LastRenderedPageBreak brk = new LastRenderedPageBreak();
Text t = r.Elements
r.InsertBefore(brk, t);
pNew2.InsertAfterSelf(pNew1);
//Remove the original paragraph at the end.
pFirst.RemoveAllChildren();
pFirst.Remove();
}
}
November 17th, 2015 at 14:52
Hi,
I have implemented the same solution to render multiple component documents in a master document in content controls. Only problem I am facing is if a component document has multiple column in end then content control block spills to next page as blank. If I remove that blank page then multiple column formatting is lost.
Multiple Column functionality if you inspect in Draft View is achieved by Section Breaks (OOB) by word.
Any help will be great.
November 17th, 2015 at 18:23
I recommend you ask this question in the Open XML SDK forum on MSDN: https://social.msdn.microsoft.com/Forums/office/en-US/home?forum=oxmlsdk. When you post, please specify whether the content control is part of the text in the columns or whether the columns are inside the content control. And where the section break is in relation to content control and columns. Perhaps it would be best if you copy the relevant part of document.xml into your question.
August 30th, 2013 at 16:54
Hi,
Very helpful article, believe me I didn’t get the help from the whole wide world of google but from you.
Using your code I have achieved the functionality.
I have a template which has two pages and through code I am inserting new pages with sdtBlock on each page and then in an Ad-In I am replacing the sdtBlock’s url (another document) with content of that another document.
I am facing some challenges.
1. When first time I run your code first sdt block is coming on the second page of template and then break is inserted. (I have changed to Val = SectionMarkValues.NextPage)
2. When I add sdtBlock on a page it spans to the next page so when I change the orientation of 3rd page it changes the orientation of the 4th Page too.
Appreciate your help in advance.
September 3rd, 2013 at 12:46
Note, please, that the topic of this blog post was specifically CONTINUOUS section breaks. It is not possible to insert a NewPage section break in the middle of a paragraph. Possibly, that explains the behavior you’re seeing in (1).
Beyond that, there’s not nearly enough information to even begin to guess what may be going on with (2) and how this blog article relates to that issue.
Please post your questions as two separate questions in the Open XML SDK forum on MSDN http://social.msdn.microsoft.com/Forums/office/en-US/home?forum=oxmlsdk. Please provide a description about what you’re bringing in in these sdtBlock nodes, how you expect the resulting document should be, include a link to any code you’re referencing and include your code.