Export Data In Angular-UI-Grid Using WebAPI

In this article, you will learn how to export grid data in CSV file or in PDF file. In this article, we will cover the things given below.

  • Export visible grid data in CSV file.
  • Export all grid data in CSV file.
  • Export visible grid data in PDF file.
  • Export all grid data in PDF file.
  • Show/ hide grid columns.

Introduction

The exporter feature allows data to be exported from the grid in CSV or PDF format. The exporter can export all the data, visible data or selected data.

If you would like how to get started with UI-Grid and how to setup a project in AngularJS and Web API, refer

Thus after adding data in Entity Model, create a Web API to get the data from Entity model.

Web API

Here, my Web API class code is given below.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using System.Data.Entity;  
  5. using System.Data.Entity.Infrastructure;  
  6. using System.Linq;  
  7. using System.Net;  
  8. using System.Net.Http;  
  9. using System.Threading.Tasks;  
  10. using System.Web.Http;  
  11. using System.Web.Http.Description;  
  12. using ng_ui_grid_export_sample.Models;  
  13. namespace ng_ui_grid_export_sample.Controllers {  
  14.     public class EmployeesAPIController: ApiController {  
  15.         private NORTHWNDEntities db = new NORTHWNDEntities();  
  16.         // GET: api/EmployeesAPI    
  17.         public IQueryable < Employees > GetEmployees() {  
  18.             return db.Employees;  
  19.         }  
  20.         // GET: api/EmployeesAPI/5    
  21.         [ResponseType(typeof(Employees))]  
  22.         public async Task < IHttpActionResult > GetEmployees(int id) {  
  23.             Employees employees = await db.Employees.FindAsync(id);  
  24.             if (employees == null) {  
  25.                 return NotFound();  
  26.             }  
  27.             return Ok(employees);  
  28.         }  
  29.         // PUT: api/EmployeesAPI/5    
  30.         [ResponseType(typeof(void))]  
  31.         public async Task < IHttpActionResult > PutEmployees(int id, Employees employees) {  
  32.             if (!ModelState.IsValid) {  
  33.                 return BadRequest(ModelState);  
  34.             }  
  35.             if (id != employees.EmployeeID) {  
  36.                 return BadRequest();  
  37.             }  
  38.             db.Entry(employees).State = EntityState.Modified;  
  39.             try {  
  40.                 await db.SaveChangesAsync();  
  41.             } catch (DbUpdateConcurrencyException) {  
  42.                 if (!EmployeesExists(id)) {  
  43.                     return NotFound();  
  44.                 } else {  
  45.                     throw;  
  46.                 }  
  47.             }  
  48.             return StatusCode(HttpStatusCode.NoContent);  
  49.         }  
  50.         // POST: api/EmployeesAPI    
  51.         [ResponseType(typeof(Employees))]  
  52.         public async Task < IHttpActionResult > PostEmployees(Employees employees) {  
  53.             if (!ModelState.IsValid) {  
  54.                 return BadRequest(ModelState);  
  55.             }  
  56.             db.Employees.Add(employees);  
  57.             await db.SaveChangesAsync();  
  58.             return CreatedAtRoute("DefaultApi"new {  
  59.                 id = employees.EmployeeID  
  60.             }, employees);  
  61.         }  
  62.         // DELETE: api/EmployeesAPI/5    
  63.         [ResponseType(typeof(Employees))]  
  64.         public async Task < IHttpActionResult > DeleteEmployees(int id) {  
  65.             Employees employees = await db.Employees.FindAsync(id);  
  66.             if (employees == null) {  
  67.                 return NotFound();  
  68.             }  
  69.             db.Employees.Remove(employees);  
  70.             await db.SaveChangesAsync();  
  71.             return Ok(employees);  
  72.         }  
  73.         protected override void Dispose(bool disposing) {  
  74.             if (disposing) {  
  75.                 db.Dispose();  
  76.             }  
  77.             base.Dispose(disposing);  
  78.         }  
  79.         private bool EmployeesExists(int id) {  
  80.             return db.Employees.Count(e => e.EmployeeID == id) > 0;  
  81.         }  
  82.     }  
  83. }   

