1+ using Syncfusion . DocIO ;
2+ using Syncfusion . DocIO . DLS ;
3+
4+ namespace MailMerge_Results_in_Two_Columns
5+ {
6+ class Program
7+ {
8+ public static void Main ( string [ ] args )
9+ {
10+ using ( FileStream fileStream = new FileStream ( Path . GetFullPath ( @"Data/Template.docx" ) , FileMode . Open , FileAccess . Read ) )
11+ {
12+ using ( WordDocument document = new WordDocument ( fileStream , FormatType . Docx ) )
13+ {
14+ // Get student data
15+ List < StudentsGroup > studentParentList = GetStudentData ( ) ;
16+ //Create mail merge data table
17+ MailMergeDataTable dataTable = new MailMergeDataTable ( "Studentsparent" , studentParentList ) ;
18+ // Execute nested mail merge
19+ document . MailMerge . ExecuteNestedGroup ( dataTable ) ;
20+ // Split the document into sections based on tables
21+ List < WSection > sections = SplitSectionsByTable ( document ) ;
22+ // Clear existing sections in the document
23+ document . Sections . Clear ( ) ;
24+ //Added newly created sections into the document.
25+ foreach ( WSection section in sections )
26+ {
27+ document . Sections . Add ( section ) ;
28+ }
29+ using ( FileStream outputFileStream = new FileStream ( Path . GetFullPath ( @"../../../Output/Result.docx" ) , FileMode . Create , FileAccess . ReadWrite ) )
30+ {
31+ //Saves the Word document to file stream.
32+ document . Save ( outputFileStream , FormatType . Docx ) ;
33+ }
34+ }
35+ }
36+ }
37+ /// <summary>
38+ /// Splits the given Word document section into multiple sections based on tables.
39+ /// </summary>
40+ /// <param name="document">The Word document to split</param>
41+ /// <returns>A list of sections created from the document.</returns>
42+ private static List < WSection > SplitSectionsByTable ( WordDocument document )
43+ {
44+ // Initialize a list to hold the new sections
45+ List < WSection > sections = new List < WSection > ( ) ;
46+ // Iterate through all sections in the document
47+ foreach ( WSection section in document . Sections )
48+ {
49+ // Clone the current section.
50+ WSection clonedSection = section . Clone ( ) ;
51+ // Clear child entities from the cloned section.
52+ clonedSection . Body . ChildEntities . Clear ( ) ;
53+ // Create a new section from the cloned section.
54+ WSection newSection = clonedSection . Clone ( ) ;
55+ // Get the text body of the current section.
56+ WTextBody textBody = section . Body ;
57+ // Iterate through each child entity in the Text Body
58+ for ( int i = 0 ; i < textBody . ChildEntities . Count ; i ++ )
59+ {
60+ //Accesses the body items (should be either paragraph, table or block content control) as IEntity
61+ IEntity bodyItemEntity = textBody . ChildEntities [ i ] ;
62+ // Decides the element type by using EntityType
63+ switch ( bodyItemEntity . EntityType )
64+ {
65+ case EntityType . Paragraph :
66+ // Clone and add the paragraph to the new section
67+ WParagraph paragraph = bodyItemEntity as WParagraph ;
68+ newSection . Body . ChildEntities . Add ( paragraph . Clone ( ) ) ;
69+ break ;
70+ case EntityType . Table :
71+ // Mark the first row of the table as a header
72+ ( bodyItemEntity as WTable ) . Rows [ 0 ] . IsHeader = true ;
73+ // Add a paragraph to separate sections
74+ newSection . AddParagraph ( ) ;
75+ // Add the current section to the collection
76+ sections . Add ( newSection ) ;
77+ // Create a new section for the table
78+ newSection = clonedSection . Clone ( ) ;
79+ newSection . BreakCode = SectionBreakCode . NoBreak ;
80+ // Setup columns (optional)
81+ float spacing = 20 ;
82+ float colWidth = newSection . PageSetup . ClientWidth / 2 - spacing ;
83+ newSection . AddColumn ( colWidth , spacing ) ;
84+ newSection . Columns [ 0 ] . Width = colWidth ;
85+ // Clone and add the table to the new section
86+ newSection . Body . ChildEntities . Add ( bodyItemEntity . Clone ( ) ) ;
87+ sections . Add ( newSection ) ;
88+ // Reset newSection for further processing
89+ newSection = clonedSection . Clone ( ) ;
90+ break ;
91+ case EntityType . BlockContentControl :
92+ // Clone and add the block content control to the new section
93+ BlockContentControl blockContentControl = bodyItemEntity as BlockContentControl ;
94+ newSection . Body . ChildEntities . Add ( ( BlockContentControl ) blockContentControl . Clone ( ) ) ;
95+ break ;
96+ }
97+ }
98+ }
99+ // Return the list of newly created sections
100+ return sections ;
101+ }
102+ /// <summary>
103+ /// Gets the Student details to perform mail merge
104+ /// </summary>
105+ /// <returns></returns>
106+ public static List < StudentsGroup > GetStudentData ( )
107+ {
108+ List < Student > students = new List < Student > ( ) ;
109+ List < Student > students1 = new List < Student > ( ) ;
110+ List < Student > students2 = new List < Student > ( ) ;
111+ for ( int i = 1 ; i <= 45 ; i ++ )
112+ {
113+ students . Add ( new Student
114+ {
115+ RollNo = $ "{ i } ",
116+ AdmissionNo = $ "ADM{ i : 000} ",
117+ StudentName = $ "Class 1A Student { i } ",
118+ Marks = $ "M{ i : 000} ",
119+ } ) ;
120+ }
121+ for ( int i = 1 ; i <= 45 ; i ++ )
122+ {
123+ students1 . Add ( new Student
124+ {
125+ RollNo = $ "{ i } ",
126+ AdmissionNo = $ "ADM{ i : 000} ",
127+ StudentName = $ "Class 2A Student { i } ",
128+ Marks = $ "M{ i : 000} ",
129+ } ) ;
130+ }
131+ for ( int i = 1 ; i <= 45 ; i ++ )
132+ {
133+ students2 . Add ( new Student
134+ {
135+ RollNo = $ "{ i } ",
136+ AdmissionNo = $ "ADM{ i : 000} ",
137+ StudentName = $ "Class 2B Student { i } ",
138+ Marks = $ "M{ i : 000} ",
139+ } ) ;
140+ }
141+ // Wrap in parent group
142+ List < StudentsGroup > parentList = new List < StudentsGroup >
143+ {
144+ new StudentsGroup {
145+ Class = "1#A" ,
146+ Exam = "MidTerm" ,
147+ Students = students
148+ } ,
149+ new StudentsGroup {
150+ Class = "2#A" ,
151+ Exam = "MidTerm" ,
152+ Students = students1
153+ } ,
154+ new StudentsGroup {
155+ Class = "2#B" ,
156+ Exam = "MidTerm" ,
157+ Students = students2
158+ }
159+ } ;
160+
161+ return parentList ;
162+ }
163+ }
164+ /// <summary>
165+ /// Represents a class to maintain Student details
166+ /// </summary>
167+ public class Student
168+ {
169+ public string RollNo { get ; set ; }
170+ public string AdmissionNo { get ; set ; }
171+ public string StudentName { get ; set ; }
172+ public string Marks { get ; set ; }
173+ }
174+ public class StudentsGroup
175+ {
176+ public string Class { get ; set ; }
177+ public string Exam { get ; set ; }
178+ public List < Student > Students { get ; set ; }
179+ }
180+ }
0 commit comments