Test in a live environment
Test in production without watermarks.
Works wherever you need it to.
ASP.NET developers often seek efficient ways to present tabular data or HTML tables with advanced features such as sorting, searching, and pagination. DataTables.NET is a powerful jQuery, JavaScript library, and highly flexible tool that facilitates the creation of interactive and feature-rich tables in web applications. In this article, we'll explore how to integrate DataTables.NET distribution files, a table-enhancing library for server-side processing into an ASP.NET project to enhance the presentation and user experience of tabular data.
DataTables.NET is a jQuery JavaScript library that allows you to create and manipulate interactive tables in .NET applications. It is based on the jQuery DataTables plug-in, which provides comprehensive API features like pagination, sorting, filtering, and scrolling for dynamic as well as static HTML tables. It is a table-enhancing library that can work with various data sources, such as SQL databases, AJAX, or in-memory objects.
Consider a scenario where you have an API endpoint delivering a vast dataset of products. The standard approach involves jQuery DataTables making an AJAX call to this API, obtaining a list of products in JSON format, and rendering an HTML table. This is known as client-side processing, which is efficient for smaller datasets, typically ranging from 100 to 1000 records. However, what happens when the dataset expands to 10,000 records or more?
When dealing with a substantial number of records, it becomes impractical to send the entire dataset to the browser in one go. Transmitting 10,000 records at once is not only wasteful in terms of bandwidth but also strains browser resources. In such cases, an alternative approach, server-side processing, becomes crucial for optimizing performance.
In server-side processing, rather than sending the entire dataset, the API transmits data in manageable chunks, typically paginated with around 50 records per page. By doing this, the load time is significantly improved, as jQuery DataTables now loads a modest number of records (~50) instead of dealing with the entire dataset at once. This approach reduces CPU and bandwidth usage, creating a more efficient interaction between the API and the DataTable.
In this article, we will explore the implementation of server-side processing in an ASP.NET Razor Page application, demonstrating how to efficiently handle and display extensive datasets while enhancing the overall performance of your web application.
To get started we need to add the DataTables.NET Client Side Library to our project. This article will use the ASP.NET Core Web App (Razor Pages) project with .NET 8. You may use any Web App Project as per your requirements.
To add a Client-Side Library, right-click on Solution>Add> Client Side Library, and search for data tables as shown below.
Now, we need to add Model Class, DB Context, Controller, HTML table, and AJAX Call.
But before that, we need to install EntityFramework Nuget Packages to connect our application with the Database. This article will use the Code First Approach, you may use Database first as per your preference.
Install the following locally hosted packages:
Install the above package by using the install-package command from the NuGet Package Manager Console, or install it from the NuGet Package Manager solution by searching it.
I am using Product Model Class for this example, you may use it as per your requirement.
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; } = string.Empty;
public string ProductPrice { get; set; } = string.Empty;
public string ProductWeight { get; set; } = string.Empty;
public string ProductDescription { get; set; } = string.Empty;
public DateTime ProductManufacturingDate { get; set; }
public DateTime ProductExpiryDate { get; set; }
}
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; } = string.Empty;
public string ProductPrice { get; set; } = string.Empty;
public string ProductWeight { get; set; } = string.Empty;
public string ProductDescription { get; set; } = string.Empty;
public DateTime ProductManufacturingDate { get; set; }
public DateTime ProductExpiryDate { get; set; }
}
Public Class Product
Public Property Id() As Integer
Public Property ProductName() As String = String.Empty
Public Property ProductPrice() As String = String.Empty
Public Property ProductWeight() As String = String.Empty
Public Property ProductDescription() As String = String.Empty
Public Property ProductManufacturingDate() As DateTime
Public Property ProductExpiryDate() As DateTime
End Class
public class ApplicationDBContext : DbContext
{
public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
}
public class ApplicationDBContext : DbContext
{
public ApplicationDBContext(DbContextOptions<ApplicationDBContext> options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
}
Public Class ApplicationDBContext
Inherits DbContext
Public Sub New(ByVal options As DbContextOptions(Of ApplicationDBContext))
MyBase.New(options)
End Sub
Public Property Products() As DbSet(Of Product)
End Class
We will add the ProductDatatables.js inside the wwwroot>js folder for adding advanced controls such as pagination, search, etc.
//add advanced interaction controls
$(document).ready(function () {
$("#productDatatable").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"ajax": {
"url": "/api/Product",
"type": "POST",
"datatype": "json"
},
"columnDefs": [{
"targets": [0].data,
"visible": false,
"searchable": false
}],
"columns": [
{ "data": "id", "name": "Id", "autoWidth": true },
{ "data": "productName", "name": "ProductName", "autoWidth": true },
{ "data": "productPrice", "name": "ProductPrice", "autoWidth": true },
{ "data": "productWeight", "name": "ProductWeight", "autoWidth": true },
{ "data": "productDescription", "name": "ProductDescription", "autoWidth": true },
{ "data": "productManufacturingDate", "name": "ProductManufacturingDate", "autoWidth": true },
{ "data": "productExpiryDate", "name": "ProductExpiryDate", "autoWidth": true },
{
"render": function (data, row) { return "<a href='#' class='btn btn-danger' onclick=DeleteProduct('" + row.id + "'); >Delete</a>"; }
},
]
});
});
//add advanced interaction controls
$(document).ready(function () {
$("#productDatatable").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"ajax": {
"url": "/api/Product",
"type": "POST",
"datatype": "json"
},
"columnDefs": [{
"targets": [0].data,
"visible": false,
"searchable": false
}],
"columns": [
{ "data": "id", "name": "Id", "autoWidth": true },
{ "data": "productName", "name": "ProductName", "autoWidth": true },
{ "data": "productPrice", "name": "ProductPrice", "autoWidth": true },
{ "data": "productWeight", "name": "ProductWeight", "autoWidth": true },
{ "data": "productDescription", "name": "ProductDescription", "autoWidth": true },
{ "data": "productManufacturingDate", "name": "ProductManufacturingDate", "autoWidth": true },
{ "data": "productExpiryDate", "name": "ProductExpiryDate", "autoWidth": true },
{
"render": function (data, row) { return "<a href='#' class='btn btn-danger' onclick=DeleteProduct('" + row.id + "'); >Delete</a>"; }
},
]
});
});
'add advanced interaction controls
$(document).ready([function] () {
$("#productDatatable").DataTable({
"processing":= True, "serverSide":= True, "filter":= True, "ajax":= {
"url":= "/api/Product",
"type":= "POST",
"datatype":= "json"
},
"columnDefs":= ({
"targets":= (0).data,
"visible":= False,
"searchable":= False
}), "columns":= ({
"data":= "id",
"name":= "Id",
"autoWidth":= True
},
{
"data":= "productName",
"name":= "ProductName",
"autoWidth":= True
},
{
"data":= "productPrice",
"name":= "ProductPrice",
"autoWidth":= True
},
{
"data":= "productWeight",
"name":= "ProductWeight",
"autoWidth":= True
},
{
"data":= "productDescription",
"name":= "ProductDescription",
"autoWidth":= True
},
{
"data":= "productManufacturingDate",
"name":= "ProductManufacturingDate",
"autoWidth":= True
},
{
"data":= "productExpiryDate",
"name":= "ProductExpiryDate",
"autoWidth":= True
},
{
"render":= [function] (data, row) { Return "<a href='#' class='btn btn-danger' onclick=DeleteProduct('" & row.id & "'); >Delete</a>"; }
},
)
}); })
Now, we need to add an HTML table.
Write the following code in the index.cshtml file to add a static HTML page.
//static HTML page
@page
@model IndexModel
@{
ViewData ["Title"] = "Home page";
}
<link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
<table id="productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Product Name</th>
<th>Product Price</th>
<th>Product Weight</th>
<th>Product Description</th>
<th>Product Manufacturing Date</th>
<th>Product Expiry Date</th>
<th>Actions</th>
</tr>
</thead>
</table>
</div>
</div>
@section Scripts
{
<script src="~/lib/datatables/js/jquery.dataTables.min.js"></script>
<script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script>
<script src="~/js/ProductDatatable.js"></script>
}
//static HTML page
@page
@model IndexModel
@{
ViewData ["Title"] = "Home page";
}
<link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
<table id="productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>Id</th>
<th>Product Name</th>
<th>Product Price</th>
<th>Product Weight</th>
<th>Product Description</th>
<th>Product Manufacturing Date</th>
<th>Product Expiry Date</th>
<th>Actions</th>
</tr>
</thead>
</table>
</div>
</div>
@section Scripts
{
<script src="~/lib/datatables/js/jquery.dataTables.min.js"></script>
<script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script>
<script src="~/js/ProductDatatable.js"></script>
}
'static HTML page
page model ReadOnly Property () As IndexModel
ViewData ("Title") = "Home page"
End Property
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table id="productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0"> <thead> <tr> <th> Id</th> <th> Product Name</th> <th> Product Price</th> <th> Product Weight</th> <th> Product Description</th> <th> Product Manufacturing @Date</th> <th> Product Expiry @Date</th> <th> Actions</th> </tr> </thead> </table> </div> </div> @section Scripts
"100%" cellspacing="0"> (Of thead) (Of tr) (Of th) Id</th> (Of th) Product Name</th> (Of th) Product Price</th> (Of th) Product Weight</th> (Of th) Product Description</th> (Of th) Product Manufacturing [Date]</th> (Of th) Product Expiry [Date]</th> (Of th) Actions</th> </tr> </thead> </table> </div> </div> section Scripts
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table id="productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing
"table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table id="productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width
"productDatatable" class="table table-striped table-bordered dt-responsive nowrap" width
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table id="productDatatable" class
"width:90%; margin:0 auto;"> <table id="productDatatable" class
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private Private Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class="container"> <br /> <div style="width:90%; margin:0 auto;"> <table id
'INSTANT VB WARNING: Instant VB cannot determine whether both operands of this division are integer types - if they are then you should use the VB integer division operator:
"container"> <br /> <div style="width:90%; margin:0 auto;"> <table id
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private Private Private Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class="container"> <br /> <div style
'INSTANT VB WARNING: Instant VB cannot determine whether both operands of this division are integer types - if they are then you should use the VB integer division operator:
"stylesheet" /> <div Class="container"> <br /> <div style
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private Private Private Private Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class
"~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" /> <div Class
Private Private Private Private Private Private Private Friend <link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: <script src="~/lib/datatables/js/jquery.dataTables.min.js"></script> <script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script> <script src="~/js/ProductDatatable.js"></script>
"~/lib/datatables/js/dataTables.bootstrap4.min.js"></script> <script src="~/js/ProductDatatable.js"></script>
'INSTANT VB WARNING: An assignment within expression was extracted from the following statement:
'ORIGINAL LINE: Private <script src="~/lib/datatables/js/jquery.dataTables.min.js"></script> <script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script> <script src
"~/lib/datatables/js/jquery.dataTables.min.js"></script> <script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script> <script src
Private Private Private <script src="~/lib/datatables/js/jquery.dataTables.min.js"></script> <script src
End Class
We need to add the controller.
Add Product Controller for creating endpoint and direct pull requests.
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private readonly ApplicationDBContext context;
public ProductController(ApplicationDBContext context)
{
this.context = context;
}
[HttpPost]
public IActionResult GetProducts()
{
try
{
var draw = Request.Form ["draw"].FirstOrDefault();
var start = Request.Form ["start"].FirstOrDefault();
var length = Request.Form ["length"].FirstOrDefault();
var searchValue = Request.Form ["search [value]"].FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var productData = context.Products.ToList();
if (!string.IsNullOrEmpty(searchValue))
{
productData = productData.Where(m => m.ProductName.Contains(searchValue)
|| m.ProductDescription.Contains(searchValue)
|| m.Id.ToString().Contains(searchValue)).ToList();
}
recordsTotal = productData.Count();
var data = productData.Skip(skip).Take(pageSize).ToList();
var jsonData = new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data };
return Ok(jsonData);
}
catch (Exception ex)
{
throw;
}
}
}
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private readonly ApplicationDBContext context;
public ProductController(ApplicationDBContext context)
{
this.context = context;
}
[HttpPost]
public IActionResult GetProducts()
{
try
{
var draw = Request.Form ["draw"].FirstOrDefault();
var start = Request.Form ["start"].FirstOrDefault();
var length = Request.Form ["length"].FirstOrDefault();
var searchValue = Request.Form ["search [value]"].FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var productData = context.Products.ToList();
if (!string.IsNullOrEmpty(searchValue))
{
productData = productData.Where(m => m.ProductName.Contains(searchValue)
|| m.ProductDescription.Contains(searchValue)
|| m.Id.ToString().Contains(searchValue)).ToList();
}
recordsTotal = productData.Count();
var data = productData.Skip(skip).Take(pageSize).ToList();
var jsonData = new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data };
return Ok(jsonData);
}
catch (Exception ex)
{
throw;
}
}
}
<Route("api/[controller]")>
<ApiController>
Public Class ProductController
Inherits ControllerBase
Private ReadOnly context As ApplicationDBContext
Public Sub New(ByVal context As ApplicationDBContext)
Me.context = context
End Sub
<HttpPost>
Public Function GetProducts() As IActionResult
Try
Dim draw = Request.Form ("draw").FirstOrDefault()
Dim start = Request.Form ("start").FirstOrDefault()
Dim length = Request.Form ("length").FirstOrDefault()
Dim searchValue = Request.Form ("search [value]").FirstOrDefault()
Dim pageSize As Integer = If(length IsNot Nothing, Convert.ToInt32(length), 0)
Dim skip As Integer = If(start IsNot Nothing, Convert.ToInt32(start), 0)
Dim recordsTotal As Integer = 0
Dim productData = context.Products.ToList()
If Not String.IsNullOrEmpty(searchValue) Then
productData = productData.Where(Function(m) m.ProductName.Contains(searchValue) OrElse m.ProductDescription.Contains(searchValue) OrElse m.Id.ToString().Contains(searchValue)).ToList()
End If
recordsTotal = productData.Count()
Dim data = productData.Skip(skip).Take(pageSize).ToList()
Dim jsonData = New With {
Key .draw = draw,
Key .recordsFiltered = recordsTotal,
Key .recordsTotal = recordsTotal,
Key .data = data
}
Return Ok(jsonData)
Catch ex As Exception
Throw
End Try
End Function
End Class
Here, we have implemented pagination & searching on the server side.
Now, we need to set up our database and add configuration to the Program.cs class. If you are using .NET 5 or a lower version, you may need to do it in Startup.cs class.
First of all, add the following Connection String in the appsettings.json file.
"ConnectionStrings": {
"ProductDB": "Server=localserver\\SQLEXPRESS;Database=ProductDB;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True;"
},
Now add the following code to the Program.cs class.
public static void Main(string [] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApplicationDBContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("ProductDB"));
});
builder.Services.AddControllers();
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see .NET documentation https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.Run();
}
public static void Main(string [] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApplicationDBContext>(options =>
{
options.UseSqlServer(builder.Configuration.GetConnectionString("ProductDB"));
});
builder.Services.AddControllers();
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see .NET documentation https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.MapRazorPages();
app.Run();
}
Public Shared Sub Main(ByVal args() As String)
Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddDbContext(Of ApplicationDBContext)(Sub(options)
options.UseSqlServer(builder.Configuration.GetConnectionString("ProductDB"))
End Sub)
builder.Services.AddControllers()
' Add services to the container.
builder.Services.AddRazorPages()
Dim app = builder.Build()
' Configure the HTTP request pipeline.
If Not app.Environment.IsDevelopment() Then
app.UseExceptionHandler("/Error")
' The default HSTS value is 30 days. You may want to change this for production scenarios, see .NET documentation https://aka.ms/aspnetcore-hsts.
app.UseHsts()
End If
app.UseHttpsRedirection()
app.UseStaticFiles()
app.UseRouting()
app.UseAuthorization()
app.MapControllers()
app.MapRazorPages()
app.Run()
End Sub
We need to run the migration, as we are using a code-first approach.
Run the following command in the Package Manager Console.
Add-Migration init
The above command will create a migration. Now we need to apply these migrations to our database. Run the following command in the Package Manager Console.
Update-Database
The above command will create tables in our database. Add dummy data in the Product Table, you may generate random data from Mockaroo.
Now, build and run this application.
We can see, that we have a very interactive UI with advanced interaction controls.
Now, pagination is implemented on the server side as shown below.
The data is then rendered on the Client Side with rich UI Control.
You can explore more from the DataTables.NET documentation by clicking explore DataTables.NET documentation.
IronXL - Excel Library for .NET is a library that allows you to work with Excel files in .NET applications. It can create Excel spreadsheets, read CSV files, edit Excel files, and export to Excel in various formats, such as XLS, XLSX, CSV, and TSV. It does not require Microsoft Office or Excel Interop to be installed. It supports .NET 8, 7, 6, 5, Core, Framework, and Azure.
We often have a requirement to export data into Excel or CSV files. IronXL is the best choice in this case. Now, we will write a code to export our data into an Excel file.
Install the IronXL library in our project by entering the following command in the Package Manager Console.
Install-Package ironXL.Excel
This will install IronXL and the required dependencies in our project.
Let's write a code to convert our Product list into an Excel File.
public void ExportToExcel(List<Product> productList)
{
WorkBook wb = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet ws = wb.DefaultWorkSheet;
int rowCount = 1;
foreach (Product product in productList)
{
ws["A" + (rowCount)].Value = product.Id.ToString();
ws["B" + (rowCount)].Value = product.ProductName;
ws["C" + (rowCount)].Value = product.ProductDescription;
ws["D" + (rowCount)].Value = product.ProductPrice;
ws["E" + (rowCount)].Value = product.ProductWeight;
ws["F" + (rowCount)].Value = product.ProductManufacturingDate;
ws["G" + (rowCount)].Value = product.ProductExpiryDate;
rowCount++;
}
wb.SaveAs("product.xlsx");
}
public void ExportToExcel(List<Product> productList)
{
WorkBook wb = WorkBook.Create(ExcelFileFormat.XLSX);
WorkSheet ws = wb.DefaultWorkSheet;
int rowCount = 1;
foreach (Product product in productList)
{
ws["A" + (rowCount)].Value = product.Id.ToString();
ws["B" + (rowCount)].Value = product.ProductName;
ws["C" + (rowCount)].Value = product.ProductDescription;
ws["D" + (rowCount)].Value = product.ProductPrice;
ws["E" + (rowCount)].Value = product.ProductWeight;
ws["F" + (rowCount)].Value = product.ProductManufacturingDate;
ws["G" + (rowCount)].Value = product.ProductExpiryDate;
rowCount++;
}
wb.SaveAs("product.xlsx");
}
Public Sub ExportToExcel(ByVal productList As List(Of Product))
Dim wb As WorkBook = WorkBook.Create(ExcelFileFormat.XLSX)
Dim ws As WorkSheet = wb.DefaultWorkSheet
Dim rowCount As Integer = 1
For Each product As Product In productList
ws("A" & (rowCount)).Value = product.Id.ToString()
ws("B" & (rowCount)).Value = product.ProductName
ws("C" & (rowCount)).Value = product.ProductDescription
ws("D" & (rowCount)).Value = product.ProductPrice
ws("E" & (rowCount)).Value = product.ProductWeight
ws("F" & (rowCount)).Value = product.ProductManufacturingDate
ws("G" & (rowCount)).Value = product.ProductExpiryDate
rowCount += 1
Next product
wb.SaveAs("product.xlsx")
End Sub
We have created an Excel file from the list in a very simple and easy way.
IronXL provides comprehensive tutorials on creating XLSX files, code examples for reading Excel, and API documentation to use its comprehensive API in the best way possible.
In optimizing ASP.NET performance, we exclusively rely on Only Core Software, ensuring a lean and efficient development environment. Utilizing DataTables.NET as locally hosted packages further enhances responsiveness, minimizing external dependencies for streamlined data handling and Excel exportation. Additionally, contributing code efficiently becomes seamless within this optimized and self-contained ecosystem.
In summary, leveraging DataTables.NET for server-side processing in ASP.NET distribution repo projects proves to be a good strategy for handling substantial datasets efficiently. This approach ensures optimized performance by transmitting data in manageable chunks, mitigating bandwidth usage, and enhancing user experience. The integration of IronXL further extends the application's capabilities, enabling effortless export of tabular data to Excel for comprehensive data analysis and reporting.
By adopting these technologies, developers can create web applications that strike a balance between rich interactivity and resource efficiency, providing users with a seamless and responsive experience, especially in scenarios where large datasets are involved. IronXL offers various licensing options for IronXL, depending on the number of developers, projects, and redistribution needs. The licenses are perpetual and include free support and updates.
9 .NET API products for your office documents