Global

Now, add few lines in Global.asax in Application_Start event. 

  1. GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;  
  2. GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);  
  3. GlobalConfiguration.Configure(WebApiConfig.Register);  

Now, add the mandatory packages given below, using NuGet Package Manager.


Bundling – Bundle the required styles and scripts.

Add the bundles given below in BundleConfig.cs

  1. bundles.Add(new StyleBundle("~/Content/css").Include(    
  2. "~/Content/bootstrap.css",    
  3. "~/Content/site.css",    
  4. "~/Content/ui-grid.css"));    
  5. bundles.Add(new ScriptBundle("~/bundles/uigrid").Include(    
  6. "~/Scripts/ui-grid.min.js"));    
  7. bundles.Add(new ScriptBundle("~/bundles/angular").Include(    
  8. "~/Scripts/angular.min.js",    
  9. "~/Angular/Controller/employeecontroller.js"));     

Render all the scripts and styles in _Loyout.cshtml

  1. @Styles.Render("~/Content/css")    
  2. @Scripts.Render("~/bundles/modernizr")    
  3. @Scripts.Render("~/bundles/jquery")    
  4. @Scripts.Render("~/bundles/bootstrap")    
  5. @Scripts.Render("~/bundles/angular")    
  6. @Scripts.Render("~/bundles/uigrid")    
  7. @RenderSection("scripts", required: false)     

MVC Controller

If you are using your own Controller, add a new Controller in Controller folder.

  1. public class EmployeeController: Controller {  
  2.     // GET: Employee    
  3.     public ActionResult Index() {  
  4.         return View();  
  5.     }  
  6. }   

Create a new View name Index inside controller folder.

After adding all this, if you want to navigate this, view from _loyout.cshtml then add this line in _loyout.cshtml.

Now, add a new Angular controller with scope. I am using just one script for Module, Service and Controller. You can have it separate, if working on a big project.

Module

  1. var employeeapp = angular.module('employeeapp', ['ui.grid''ui.grid.pagination''ui.grid.exporter']);     

Service

  1. employeeapp.service("employeeservice"function($http) {  
  2.     //Function to call get genre web api call    
  3.     this.GetEmployee = function() {  
  4.         var req = $http.get('api/EmployeesAPI');  
  5.         return req;  
  6.     }  
  7. });   

