Exporting grid with templates in Syncfusion Blazor DataGrid
30 Apr 202524 minutes to read
The Syncfusion Blazor DataGrid offers the option to export the column, detail, and caption templates to an Excel document. The template contains images, hyperlinks, and customized text.
Exporting with column template
The Excel export functionality allows you to export Grid columns that include images, hyperlinks, and custom text to an Excel document.
To export the template columns into an Excel document, set the IncludeTemplateColumn property of the ExcelExportProperties to true in the OnToolbarClick event, and pass it to the ExportToExcelAsync or ExportToCsvAsync method.
The template values cannot be directly exported into the cells. To customize the values of the template columns in Excel document, you must use ExcelQueryCellInfoEvent event.
Excel Export supports base64 string to export the images.
The following sample demonstrates how to export template columns such as FirstName and EmailID into an Excel document:
@using Syncfusion.Blazor.Grids
<SfGrid ID="Grid" @ref="DefaultGrid" DataSource="@EmployeeData.GetAllRecords()" Toolbar="@(new List<string>() { "ExcelExport" })" AllowExcelExport="true" AllowPaging="true">
<GridEvents ExcelQueryCellInfoEvent="ExcelQueryCellInfoHandler" OnToolbarClick="ToolbarClickHandler" TValue="EmployeeData"></GridEvents>
<GridColumns>
<GridColumn Field=@nameof(EmployeeData.EmployeeID) HeaderText="Employee ID" TextAlign="TextAlign.Right" Width="120"></GridColumn>
<GridColumn Field=@nameof(EmployeeData.FirstName) HeaderText="Employee Name" Width="150">
<Template>
@{
var con = (context as EmployeeData);
}
<span>[email protected]</span>
</Template>
</GridColumn>
<GridColumn Field=@nameof(EmployeeData.EmailID) HeaderText="Email" Width="180">
<Template>
@{
var employee = (context as EmployeeData);
}
<a href="mailto:@employee.EmailID">@employee.EmailID</a>
</Template>
</GridColumn>
<GridColumn Field=@nameof(EmployeeData.Title) HeaderText="Title" Width="180"></GridColumn>
<GridColumn Field=@nameof(EmployeeData.City) HeaderText="City" Width="120"></GridColumn>
</GridColumns>
</SfGrid>
@code {
private SfGrid<EmployeeData> DefaultGrid;
public List<EmployeeData> Orders { get; set; }
public bool OrderDateVisible { get; set; } = false;
protected override void OnInitialized()
{
Orders = EmployeeData.GetAllRecords();
}
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Id == "Grid_excelexport") // Id is the combination of Grid's ID and item name.
{
ExcelExportProperties ExportProperties = new ExcelExportProperties();
ExportProperties.IncludeTemplateColumn = true;
await this.DefaultGrid.ExportToExcelAsync(ExportProperties);
}
}
public void ExcelQueryCellInfoHandler(ExcelQueryCellInfoEventArgs<EmployeeData> args)
{
if (args.Column.Field == "FirstName")
{
args.Cell.Value = "Mr." + args.Data.FirstName;
}
else if (args.Column.Field == "EmailID")
{
var email = args.Data.EmailID;
args.Cell.Value = $"<a href='mailto:{email}'>{email}</a>";
}
}
}
public class EmployeeData
{
public static List<EmployeeData> Employees = new List<EmployeeData>();
public EmployeeData(int employeeID, string firstName, string emailID, string title, string city)
{
EmployeeID = employeeID;
FirstName = firstName;
EmailID = emailID;
Title = title;
City = city;
}
public static List<EmployeeData> GetAllRecords()
{
if (Employees.Count == 0)
{
Employees.Add(new EmployeeData(1, "Davolio", "[email protected]", "Sales Representative", "Seattle"));
Employees.Add(new EmployeeData(2, "Fuller", "[email protected]", "Vice President, Sales", "Tacoma"));
Employees.Add(new EmployeeData(3, "Leverling", "[email protected]", "Sales Representative", "Kirkland"));
Employees.Add(new EmployeeData(4, "Peacock", "[email protected]", "Sales Manager", "London"));
Employees.Add(new EmployeeData(5, "Buchanan", "[email protected]", "Sales Manager", "Seattle"));
Employees.Add(new EmployeeData(6, "Suyama", "[email protected]", "Sales Representative", "Tokyo"));
Employees.Add(new EmployeeData(7, "King", "[email protected]", "Sales Representative", "London"));
Employees.Add(new EmployeeData(8, "Callahan", "[email protected]", "Inside Sales Coordinator", "Seattle"));
Employees.Add(new EmployeeData(9, "Dodsworth", "[email protected]", "Sales Representative", "London"));
}
return Employees;
}
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string EmailID { get; set; }
public string Title { get; set; }
public string City { get; set; }
}
Exporting with group caption template
The Syncfusion Blazor Grid allows you to export the Grid data along with a custom caption template into an Excel document. This feature can be useful when you want to provide meaningful group captions (e.g., count of records) in the exported Excel document.
To customize the caption text in the exported Excel document, you can handle the ExcelGroupCaptionTemplateInfo event. This event provides you with the necessary information to set the group caption in the exported Excel document, such as the group key, record count, and header text. Within the event, you can set a customized group caption using args.Cell.Value
property.
The following example demonstrates how the Grid is grouped by the CustomerID field and exports the Grid data to Excel document with a custom group caption template, utilizing the OnToolbarClick event and the ExportToExcelAsync method.
@using Syncfusion.Blazor.Grids
<SfGrid ID="Grid" @ref="Grid" DataSource="@GridData" AllowGrouping="true" Height="315px" Toolbar="@(new List<string>() { "ExcelExport" })" AllowExcelExport="true">
<GridEvents OnToolbarClick="ToolbarClickHandler" ExcelGroupCaptionTemplateInfo="ExcelGroupCaptionInfoHandler" TValue="OrderData"></GridEvents>
<GridColumns>
<GridColumn Field=@nameof(OrderData.OrderID) HeaderText="Order ID" TextAlign="TextAlign.Right" Width="90"></GridColumn>
<GridColumn Field=@nameof(OrderData.CustomerID) HeaderText="Customer Name" TextAlign="TextAlign.Right" Width="100"></GridColumn>
<GridColumn Field=@nameof(OrderData.Freight) HeaderText="Freight" Width="80"></GridColumn>
<GridColumn Field=@nameof(OrderData.ShipCity) HeaderText="Ship City" Width="100"></GridColumn>
</GridColumns>
<GridGroupSettings Columns=@(new string[] { "CustomerID" })>
<CaptionTemplate>
@{
var order = (context as CaptionTemplateContext);
<span>@order.Key - @order.Count Records : @order.HeaderText</span>
}
</CaptionTemplate>
</GridGroupSettings>
</SfGrid>
@code {
private SfGrid<OrderData> Grid;
public List<OrderData> GridData { get; set; }
protected override void OnInitialized()
{
GridData = OrderData.GetAllRecords(); // Replace with your actual data logic.
}
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Id == "Grid_excelexport") // Id is the combination of Grid's ID and item name.
{
if (args.Item.Id == "Grid_excelexport")
{
await Grid.ExportToExcelAsync();
}
}
}
public void ExcelGroupCaptionInfoHandler(ExcelCaptionTemplateArgs args)
{
args.Cell.Value = args.Key + "-" + args.Count + " Records: " + args.HeaderText;
}
}
public class OrderData
{
public OrderData(int orderID, string customerID, double freight, string shipCity)
{
this.OrderID = orderID;
this.CustomerID = customerID;
this.Freight = freight;
this.ShipCity = shipCity;
}
public static List<OrderData> GetAllRecords()
{
return new List<OrderData>
{
new OrderData(10248, "VINET", 32.38, "Reims"),
new OrderData(10249, "TOMSP", 11.61, "Münster"),
new OrderData(10250, "HANAR", 65.83, "Rio de Janeiro"),
new OrderData(10251, "VICTE", 41.34, "Lyon"),
new OrderData(10252, "SUPRD", 51.30, "Charleroi"),
new OrderData(10253, "HANAR", 58.17, "Rio de Janeiro"),
new OrderData(10254, "CHOPS", 22.98, "Bern"),
new OrderData(10255, "RICSU", 148.33, "Genève"),
new OrderData(10256, "WELLI", 13.97, "Resende"),
new OrderData(10257, "HILAA", 81.91, "San Cristóbal"),
new OrderData(10258, "ERNSH", 140.51, "Graz"),
new OrderData(10259, "CENTC", 3.25, "México D.F."),
new OrderData(10260, "OTTIK", 55.09, "Köln"),
new OrderData(10261, "QUEDE", 3.05, "Rio de Janeiro"),
new OrderData(10262, "RATTC", 48.29, "Albuquerque"),
new OrderData(10263, "ERNSH", 76.56, "Graz"),
new OrderData(10264, "FOLKO", 67.10, "Bräcke"),
new OrderData(10265, "BLONP", 36.65, "Strasbourg"),
new OrderData(10266, "WARTH", 27.19, "Stavanger"),
new OrderData(10267, "FRANK", 65.83, "München")
};
}
public int OrderID { get; set; }
public string CustomerID { get; set; }
public double Freight { get; set; }
public string ShipCity { get; set; }
}
Exporting with detail template
The Syncfusion Blazor DataGrid provides the capability to export both parent and child (detail) records, including nested data, to an Excel document. By default, the Grid exports the parent Grid along with expanded detail rows only. To customize the exporting behavior, utilize the ExcelExportProperties.ExcelDetailRowMode property within the OnToolbarClick event, and pass it to the ExportToExcelAsync or ExportToCsvAsync method. The available options include:
Mode | Behavior |
---|---|
Expand | Exports the parent Grid with expanded detail rows. |
Collapse | Exports the parent Grid with collapsed detail rows. |
None | Exports the parent Grid alone. |
You can customize and format the detail rows in the exported Excel document using the ExcelDetailTemplateExporting event. In this event, the detail rows of the Excel document are formatted in accordance with their parent row details.
In the following example, the detail row content is formatted by specifying the Headers, Rows using parent row details, facilitating the creation of detail rows within the Excel document. Additionally, custom styles can be applied to specific cells using the Style property.
@using Syncfusion.Blazor.Grids
<SfGrid @ref="Grid" ID="Grid" DataSource="@Employees" Toolbar="@(new List<string>() { "ExcelExport" })" AllowExcelExport="true" Height="450px">
<GridTemplates>
<DetailTemplate>
@{
var employee = (context as ProductData);
<table class="detailtable" width="100%">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<thead>
<tr>
<th colspan="2" style="font-weight: 500;text-align: center;background-color: #ADD8E6;">
Product Details
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">
<span>@employee.ProductDesc</span>
</td>
<td>
<span class="link">
Contact: <a href="mailto:${@employee.Contact}">@employee.Contact</a>
</span>
</td>
</tr>
<tr>
<td style="text-align: center;">
<span style="font-weight: 500;"> @employee.Cost</span>
</td>
<td>
<span>Available: @employee.Available </span>
</td>
</tr>
<tr>
<td style="text-align: center;">
<span class="@((employee.Status == "Available") ? "available" : "unavailable")" style="font-weight: 500;"> @employee.Status</span>
</td>
<td>
<span>@employee.ReturnPolicy</span>
</td>
</tr>
<tr>
<td style="text-align: center;">
<span style="font-weight: 500;color: #0a76ff;">Offers: @employee.Offers </span>
</td>
<td>
<span>@employee.Cancellation</span>
</td>
</tr>
<tr>
<td style="text-align: center;">
<span style="font-weight: 500;color: #0a76ff;"> Ratings: @employee.Ratings</span>
</td>
<td>
<span style="font-weight: 500;color: #0a76ff;">@employee.Delivery</span>
</td>
</tr>
</tbody>
</table>
}
</DetailTemplate>
</GridTemplates>
<GridEvents ExcelDetailTemplateExporting="ExcelDetailTemplateHandler" OnToolbarClick="ToolbarClickHandler" TValue="ProductData"></GridEvents>
<GridColumns>
<GridColumn Field=@nameof(ProductData.Category) HeaderText="Category" Width="110"> </GridColumn>
<GridColumn Field=@nameof(ProductData.ProductID) HeaderText="Product ID" Width="160"> </GridColumn>
<GridColumn Field=@nameof(ProductData.Status) HeaderText="Status" Width="180"></GridColumn>
</GridColumns>
</SfGrid>
<style type="text/css" class="cssStyles">
.detailtable td {
font-size: 13px;
padding: 4px;
max-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: normal;
}
.unavailable {
color: #FF0000;
}
.available {
color: #00FF00;
}
</style>
@code {
private SfGrid<ProductData> Grid;
public List<ProductData> Employees { get; set; }
protected override void OnInitialized()
{
Employees = ProductData.GetAllRecords();
}
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Id == "Grid_excelexport") // Id is the combination of Grid's ID and item name.
{
ExcelExportProperties ExportProperties = new ExcelExportProperties();
ExportProperties.ExcelDetailRowMode = ExcelDetailRowMode.Expand;
await Grid.ExportToExcelAsync(ExportProperties);
}
}
public void ExcelDetailTemplateHandler(ExcelDetailTemplateEventArgs<ProductData> args)
{
// Initialize a list to hold detail template rows for the Excel export.
var excelRows = new List<ExcelDetailTemplateRow>();
// Get the parent row's data.
var data = args.ParentRow.Data;
// Set the header row for the detail template.
args.RowInfo.Headers = new List<ExcelDetailTemplateRow>() {
new ExcelDetailTemplateRow() {
Cells = new List<ExcelDetailTemplateCell>() {
new ExcelDetailTemplateCell() {
Index = 0,
CellValue = "Product Details",
ColumnSpan = 2,
Style = new ExcelStyle() {
Bold = true, BackColor = "#ADD8E6"
}
}
}
}
};
// Add the first row with product description and contact as a hyperlink.
excelRows.Add(new ExcelDetailTemplateRow()
{
Cells = new List<ExcelDetailTemplateCell>()
{
new ExcelDetailTemplateCell()
{
CellValue = data.ProductDesc, Index = 0
},
new ExcelDetailTemplateCell()
{
Index = 1, Hyperlink = new Hyperlink() { DisplayText = data.Contact, Target = data.Contact }
}
}
});
excelRows.Add( new ExcelDetailTemplateRow()
{
Cells = new List<ExcelDetailTemplateCell>()
{
new ExcelDetailTemplateCell()
{
CellValue = data.Cost, Index = 0
},
new ExcelDetailTemplateCell()
{
Index = 1, CellValue = "Available :" + data.Available
}
}
});
// Add the second row with product cost and availability status.
excelRows.Add(new ExcelDetailTemplateRow()
{
Cells = new List<ExcelDetailTemplateCell>()
{
new ExcelDetailTemplateCell()
{
CellValue = data.Status, Index = 0,
Style = new ExcelStyle()
{
FontColor = data.Status == "Available" ? "#00FF00" : "#FF0000"
}
},
new ExcelDetailTemplateCell()
{
Index = 1, CellValue = data.ReturnPolicy
}
}
});
// Add the third row with product status and return policy.
excelRows.Add(new ExcelDetailTemplateRow()
{
Cells = new List<ExcelDetailTemplateCell>()
{
new ExcelDetailTemplateCell()
{
CellValue = "Offers :" + data.Offers, Index = 0, Style = new ExcelStyle()
{
FontColor = "#0A76FF", FontSize = 12
}
},
new ExcelDetailTemplateCell()
{
Index = 1, CellValue = data.Cancellation
}
}
});
// Add the fifth row with product ratings and delivery information.
excelRows.Add(new ExcelDetailTemplateRow()
{
Cells = new List<ExcelDetailTemplateCell>()
{
new ExcelDetailTemplateCell()
{
CellValue = "Ratings: " + data.Ratings, Index = 0, Style = new ExcelStyle()
{
FontColor = "#0A76FF", FontSize = 12
}
},
new ExcelDetailTemplateCell()
{
Index = 1, CellValue = data.Delivery, Style = new ExcelStyle()
{
FontColor = "#0A76FF", FontSize = 12
}
}
}
});
// Assign the customized detail rows to the RowInfo.
args.RowInfo.Rows = excelRows;
}
}
public class ProductData
{
public static List<ProductData> Products = new List<ProductData>();
public ProductData(string category, string offers, string cost, string available, string itemID, string productID,
string contact, string status, string productDesc, string returnPolicy,
string delivery, string cancellation, string ratings)
{
Category = category;
Offers = offers;
Cost = cost;
Available = available;
ItemID = itemID;
ProductID = productID;
Contact = contact;
Status = status;
ProductDesc = productDesc;
ReturnPolicy = returnPolicy;
Delivery = delivery;
Cancellation = cancellation;
Ratings = ratings;
}
public string Category { get; set; }
public string Offers { get; set; }
public string Cost { get; set; }
public string Available { get; set; }
public string ItemID { get; set; }
public string ProductID { get; set; }
public string Contact { get; set; }
public string Status { get; set; }
public string ProductDesc { get; set; }
public string ReturnPolicy { get; set; }
public string Delivery { get; set; }
public string Cancellation { get; set; }
public string Ratings { get; set; }
public static List<ProductData> GetAllRecords()
{
if (Products.Count == 0)
{
Products.Add(new ProductData("Suits/Slim", "5%", "199.99$", "10", "Suit-001", "EJ-SU-01", "[email protected]", "Available", "Slim Fit Suit", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.5"));
Products.Add(new ProductData("Suits/Classic", "12%", "249.99$", "8", "Suit-002", "EJ-SU-02", "[email protected]", "Available", "Classic Fit Suit", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.8"));
Products.Add(new ProductData("Suits/Formal", "5%", "149.99$", "15", "Suit-003", "EJ-SU-03", "[email protected]", "Available", "Formal Fit Suit", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.7"));
Products.Add(new ProductData("Pants/Slim", "10%", "19.99$", "50", "Pant-001", "EJ-PA-01", "[email protected]", "Available", "Slim Fit Pants", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.2"));
Products.Add(new ProductData("Pants/Casual", "15%", "25.99$", "35", "Pant-002", "EJ-PA-02", "[email protected]", "Available", "Casual Cotton Pants", "Return within 7 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.4"));
Products.Add(new ProductData("Shirts/Formal", "8%", "39.99$", "20", "Shirt-001", "EJ-SH-01", "[email protected]", "Available", "Formal Cotton Shirt", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.6"));
Products.Add(new ProductData("Shirts/Casual", "10%", "29.99$", "60", "Shirt-002", "EJ-SH-02", "[email protected]", "Available", "Casual Check Shirt", "Return within 15 days", "** FREE Delivery **", "Cancellation upto 48 hrs", "4.3"));
Products.Add(new ProductData("Shirts/Denim", "6%", "49.99$", "25", "Shirt-003", "EJ-SH-03", "[email protected]", "Available", "Denim Shirt", "Return within 10 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.1"));
Products.Add(new ProductData("Jackets/Leather", "18%", "199.99$", "5", "Jacket-001", "EJ-JA-01", "[email protected]", "Available", "Leather Jacket", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 6 hrs", "4.9"));
Products.Add(new ProductData("Jackets/Bomber", "20%", "129.99$", "12", "Jacket-002", "EJ-JA-02", "[email protected]", "Available", "Bomber Jacket", "Return within 7 days", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.6"));
Products.Add(new ProductData("T-Shirts/Graphic", "10%", "19.99$", "80", "TShirt-001", "EJ-TS-01", "[email protected]", "Available", "Graphic Tee", "Return within 15 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.5"));
Products.Add(new ProductData("T-Shirts/Plain", "5%", "14.99$", "90", "TShirt-002", "EJ-TS-02", "[email protected]", "Available", "Plain T-Shirt", "Return within 10 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.2"));
Products.Add(new ProductData("T-Shirts/Sports", "12%", "24.99$", "70", "TShirt-003", "EJ-TS-03", "[email protected]", "Available", "Sports Tee", "Return within 7 days", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.7"));
Products.Add(new ProductData("Jeans/Skinny", "15%", "59.99$", "30", "Jeans-001", "EJ-JE-01", "[email protected]", "Available", "Skinny Fit Jeans", "Return within 15 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.6"));
Products.Add(new ProductData("Jeans/Straight", "8%", "54.99$", "40", "Jeans-002", "EJ-JE-02", "[email protected]", "Available", "Straight Cut Jeans", "Return within 10 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.4"));
Products.Add(new ProductData("Sweaters/Wool", "10%", "34.99$", "18", "Sweater-001", "EJ-SW-01", "[email protected]", "Available", "Woolen Sweater", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 6 hrs", "4.3"));
Products.Add(new ProductData("Sweaters/Cotton", "7%", "29.99$", "22", "Sweater-002", "EJ-SW-02", "[email protected]", "Available", "Cotton Sweater", "Return within 10 days", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.2"));
Products.Add(new ProductData("Blazers/Formal", "14%", "89.99$", "10", "Blazer-001", "EJ-BL-01", "[email protected]", "Available", "Formal Blazer", "Return within 5 days", "** FREE Delivery **", "Cancellation upto 6 hrs", "4.7"));
Products.Add(new ProductData("Blazers/Casual", "10%", "79.99$", "14", "Blazer-002", "EJ-BL-02", "[email protected]", "Available", "Casual Blazer", "No Returns Applicable", "** FREE Delivery **", "Cancellation upto 12 hrs", "4.5"));
Products.Add(new ProductData("Hoodies/Zip", "0%", "39.99$", "0", "Hoodie-001", "EJ-HO-01", "[email protected]", "Unavailable", "Zip-up Hoodie", "Return within 10 days", "** FREE Delivery **", "Cancellation upto 24 hrs", "4.6"));
}
return Products;
}
}
Exporting hierarchical Grid using detail template
The Syncfusion Blazor DataGrid allows you to export hierarchical Grid data to Excel document using the detail template feature. This is particularly useful for scenarios where data is nested within parent rows (such as employee details and their related orders), and you need to export both the parent and child records to a single Excel document.
You can customize and format the detail rows in the exported Excel document using the ExcelDetailTemplateExporting event. In this event, the detail rows of the Excel document are formatted in accordance with their parent row details.
In the following example, the detail row content is formatted by specifying the Headers, Rows using parent row details. Additionally, this achieves a nested level of children using the ChildRowInfo property and the ExcelExportProperties.ExcelDetailRowMode property, which is set to Expand to export the parent Grid with expanded detail rows within the OnToolbarClick event. This property is then passed to the ExportToExcelAsync method:
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.Data
<SfGrid @ref="Grid" ID="Grid" DataSource="@Employees" AllowExcelExport="true" Toolbar="@(new List<string>() { "ExcelExport"})">
<GridTemplates>
<DetailTemplate>
@{
var employee = (context as EmployeeData);
}
<SfGrid DataSource="@Orders" Query="@(new Query().Where("EmployeeID", "equal", employee.EmployeeID))">
<GridTemplates>
<DetailTemplate Context="CustomerContext">
@{
var customer = (CustomerContext as Order);
}
<SfGrid DataSource="@OrderInfo" TValue="OrderDetails" Query="@(new Query().Where("OrderID", "equal", customer.OrderID))">
<GridColumns>
<GridColumn Field=@nameof(OrderDetails.CustomerID) HeaderText="Customer ID" TextAlign="TextAlign.Right" Width="110"> </GridColumn>
<GridColumn Field=@nameof(OrderDetails.Title) HeaderText="Title" Width="110"></GridColumn>
<GridColumn Field=@nameof(OrderDetails.Address) HeaderText="Address" TextAlign="TextAlign.Right" Width="90" Format="C2"></GridColumn>
<GridColumn Field=@nameof(OrderDetails.Country) HeaderText="Country" Width="110"></GridColumn>
</GridColumns>
</SfGrid>
</DetailTemplate>
</GridTemplates>
<GridColumns>
<GridColumn Field=@nameof(Order.OrderID) HeaderText="Order ID" TextAlign="TextAlign.Right" Width="110"> </GridColumn>
<GridColumn Field=@nameof(Order.CustomerID) HeaderText="Customer Name" Width="110"></GridColumn>
<GridColumn Field=@nameof(Order.Freight) HeaderText="Freight" TextAlign="TextAlign.Right" Width="90" Format="C2"></GridColumn>
<GridColumn Field=@nameof(Order.ShipCity) HeaderText="Ship City" Width="110"></GridColumn>
</GridColumns>
</SfGrid>
</DetailTemplate>
</GridTemplates>
<GridEvents ExcelDetailTemplateExporting="ExcelDetailTemplateHandler" OnToolbarClick="ToolbarClickHandler" TValue="EmployeeData"></GridEvents>
<GridColumns>
<GridColumn Field=@nameof(EmployeeData.EmployeeID) HeaderText="EmployeeID" Width="110"> </GridColumn>
<GridColumn Field=@nameof(EmployeeData.FirstName) HeaderText="First Name" Width="110"> </GridColumn>
<GridColumn Field=@nameof(EmployeeData.Title) HeaderText="Title" Width="110"></GridColumn>
<GridColumn Field=@nameof(EmployeeData.Country) HeaderText="Country" Width="110"></GridColumn>
</GridColumns>
</SfGrid>
@code {
private SfGrid<EmployeeData> Grid;
public List<EmployeeData> Employees { get; set; }
public List<OrderDetails> OrderInfo { get; set; }
public static List<Order> Orders { get; set; }
protected override void OnInitialized()
{
Employees = EmployeeData.GetAllRecords();
Orders = Order.GetAllRecords();
OrderInfo = OrderDetails.GetAllRecords();
}
// Handles toolbar click event (for Excel export).
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
// Id is the combination of Grid's ID and item name.
if (args.Item.Id == "Grid_excelexport")
{
ExcelExportProperties ExportProperties = new ExcelExportProperties();
// Specify that detailed rows should be expanded.
ExportProperties.ExcelDetailRowMode = ExcelDetailRowMode.Expand;
// Export the data to Excel document.
await Grid.ExportToExcelAsync(ExportProperties);
}
}
// Customizes the Excel detail export for each employee.
public void ExcelDetailTemplateHandler(ExcelDetailTemplateEventArgs<EmployeeData> args)
{
var excelRows = new List<ExcelDetailTemplateRow>();
// Fetch all orders for the current employee.
var data = Orders.ToList().Where(_ => _.EmployeeID == args.ParentRow.Data.EmployeeID).ToList();
for (var i = 0; i < data.Count(); i++)
{
var row = data[i];
// Fetch all order details for the current order.
var childData = OrderInfo.ToList().Where(_ => _.OrderID == row.OrderID).ToList();
var excelchildRows = new List<ExcelDetailTemplateRow>();
// For each order (parent row), create a new Excel row with specific columns.
var excelRow = ProcessExcelRow(new List<string>() {
row.OrderID.ToString(),
row.CustomerID.ToString(),
row.Freight.ToString(),
row.ShipCity
});
// For each order detail (child row), create an Excel row with the following details.
for (var j = 0; j < childData.Count; j++)
{
var childRow = childData[j];
excelchildRows.Add(ProcessExcelRow(new List<string>() {
childRow.CustomerID.ToString(),
childRow.Title.ToString(),
childRow.Address.ToString(),
childRow.Country
}));
}
// Add the child rows under the parent row.
excelRow.ChildRowInfo = new ExcelDetailTemplateRowSettings()
{
// Set headers for child rows (order details).
Headers = new List<ExcelDetailTemplateRow>()
{
ProcessExcelRow(new List<string>() { "Customer Name", "Title", "Address", "Country" })
},
// Set the child rows (the actual order details).
Rows = excelchildRows
};
// Add the row to the list of rows for this employee's orders.
excelRows.Add(excelRow);
}
// Set the parent row headers (order-related information).
args.RowInfo.Headers = new List<ExcelDetailTemplateRow>()
{
ProcessExcelRow(new List<string>() { "Order ID", "Customer ID", "Freight", "Ship City" })
};
// Set the final row data (parent and child rows) for the Excel export.
args.RowInfo.Rows = excelRows;
}
// Converts a list of cell values into an Excel row.
ExcelDetailTemplateRow ProcessExcelRow(List<string> value)
{
var cells = new List<ExcelDetailTemplateCell>();
// Populate each cell with the corresponding value.
for (var j = 0; j < value.Count(); j++)
{
cells.Add(new ExcelDetailTemplateCell {
CellValue = $"{value[j]}",
Index = j // Set the index of each cell.
});
}
// Return the Excel row with its cells.
return new ExcelDetailTemplateRow { Cells = cells };
}
}
public class EmployeeData
{
public EmployeeData(int employeeID, string firstName, string title, string city, string country)
{
this.EmployeeID = employeeID;
this.FirstName = firstName;
this.Title = title;
this.City = city;
this.Country = country;
}
public static List<EmployeeData> GetAllRecords()
{
return new List<EmployeeData>
{
new EmployeeData(1, "Nancy", "Sales Representative", "Texas", "USA"),
new EmployeeData(2, "Andrew", "Vice President", "London", "UK"),
new EmployeeData(3, "Janet", "Sales", "London", "UK"),
new EmployeeData(4, "Margaret", "Sales Manager", "London", "UK"),
new EmployeeData(5, "Steven", "Inside Sales Coordinator", "Vegas", "USA"),
new EmployeeData(6, "Smith", "HR Manager", "Dubai", "UAE"),
new EmployeeData(7, "Steven", "Inside Sales Coordinator", "Paris", "France"),
new EmployeeData(8, "Smith", "HR Manager", "Mumbai", "India"),
new EmployeeData(9, "Smith", "HR Manager", "Chennai", "India")
};
}
public int EmployeeID { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
public class Order
{
public Order(int employeeID, int orderID, string customerID, string shipCity, double freight)
{
this.EmployeeID = employeeID;
this.OrderID = orderID;
this.CustomerID = customerID;
this.ShipCity = shipCity;
this.Freight = freight;
}
public static List<Order> GetAllRecords()
{
return new List<Order>
{
new Order(1, 1001, "Nancy", "Texas", 2.1 * 1),
new Order(2, 1002, "Andrew", "London", 2.1 * 2),
new Order(3, 1003, "Janet", "London", 2.1 * 3),
new Order(4, 1004, "Margaret", "London", 2.1 * 4),
new Order(5, 1005, "Steven", "Vegas", 2.1 * 5),
new Order(6, 1006, "Smith", "Dubai", 2.1 * 6),
new Order(7, 1007, "Steven", "Paris", 2.1 * 7),
new Order(8, 1008, "Smith", "Mumbai", 2.1 * 8),
new Order(9, 1009, "Smith", "Chennai", 2.1 * 9),
new Order(2, 1010, "Smith", "Chennai", 2.1 * 9),
new Order(3, 1011, "Smith", "Chennai", 2.1 * 9),
new Order(3, 1012, "Smith", "Chennai", 2.1 * 9)
};
}
public int EmployeeID { get; set; }
public int OrderID { get; set; }
public string CustomerID { get; set; }
public string ShipCity { get; set; }
public double Freight { get; set; }
}
public class OrderDetails
{
public OrderDetails(int orderID, string title, string customerID, string country, string address)
{
this.OrderID = orderID;
this.Title = title;
this.CustomerID = customerID;
this.Country = country;
this.Address = address;
}
public static List<OrderDetails> GetAllRecords()
{
return new List<OrderDetails>
{
new OrderDetails(1001, "Sales Representative", "Nancy", "Germany", "Obere Str. 57"),
new OrderDetails(1002, "HR Manager", "Andrew", "Mexico", "Avda. de la Constitución 2222"),
new OrderDetails(1003, "Vice President", "Janet", "Mexico", "Mataderos 2312"),
new OrderDetails(1004, "Inside Sales Coordinator", "Margaret", "Mexico", "Mataderos 2312"),
new OrderDetails(1005, "HR Manager", "Steven", "Spain", "C/ Araquil, 67"),
new OrderDetails(1006, "Vice President", "Smith", "Mexico", "Avda. de la Constitución 2222"),
new OrderDetails(1007, "Sales", "Steven", "France", "24, place Kléber"),
new OrderDetails(1008, "HR Manager", "Smith", "Spain", "C/ Araquil, 67"),
new OrderDetails(1009, "Sales", "Smith", "Mexico", "Mataderos 2312"),
new OrderDetails(1010, "Vice President", "Smith", "Spain", "C/ Araquil, 67"),
new OrderDetails(1011, "Inside Sales Coordinator", "Smith", "Mexico", "Mataderos 2312"),
new OrderDetails(1012, "HR Manager", "Smith", "India", "45A")
};
}
public int OrderID { get; set; }
public string Title { get; set; }
public string CustomerID { get; set; }
public string Country { get; set; }
public string Address { get; set; }
}