How to reset page numbers for record in ASP.NET Core DocIO during mail merge?
Syncfusion® Essential® DocIO is a .NET Core Word library used to create, read, and edit Word documents programmatically without Microsoft Word or Interop dependencies. Using this library, you can reset page numbers after each record in Word document during mail merge in C#.
How to design input Word document template
In your template add the place holder (#SectionBreak#) at the end of each group to indicate where to insert a section break and customize the template Word document as shown in the highlighted text below.
Steps to reset page numbers after each record in Word document during mail merge
- Create a new C# .NET Core console application project.
- Install the Syncfusion.DocIORenderer.Net.Core NuGet package as a reference to your .NET Core applications from NuGet.org.
- Include the following namespace in the Program.cs file.
C#
using Syncfusion.DocIO; using Syncfusion.DocIO.DLS; using Syncfusion.DocIORenderer;
- In your sample application, below steps need to be followed to reset page numbers after each record in Word document during mail merge in C#.
- Open the template Word document.
- Execute the mail merge in the Word document.
- Split each record into sections by finding the place holder (#SectionBreak#).
- Enable the RestartPageNumbering flag and set the PageStartingNumber to reset page numbers after each record in Word document.
- Save the output Word document.
4.1 Use the following code snippet to open the template Word document.
C#
//Open the input Word document. using (WordDocument document = new WordDocument(fileStream,FormatType.Automatic))
4.2 Use the following code snippet to perform mail merge in a Word document.
C#
#region Perform the mail merge //Get the employee details as “IEnumerable” collection. List<Employee> employeeList = GetEmployees(); //Create an instance of MailMergeDataTable by specifying MailMerge group name and IEnumerable collection. MailMergeDataTable dataSource = new MailMergeDataTable("Employees", employeeList); //Perform Mail merge. document.MailMerge.ExecuteGroup(dataSource); #endregion
4.2.1 Use the following helper method and class to get employees details to perform the mail merge.
C#
/// <summary> /// Get the employee details to perform mail merge. /// </summary> public static List<Employee> GetEmployees() { List<Employee> employees = new List<Employee>(); employees.Add(new Employee("Nancy", "Smith", "1", "Sales Representative", "505 - 20th Ave. E. Apt. 2A,", "Seattle", "WA", "USA")); employees.Add(new Employee("Andrew", "Fuller", "2", "Vice President, Sales", "908 W. Capital Way", "Tacoma", "WA", "USA")); employees.Add(new Employee("Roland", "Mendel", "3", "Sales Representative", "722 Moss Bay Blvd.", "Kirkland", "WA", "USA")); return employees; } /// <summary> /// Represent a class to maintain employee details. /// </summary> public class Employee { public string FirstName { get; set; } public string LastName { get; set; } public string EmployeeID { get; set; } public string Address { get; set; } public string City { get; set; } public string Region { get; set; } public string Country { get; set; } public string Title { get; set; } public Employee(string firstName, string lastName, string employeeId, string title, string address, string city, string region, string country) { FirstName = firstName; LastName = lastName; EmployeeID = employeeId; Title = title; Address = address; City = city; Region = region; Country = country; } }
4.3 Use the following code snippet to split each record into sections by finding the placeholder #SectionBreak#.
C#
#region Split Word document by sections //Find all the occurance of place holder - #SectionBreak#. TextSelection[] selections = document.FindAll("#SectionBreak#", false, false); //Loop through all the text selection for (int i = selections.Length - 1; i >= 0; i--) { TextSelection selection = selections[i]; //Get the owner paragraph of the selected text. WParagraph para = selection.GetAsOneRange().OwnerParagraph; WSection srcSection = document.LastSection; //Insert section break InsertSectionBreak(para, srcSection); WSection curSection = GetSection(para); //Remove the place holder. curSection.Body.ChildEntities.Remove(para); } #endregion
4.3.1 Use the following helper method to insert section break and split each record into sections.
C#
/// <summary> /// Insert Section break code /// </summary> private static WSection InsertSectionBreak(TextBodyItem bodyItem, WSection srcSection) { //Get the current section of the body item var currentSection = GetSection(bodyItem); // Identify all the items in the same Section that are positioned after the bodyItem. These body items need to be cut and pasted to the new section. int numBodyItemsToStay = GetIndex(bodyItem) + 1; var entityCollection = currentSection.Body.ChildEntities; var bodyItemsToMove = entityCollection.Cast<TextBodyItem>() .Skip(numBodyItemsToStay) .ToList(); //Create a new section that is positioned after the current section. var newSection = new WSection(bodyItem.Document); //Update the section properties of the template document. CopySectionProperties(newSection, srcSection); //Add new section as a sibling of current section AddSiblings(currentSection, new[] { newSection }); // Cut and paste each marked body item from the current section to the new section. foreach (var bodyItemToMove in bodyItemsToMove) { newSection.Body.ChildEntities.Add(bodyItemToMove); } return newSection; } /// <summary> /// Get the index of the particular entity /// </summary> private static int GetIndex(IEntity entity) { ICompositeEntity container = entity.Owner as ICompositeEntity; if (container == null) { throw new ApplicationException("Entity is not index-able as it does not have a valid container."); } return container.ChildEntities.IndexOf(entity); } /// <summary> /// Get the section of the specified entity /// </summary> private static WSection GetSection(IEntity entity) { if (entity is WSection) { return (WSection)entity; } if (entity is WordDocument) { throw new ApplicationException("WordDocument does not belong to any sections."); } // Traverse the tree bottom-up until the Section is found. IEntity parentEntity = entity.Owner; while (parentEntity != null) { if (parentEntity is WSection) { return (WSection)parentEntity; } parentEntity = parentEntity.Owner; } // Unable to find the Section this entity belongs to. This entity is most likely not attached to any containers yet. return null; } /// <summary> /// Copy page section properties. /// </summary> private static void CopySectionProperties(IWSection newSection, IWSection srcSection) { //Update section break code. newSection.BreakCode = srcSection.BreakCode; //Update column size. foreach (Column column in srcSection.Columns) { newSection.AddColumn(column.Width, column.Space); } } /// <summary> /// Add new section as sibling of current section /// </summary> public static void AddSiblings<T>(IEntity entity, IEnumerable<T> newSiblings) where T : class, IEntity { int newIndex = GetIndex(entity) + 1; ICompositeEntity container = entity.Owner as ICompositeEntity; if (container == null) { throw new ApplicationException("Unable to add new siblings to this entity as it does not have a valid container."); } foreach (var newSibling in newSiblings) { container.ChildEntities.Insert(newIndex++, newSibling); } }
4.4 Use the following code snippet to enable the RestartPageNumbering flag and set the PageStartingNumber to reset page numbers after each record in Word document.
C#
#region Reset the page number //Iterate each section from Word document. foreach (WSection section in document.Sections) { //Reset the page number. section.PageSetup.RestartPageNumbering = true; section.PageSetup.PageStartingNumber = 1; } //Updates fields in Word document. document.UpdateDocumentFields(true); #endregion
4.5 Use the following code snippet to save the output Word document.
C#
//Save the Word document to file stream. document.Save(outputStream, FormatType.Docx);
A complete working sample to reset page numbers after each record in Word document during mail merge in C# can be downloaded from GitHub.
By executing the program, you will get the output document as follows.
Take a moment to peruse the documentation, where you can find basic Word document processing options along with the features like mail merge, merge and split documents, find and replace text in the Word document, protect the Word documents, and most importantly, the PDF and Image conversions with code examples.
Explore more about the rich set of Syncfusion® Word Framework features.
See Also:
How to replace merge field with HTML string using Mail merge
How to perform mail merge in Word document using image from URL
Conclusion
I hope you enjoyed learning about how to reset page numbers for each record in Word document during mail merge.
You can refer to our ASP.NET Core DocIO’s feature tour page to know about its other groundbreaking feature representations. You can also explore our ASP.NET Core DocIO documentation to understand how to present and manipulate data.
For current customers, you can check out our ASP.NET Core components from the License and Downloads page. If you are new to Syncfusion®, you can try our 30-day free trial to check out our ASP.NET Core DocIO and other ASP.NET Core components.
If you have any queries or require clarifications, please let us know in the comment section below. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!