Controller

  1. //Controller    
  2. employeeapp.controller("employeecontroller"function($scope, employeeservice, $filter, $window, $interval) {  
  3.     GetEmployee();  
  4.   
  5.     function GetEmployee() {  
  6.         employeeservice.GetEmployee().then(function(result) {  
  7.             $scope.Employees = result.data;  
  8.             console.log($scope.Employees);  
  9.         }, function(error) {  
  10.             $window.alert('Oops! Something went wrong while fetching employee data.');  
  11.         })  
  12.     }  
  13.     $scope.gridOptions = {  
  14.         enableRowSelection: true,  
  15.         paginationPageSizes: [5, 10, 20, 30, 40],  
  16.         paginationPageSize: 5,  
  17.         enableSorting: true,  
  18.         columnDefs: [{  
  19.             name: 'photo',  
  20.             enableSorting: false,  
  21.             field: 'PhotoPath',  
  22.             cellTemplate: "<img width=\"50px\" ng-src=\"{{grid.getCellValue(row, col)}}\" lazy-src>"  
  23.         }, {  
  24.             name: 'First Name',  
  25.             field: 'FirstName',  
  26.             headerCellClass: 'tablesorter-header-inner'  
  27.         }, {  
  28.             name: 'Last Name',  
  29.             field: 'LastName',  
  30.             headerCellClass: 'tablesorter-header-inner'  
  31.         }, {  
  32.             name: 'Title',  
  33.             field: 'Title',  
  34.             headerCellClass: 'tablesorter-header-inner'  
  35.         }, {  
  36.             name: 'City',  
  37.             field: 'City',  
  38.             headerCellClass: 'tablesorter-header-inner'  
  39.         }, {  
  40.             name: 'Country',  
  41.             field: 'Country',  
  42.             headerCellClass: 'tablesorter-header-inner'  
  43.         }, {  
  44.             name: 'Notes',  
  45.             field: 'Notes',  
  46.             headerCellClass: 'tablesorter-header-inner'  
  47.         }],  
  48.         //This code used for export grid data in csv file    
  49.         enableGridMenu: true,  
  50.         enableSelectAll: true,  
  51.         exporterMenuPdf: true,  
  52.         exporterCsvFilename: 'EmployeeList.csv',  
  53.         //This is for PDF export    
  54.         exporterPdfDefaultStyle: {  
  55.             fontSize: 9  
  56.         },  
  57.         exporterPdfTableStyle: {  
  58.             margin: [30, 30, 30, 30]  
  59.         },  
  60.         exporterPdfTableHeaderStyle: {  
  61.             fontSize: 10,  
  62.             bold: true,  
  63.             italics: true,  
  64.             color: 'red'  
  65.         },  
  66.         exporterPdfHeader: {  
  67.             text: "My Header",  
  68.             style: 'headerStyle'  
  69.         },  
  70.         exporterPdfFooter: function(currentPage, pageCount) {  
  71.             return {  
  72.                 text: currentPage.toString() + ' of ' + pageCount.toString(),  
  73.                 style: 'footerStyle'  
  74.             };  
  75.         },  
  76.         exporterPdfCustomFormatter: function(docDefinition) {  
  77.             docDefinition.styles.headerStyle = {  
  78.                 fontSize: 22,  
  79.                 bold: true  
  80.             };  
  81.             docDefinition.styles.footerStyle = {  
  82.                 fontSize: 10,  
  83.                 bold: true  
  84.             };  
  85.             return docDefinition;  
  86.         },  
  87.         exporterPdfOrientation: 'portrait',  
  88.         exporterPdfPageSize: 'LETTER',  
  89.         exporterPdfMaxGridWidth: 500,  
  90.         //End here    
  91.         exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),  
  92.         onRegisterApi: function(gridApi) {  
  93.             $scope.gridApi = gridApi;  
  94.         },  
  95.         //end here    
  96.         //data for binding grid    
  97.         data: 'Employees',  
  98.         //end here    
  99.     };  
  100. });   

Index

  1. @ {  
  2.     ViewBag.Title = "Index";  
  3.     Layout = "~/Views/Shared/_Layout.cshtml";  
  4. } < h2 > Employee List < /h2>   < div ng - app = "employeeapp"  
  5. ng - controller = "employeecontroller" > < div ui - grid = "gridOptions"  
  6. ui - grid - auto - resize ui - grid - pagination ui - grid - selection ui - grid - exporter class = "grid"  
  7. style = "height:300px" > < /div>   < /div>   

As everything is done, run the Application.


Once the Application is run, you can see there is an icon on right side of the grid header.


If you click on the icon, you can see export options and all visible columns.


If you scroll down little bit, you can see all the columns names with hide show status.


Let’s click Export all data as CSV. As you can see, there is one CSV file, which is downloaded with all columns data. If you click Export visible data as CSV, then all visible data will be exported.


See the exported CSV file.


Now, click Export PDF option.

Note – Please make sure to install PdfMake before exporting in PDF. 

  1. bower install pdfmake  

Or

You can add it, using form NuGet Package Manager.

Add the bundles given below in BundleConfig.cs. 

  1. bundles.Add(new ScriptBundle("~/bundles/pdfmake").Include(  
  2. "~/Scripts/pdfmake/pdfmake.min.js",  
  3. "~/Scripts/pdfmake/vfs_fonts.js"));  


Exported PDF file is given.

If you want to hide some columns, simply click on the column name and you can unhide also.

Conclusion

In this article, we have seen how to use export Angular UI-Grid data in CSV and PDF and show hidden grid columns with Web API with an Entity Framework in MVC. If you have any question or comments, drop me a line in the comments section.