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…

ContSecBreak

…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<SectionProperties>().FirstOrDefault();
        SectionType secType = secNext.Elements<SectionType>().FirstOrDefault();
        if (secType==null) {
            secType = new SectionType { Val=SectionMarkValues.Continuous};
            secNext.InsertAt(secType, 0); }
        else {
            secType.Val = SectionMarkValues.Continuous; }

        Paragraph pFirst = b.Descendants<Paragraph>().FirstOrDefault();

        //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<Run>().FirstOrDefault();
        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<ParagraphProperties>().FirstOrDefault(); 
        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<Run>().FirstOrDefault();
        LastRenderedPageBreak brk = new LastRenderedPageBreak();
        Text t = r.Elements<Text>().FirstOrDefault();
        r.InsertBefore(brk, t);
        pNew2.InsertAfterSelf(pNew1);
        //Remove the original paragraph at the end.
        pFirst.RemoveAllChildren();
        pFirst.Remove();
    }
}
2 Responses to “Open XML SDK: Continuous section break in the middle of a paragraph”
  1. Syed Abbas says:

    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.

    • wordmeister says:

      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.

  2.  
Leave a Reply


Network-wide options by YD - Freelance Wordpress Developer