Add Sections, Subsections and its contents dynamically

Hi,

I am trying to create subsections dynamically under a section and add data/content under the created subsection.

Is there away to create a subsection under named/specified Section directly ? Also way to access the created subsection to add title and data/content under it ?

Currently I am trying to get the Section by doing the following but the subsections are not added at the expected Section where the bookmark belongs rather gets added under the last section in the file.

Paragraph para = new Paragraph(doc);
para.ParagraphFormat.StyleName = "Heading 2";
Body body = new Body(doc);
body.AppendChild(para);
Run run = new Run(doc);
run.Text = section_heading;
para.AppendChild(run);

docBuilder.MoveToBookmark("bookmark_inword_under_mainsection");
docBuilder.CurrentSection.Body.AppendChild(para);

Is there a way to get named sections and appendChild to a named section instead of only docBuilder.CurrentSection.Body.AppendChild

Any help would be really appreciated!

Thanks

@PradnyaR Section in MS Word document is not a content under Heading paragraph. This is node in the Document Object Model that has it’s own page setup, headers and footers.
In your case if you simply need to put content at the bookmark, you can use code like this:

docBuilder.MoveToBookmark("bookmark_inword_under_mainsection");
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
docBuilder.Write("section_heading");

If you need further assistance, please attach your input and expected output documents. We will check them and provide you more information.

Thanks Alexey. That worked! But the headings created are printing in reverse order.

For example : The list iterated is Head1, Head2, Head3 and created subsections with about patch.

Output:
2 Main_Section_Title

2.1 Head3
This paragraph belongs to Subsection_3. …

2.2 Head2
This paragraph belongs to Subsection_2. …

2.3 Head1
This paragraph belongs to Subsection_1. …

Expected :

2 Main_Section_Title

2.1 Head1
This paragraph belongs to Subsection_1. …

2.2 Head2
This paragraph belongs to Subsection_2. …

2.3 Head3
This paragraph belongs to Subsection_3. …

@PradnyaR Please change this line of code:

docBuilder.MoveToBookmark("bookmark_inword_under_mainsection");

to this:

docBuilder.MoveToBookmark("bookmark_inword_under_mainsection", true, false);

In this case DocumentBuilder's cursor will be placed before the bookmark and order will be correct.

Hi Alexey, this helped! Thank you. But another issue, it not numbering the headings, meaning the

Output:

2 Main_Section_Title

Head1
This paragraph belongs to Subsection_1. …

Head2
This paragraph belongs to Subsection_2. …

Head3
This paragraph belongs to Subsection_3. …

Expected:

2 Main_Section_Title

2.1 Head1
This paragraph belongs to Subsection_1. …

2.2 Head2
This paragraph belongs to Subsection_2. …

2.3 Head3
This paragraph belongs to Subsection_3. …

I have ‘2 Main_Section_Title’ with ‘Heading2’ format in the word template and added the bookmark ‘bookmark_inword_under_mainsection’ under it where my subsection headings are listed now and in the program to get the numbered list, used ‘docBuilder.ListFormat.ListIndent();’ as indicated in the following patch but still no numbered list. Can you help ? Thanks

//Switches to second level in the list.
docBuilder.ListFormat.ListIndent();
docBuilder.MoveToBookmark("bookmark_inword_under_mainsection", true, false);
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
// Print Section Heading
docBuilder.Write(section_heading);
// Print Table
docBuilder. InsertHtml(reportResHtml);
doc.UpdateFields();

@PradnyaR In your case, you should define a list in heading styles. For example see the following code:

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder docBuilder = new DocumentBuilder(doc);

// Create a list for heading paragraphs.
List lst = doc.Lists.Add(ListTemplate.OutlineLegal);

// Apply numbering to the heading styles.
doc.Styles[StyleIdentifier.Heading1].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading1].ListFormat.ListLevelNumber = 0;
doc.Styles[StyleIdentifier.Heading2].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading2].ListFormat.ListLevelNumber = 1;
doc.Styles[StyleIdentifier.Heading3].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading3].ListFormat.ListLevelNumber = 2;
doc.Styles[StyleIdentifier.Heading4].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading4].ListFormat.ListLevelNumber = 3;

// Insert subheadings.
docBuilder.MoveToBookmark("bookmark_inword_under_mainsection", true, false);
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
docBuilder.Write("section_heading 2");
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;
docBuilder.Write("section_heading 3");
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading4;
docBuilder.Write("section_heading 4");

