[]
Once the template layout is created, it needs to be bound to a data source to populate actual data in the Word document upon template processing. You can add a data source by using DataSources property of DataTemplate class.
GcWord supports the following data sources in Report Templates:
A single table which has collection of rows and columns from any type of database.
Template syntax
[Alias of data source].[Column name]
For example:
{{ds.ID}}
{{ds.Name}}
Bind DataTable datasource
var datasource = new System.Data.DataTable();
datasource.Columns.Add(new DataColumn("ID", typeof(Int32)));
datasource.Columns.Add(new DataColumn("Name", typeof(string)));
datasource.Columns.Add(new DataColumn("Score", typeof(Int32)));
datasource.Columns.Add(new DataColumn("Team", typeof(string)));
//Add data source
document.DataTemplate.DataSources.Add("ds", datasource);
A collection of one or more DataTables from any type of database.
Template syntax
[Alias of data source].[Table name].[Column name]
For example:
{{ds.Table1.ID}}
{{ds.Table2.Team}}
Bind DataSet datasource
var dTable1 = new System.Data.DataTable();
var dTable2 = new System.Data.DataTable();
...//Init data
var datasource = new System.Data.DataSet();
datasource.Tables.Add(team1);
datasource.Tables.Add(team2);
//Add data source
document.DataTemplate.DataSources.Add("ds", datasource);
A user-defined object from user code or serialized object of JSON String, File or XML etc. GcWord Template supports any data source that can be serialized as a custom object.
Template syntax
[Alias of data source].[Field path]
or
[Alias of data source].[Property path]
For example:
{{ds.Records.Area}}
{{{ds.Records.Product}}
Bind Custom Object datasource
var datasource = new SalesData
{
Records = new List()
};
var record1 = new SalesRecord
{
Area = "NorthChina",
Salesman = "Hellen",
Product = "Apple",
ProductType = "Fruit",
Sales = 120
};
datasource.Records.Add(record1);
var record2 = new SalesRecord
{
Area = "NorthChina",
Salesman = "Hellen",
Product = "Banana",
ProductType = "Fruit",
Sales = 143
};
datasource.Records.Add(record2);
...//Init data
//Add data source
document.DataTemplate.DataSources.Add("ds", datasource);
JSON objects (or JSON text) can be used as data source in GcWord Report Templates.
Template syntax
[Alias of data source].[Field path]
For example:
{{ds.ID}}
{{ds.Name}}
Bind JSON datasource
The template engine allows you to add the following object types as JSON data sources:
Newtonsoft.Json.Linq.JToken
Newtonsoft.Json.JsonReader
System.Text.Json.JsonElement
System.Text.Json.JsonDocument
System.ReadOnlyMemory (parsed as System.Text.Json.JsonDocument)
System.ReadOnlyMemory (parsed as System.Text.Json.JsonDocument)
System.ReadOnlySequence (parsed as System.Text.Json.JsonDocument)
System.IO.StreamReader (parsed as Newtonsoft.Json.Linq.JToken)
System.IO.Stream (parsed as Newtonsoft.Json.Linq.JToken)
System.String (It can be a JSON formatted string or a file name that contains JSON formatted string. It will be parsed as Newtonsoft.Json.Linq.JToken. If the string does not contain valid JSON, it will be interpreted as the path name of a .json file).
The below example code shows all the ways in which a JSON datasource can be bound to a template to populate data in the final Word documents.
// json file as data source
public void JsonFileDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
doc.DataTemplate.DataSources.Add("ds", @"c:\data.json");
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
// json string as data source
public void JsonStringDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
doc.DataTemplate.DataSources.Add("ds", "{\"name\": \"David\"}");
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
// json stream as data source
public void JsonStreamDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
using (Stream stream = File.OpenRead(@"c:\data.json"))
{
doc.DataTemplate.DataSources.Add("ds", stream);
}
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
// json stream reader as data source
public void JsonStreamReaderDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
using (StreamReader reader = File.OpenText(@"c:\data.json"))
{
doc.DataTemplate.DataSources.Add("ds", reader);
}
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
// json document as data source
public void JsonDocumentDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
System.Text.Json.JsonDocument jdoc = System.Text.Json.JsonDocument.Parse("{\"name\": \"David\"}");
doc.DataTemplate.DataSources.Add("ds", jdoc);
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
// json token as data source
public void JsonTokenDataSource()
{
var doc = new GcWordDocument();
doc.Load(@"c:\template.docx");
Newtonsoft.Json.Linq.JToken jtoken = Newtonsoft.Json.Linq.JToken.Parse("{\"name\": \"David\"}");
doc.DataTemplate.DataSources.Add("ds", jtoken);
doc.DataTemplate.Process();
doc.Save(@"c:\json.docx");
}
The template and output for JSON string, document and token code sample above will look like below:
A list is a collection of hetrogeneous data and elements while an array is a homogeneous collection of elements ordered in a sequence. In arrays and lists of unnamed entities of primitive types (Type.IsPrimitive = true) and strings, value of current element is represented by a virtual property named value.
Template syntax
[[Alias of data source].value] OR [#Alias of data source][[Alias of data source].value][/Alias of data source]]
For example:
{{ds.value}} OR {{#ds}}{{ds.value}}{{/ds}}
Bind List and Array datasource
var doc = new GcWordDocument();
// Add a simple List as data source:
doc.DataTemplate.DataSources.Add("dsStrs", new List()
{
"Pacific",
"Atlantic",
"Indian",
"Southern",
"Arctic",
});
// Add a simple array as data source:
doc.DataTemplate.DataSources.Add("dsInts", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
// Add a list template so that the data is formatted as a list:
var myListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "myListTemplate");
// Strings (oceans) List:
doc.Body.Paragraphs.Add("List of Strings (oceans):", doc.Styles[BuiltInStyleId.Heading1]);
var p = doc.Body.Paragraphs.Add("{{#dsStrs}}{{dsStrs.value}:toupper()}{{/dsStrs}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
A variable is a number, or a quantity that changes with time and can take different values in different situations.
Template syntax
[Alias of data source]
For example:
{{ds}}
Bind Variable datasource
var doc = new GcWordDocument();
// Add a variable as data sources:
string str = "Data Record";
doc.DataTemplate.DataSources.Add("dsConsts", str);
// Add a list template so that the data is formatted as a list:
var myListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "myListTemplate");
// Variable:
doc.Body.Paragraphs.Add("Variable Data:", doc.Styles[BuiltInStyleId.Heading1]);
var p = doc.Body.Paragraphs.Add("{{#dsConsts}}{{dsConsts.value}}{{/dsConsts}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
Note:
If template contains a field that does not exist in the bound data source, 'KeyNotFoundException' is thrown by default. However, this behavior can be controlled by setting MissingFieldsHandling property of the DataTemplateOptions class. Default value of this property is Strict which results into the aforementioned exception. To ignore the missing fields, you can set the property to Relaxed.
When MissingFieldsHandling property is set to Relaxed, the missing range templates are interpreted as empty ranges. To hide these empty ranges which are exposed as a single element, you can use the hide-block-if-empty() (hbi-empty()) formatter. For more information about formatters, see Formatters.