In a recent project, I was using a Clarity Datagrid to display a table of data in an Angular application. The datagrid provides options to sort and filter the table, but it was missing an option to export to CSV. Let's learn how!
Access Clarity Datagrid Rows
Before we can export to CSV, we need access to the actual rows of data. To get that data, we need access to the datagrid class. Let’s import the ClrDatagrid class.
import { ClrDatagrid } from '@clr/angular';
Create a reference to the datagrid class using ViewChild.
import { ViewChild } from '@angular/core';
@ViewChild(ClrDatagrid) datagrid: ClrDatagrid;
With the reference created, we now have access to all datagrid items.
this.datagrid.items.all
However, we don’t want to export all items all the time. What if the user decides to filter a column and change the rows being displayed. We want to take that into account. You can use the following property instead:
this.datagrid.items['_filtered']
Hidden Reusable Anchor Element
When choosing to export to CSV, a file is created and downloaded. An anchor element provides that functionality. When clicked, it downloads a file containing the CSV content with a name of our choosing. However, we don’t want to create a new anchor element every time the user clicks on the Export CSV button. So we’ll create a hidden reusable anchor element.
Within your html template, create an anchor element like the following:
<a #exportLink href="#" style="display: none"></a>
Notice we defined a template variable called exportLink on the anchor element. Let’s create a reference to that next.
import { ElementRef, ViewChild } from '@angular/core';
@ViewChild('exportLink') exportLink: ElementRef<HTMLAnchorElement>;
We have everything in place now for the Export CSV button.
Export CSV
Let’s add an Export CSV button to the action bar of the Clarity Datagrid. Notice we also defined a click handler called exportCSV that will be called when the button is clicked.
<clr-datagrid>
<clr-dg-action-bar>
<button type="button" class="btn btn-sm" (click)="exportCSV()">Export CSV</button>
</clr-dg-action-bar>
...
</clr-datagrid>
Create the exportCSV method next.
exportCSV() {
}
First, we need the row data. We already learned how to get that earlier. Let’s store it in a variable called data.
const data = this.datagrid.items['_filtered'];
The first row of a CSV file is usually the column headers. We can get that by extracting the keys of the first object in the data array.
const headers = Object.keys(data[0]);
The values in each row of data could potentially include commas. We need to wrap values that are of type string in double quotes to avoid any issues with commas.
const rows = data.map((entry: any) => headers.map(header => {
let value = entry[header];
if (typeof value === 'string') {
// Enclose in double quotes
value = `"${value}"`;
}
return value;
}));
Now we can combine the headers and rows of data and convert them into CSV format. We need a comma to separate each value and a new line character at the end of each row.
const csvContent = [headers, ...rows].map(row => row.join(',')).join('\n');
Create a url using a blob with the correct format for CSV.
const blob = new Blob([csvContent], { type: 'text/csv; charset=utf-8;' });
const url = URL.createObjectURL(blob);
Remember that reusable anchor element we created earlier? We’re ready to use it now! We assign the url to the anchor’s href. The file name will be called data.csv. To trigger the actual download, we programmatically call the click method on the anchor element.
this.exportLink.nativeElement.href = url;
this.exportLink.nativeElement.download = 'data.csv';
this.exportLink.nativeElement.click();
Here’s the final code for the exportCSV method:
exportCSV() {
const data = this.datagrid.items['_filtered'];
const headers = Object.keys(data[0]);
const rows = data.map((entry: any) => headers.map(header => {
let value = entry[header];
if (typeof value === 'string') {
// Enclose in double quotes
value = `"${value}"`;
}
return value;
}));
const csvContent = [headers, ...rows].map(row => row.join(',')).join('\n');
const blob = new Blob([csvContent], { type: 'text/csv; charset=utf-8;' });
const url = URL.createObjectURL(blob);
this.exportLink.nativeElement.href = url;
this.exportLink.nativeElement.download = 'data.csv';
this.exportLink.nativeElement.click();
}
Click the Export CSV button and a file called data.csv is downloaded with the data from your Clarity Datagrid in CSV format!
Visit our website at https://nightwolf.dev and follow us on Twitter!