This content originally appeared on Telerik Blogs and was authored by Dimitar Karamfilov
Explore what’s possible with the nested mail merge function with this home library demo.
Nested mail merge allows you to handle complex mail merge scenarios. It is useful when your data source contains properties that are business objects or collections of such objects, and you want to access their properties when performing the mail merge. This comes in handy when creating tables as well.
In this blog post, we will create a complete example of how to use this feature. We will begin by creating a sample business object, create a document in the code and finally perform the mail merge and save the resulting document.
The example creates a representation of a home library which catalogs books with their author, their description and their position.
Creating Our Library
We can start by creating the business object that will represent the home library. We will have two objects—an object that will hold the book details and an object that will hold the entire library. The books are separated by genre.
class
HomeLibrary
{
public
List<BookDetails> Fiction {
get
; }
public
List<BookDetails> NonFiction {
get
; }
public
List<BookDetails> Kids {
get
; }
public
HomeLibrary()
{
this
.Fiction =
new
List<BookDetails>();
this
.NonFiction =
new
List<BookDetails>();
this
.Kids =
new
List<BookDetails>();
}
}
class
BookDetails
{
public
BookDetails(
string
title,
string
description,
string
position,
string
author)
{
Title = title;
Description = description;
Position = position;
this
.Author = author;
}
public
string
Title {
get
;
set
; }
public
string
Description {
get
;
set
; }
public
string
Position {
get
;
set
; }
public
string
Author {
get
;
set
; }
}
Now we can create a sample library that contains some books. In this example, the data is stored in CSV files and the properties are separated by the “#” character. The GetLibraryFromFile method reads the CSV files line by line and creates the book detail objects.
public
static
HomeLibrary CreateSampleLibrary()
{
HomeLibrary library =
new
HomeLibrary();
var nonFiction = GetLibraryFromFile(@
"..\..\..\NonFiction.csv"
);
library.NonFiction.AddRange(nonFiction);
var fiction = GetLibraryFromFile(@
"..\..\..\Fiction.csv"
);
library.Fiction.AddRange(fiction);
var kids = GetLibraryFromFile(@
"..\..\..\Kids.csv"
);
library.Kids.AddRange(kids);
return
library;
}
public
static
List<BookDetails> GetLibraryFromFile(
string
path)
{
List<BookDetails> library =
new
List<BookDetails>();
string
separtor =
"#"
;
StreamReader readFile =
new
StreamReader(path);
string
line;
string
[] row;
while
((line = readFile.ReadLine()) !=
null
)
{
if
(
string
.IsNullOrEmpty(line))
{
continue
;
}
row = line.Split(separtor, StringSplitOptions.RemoveEmptyEntries);
BookDetails details =
new
BookDetails(row[0], row[2], row[3], row[1]);
library.Add(details);
}
readFile.Close();
return
library;
}
Once we have the sample library that is populated with data, we can start creating the document. For each of the genres in our library, we will create a table. Each table will have rows for each book inside the genre and columns with the specific book details.
The AddTable method creates a table and adds the columns, then adds the nested mail merge fields as well. The first and the last merge fields are the key to this functionality. You need to start with the TableStart field followed by the name of the property that you want to access. Then you can access the underlying properties like in a regular merge field.
When done with the insertion of the fields related to the properties, you need to add a merge field with the TableEnd keyword followed by the same property name as well. More information about this is available in our documentation: Mail Merge.
static
void
Main(
string
[] args)
{
RadFlowDocument document =
new
();
document.StyleRepository.AddBuiltInStyle(BuiltInStyleNames.GetHeadingStyleIdByIndex(1));
document.StyleRepository.AddBuiltInStyle(BuiltInStyleNames.GetHeadingStyleIdByIndex(2));
RadFlowDocumentEditor editor =
new
(document);
Run heading = editor.InsertText(
"Listing the articles in my home library"
);
heading.Paragraph.StyleId =
"Heading1"
;
AddTable(document, editor,
"NonFiction"
);
AddTable(document, editor,
"Fiction"
);
AddTable(document, editor,
"Kids"
);
var collection =
new
List<HomeLibrary> { CreateSampleLibrary() };
var mergedDocument = document.MailMerge(collection);
DocxFormatProvider provider =
new
DocxFormatProvider();
File.WriteAllBytes(@
"..\..\..\my_library.docx"
, provider.Export(mergedDocument));
}
private
static
void
AddTable(RadFlowDocument document, RadFlowDocumentEditor editor,
string
libraryName)
{
editor.InsertParagraph();
var run = editor.InsertText(libraryName);
run.Paragraph.StyleId =
"Heading2"
;
var table = editor.InsertTable(2, 4);
table.PreferredWidth =
new
TableWidthUnit(TableWidthUnitType.Percent, 100);
document.StyleRepository.AddBuiltInStyle(BuiltInStyleNames.TableGridStyleId);
table.StyleId = BuiltInStyleNames.TableGridStyleId;
AddTextToCelll(table.Rows[0].Cells[0],
"Title"
,
true
);
AddTextToCelll(table.Rows[0].Cells[1],
"Author"
,
true
);
AddTextToCelll(table.Rows[0].Cells[2],
"Description"
,
true
);
AddTextToCelll(table.Rows[0].Cells[3],
"Position"
,
true
);
AddFieldToCelll(table.Rows[1].Cells[0], editor,
"MERGEFIELD TableStart:"
+ libraryName);
AddFieldToCelll(table.Rows[1].Cells[0], editor,
"MERGEFIELD Title"
);
AddFieldToCelll(table.Rows[1].Cells[1], editor,
"MERGEFIELD Author"
);
AddFieldToCelll(table.Rows[1].Cells[2], editor,
"MERGEFIELD Description"
);
AddFieldToCelll(table.Rows[1].Cells[3], editor,
"MERGEFIELD Position"
);
AddFieldToCelll(table.Rows[1].Cells[3], editor,
"MERGEFIELD TableEnd:"
+ libraryName);
editor.MoveToTableEnd(table);
editor.InsertParagraph();
}
private
static
void
AddFieldToCelll(TableCell tableCell, RadFlowDocumentEditor editor,
string
fieldCode)
{
Paragraph paragraph;
if
(tableCell.Blocks.Count == 0)
{
paragraph = tableCell.Blocks.AddParagraph();
editor.MoveToParagraphStart(paragraph);
}
else
{
paragraph = tableCell.Blocks.Last()
as
Paragraph;
editor.MoveToParagraphEnd(paragraph);
}
editor.InsertField(fieldCode,
""
);
}
public
static
void
AddTextToCelll(TableCell cell,
string
text,
bool
isbold)
{
var run = cell.Blocks.AddParagraph().Inlines.AddRun(text);
if
(isbold)
{
run.FontWeight = FontWeights.Bold;
}
}
We are ready to test our project and examine the results. The merged document will have three tables—one for each genre in our library.
Try It and Share Your Feedback
No matter if you are already familiar with Telerik Document Processing or will meet the libraries for the first time, hurry up and get the latest bits so you can take advantage of the different document management possibilities they provide:
And I am sure I have told you many times that your input is valuable. We do listen. So, do not be shy—drop us a line to share your feedback in the comments section below or directly in our Document Processing Libraries Feedback Portal.
This content originally appeared on Telerik Blogs and was authored by Dimitar Karamfilov
Dimitar Karamfilov | Sciencx (2022-04-14T15:15:03+00:00) Nested Mail Merge Comes to RadWordsProcessing Library in R1 2022. Retrieved from https://www.scien.cx/2022/04/14/nested-mail-merge-comes-to-radwordsprocessing-library-in-r1-2022/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.