doc.Save(@"C:\Temp\out.docx")

Thanks Alexey, but the above is achieved by following patch as per my numbering requirement.

//Switches to second level in the list.
docBuilder.ListFormat.List = doc.Lists.Add(Aspose.Words.Lists.ListTemplate.NumberArabicDot);
docBuilder.ListFormat.ListLevelNumber = 2;
docBuilder.ListFormat.ListIndent();

But with this, the issue I am facing is the sections inserted at the bookmark are not replacing bookmark area (content) rather it is taking the bookmark line as another section heading at the last heading in the list. I am struggling to get rid of that extra blank section heading.

Deatils: My Document is designed as following

image.png (5.1 KB)

and output is
image.png (10.9 KB)

Any help, much appreciated !

@PradnyaR Most likely the problem occurs because an empty heading paragraph is inserted. But it is difficult to tell you for sure using screenshots. Could you please attach your real documents? We ill check the issues and provide you more information.
If you use DocumentBuilder.Writeln method in insert your heading paragraphs content, you should call DocumentBuilder.ParagraphFormat.ClearFormatting() after the last call to reset heading style for the empty paragraph generated by DocumentBuilder.Writeln.

Hi Alexey,

This worked. Thanks :slight_smile:

DocumentBuilder.ParagraphFormat.ClearFormatting() after the last call to reset heading style for the empty paragraph really helped. Thanks a tone!

In my case, I am checking if its the last heading being printed and accordingly skip printing DocumentBuilder.Writeln . So this was ok. But if you see the patch given earlier (again attached here below) has docBuilder. InsertHtml(reportResHtml); (a data table created through xsl and inserted as the content of the resp. subsections) and this is causing the issue. Somehow it adds Writeln and hence was creating an empty paragraph and hence the empty subsection.

NOTE: I have also now tried defining a list in heading styles as described by you in the example earlier and that too helped but of couse with DocumentBuilder.ParagraphFormat.ClearFormatting()

//Switches to second level in the list.
docBuilder.ListFormat.ListIndent();
docBuilder.MoveToBookmark("bookmark_inword_under_mainsection", true, false);
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
// Print Section Heading
docBuilder.Write(section_heading);
// Print Table
docBuilder. InsertHtml(reportResHtml);
doc.UpdateFields();

Now, just that my section number are of format for example 2.4. and I want 2.4 only (without a dot at the end of the number) if you have any solution, kindly provide. Thanks again.

@PradnyaR

  1. You can use HtmlInsertOptions.RemoveLastEmptyParagraph to avoid an empty paragraph after inserting HTML into the document:
builder.InsertHtml(html, HtmlInsertOptions.RemoveLastEmptyParagraph);
  1. In the code Default numbering template is used. You can adjust numbering format to fit your needs. For example see the following code:
Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder docBuilder = new DocumentBuilder(doc);

// Create a list for heading paragraphs.
List lst = doc.Lists.Add(ListTemplate.OutlineLegal);
lst.ListLevels[0].NumberFormat = "\0";
lst.ListLevels[1].NumberFormat = "\0.\u0001";
lst.ListLevels[2].NumberFormat = "\0.\u0001.\u0002";
lst.ListLevels[3].NumberFormat = "\0.\u0001.\u0002.\u0003";

// Apply numbering to the heading styles.
doc.Styles[StyleIdentifier.Heading1].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading1].ListFormat.ListLevelNumber = 0;
doc.Styles[StyleIdentifier.Heading2].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading2].ListFormat.ListLevelNumber = 1;
doc.Styles[StyleIdentifier.Heading3].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading3].ListFormat.ListLevelNumber = 2;
doc.Styles[StyleIdentifier.Heading4].ListFormat.List = lst;
doc.Styles[StyleIdentifier.Heading4].ListFormat.ListLevelNumber = 3;

// Insert subheadings.
docBuilder.MoveToBookmark("bookmark_inword_under_mainsection", true, false);
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;
docBuilder.Write("section_heading 2");
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;
docBuilder.Write("section_heading 3");
docBuilder.Writeln();
docBuilder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading4;
docBuilder.Write("section_heading 4");

doc.Save(@"C:\Temp\out.docx");

Thanks for your support!