Export CSV from Clarity Datagrid in Angular
Tags: angular, tutorial
Published: 2024-03-02 00:59:55

In a recent project, I was using a [Clarity Datagrid](https://clarity.design/documentation/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.

```javascript
import { ClrDatagrid } from '@clr/angular';
```

Create a reference to the datagrid class using [ViewChild](https://angular.io/api/core/ViewChild).

```javascript
import { ViewChild } from '@angular/core';
 
@ViewChild(ClrDatagrid) datagrid: ClrDatagrid;
```

With the reference created, we now have access to all datagrid items.

```javascript
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:

```javascript
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:

```html
<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.

```javascript
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.

```html
<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.

```javascript
exportCSV() {
 
}
```

First, we need the row data. We already learned how to get that earlier. Let’s store it in a variable called data.

```javascript
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.

```javascript
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.

```javascript
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.

```javascript
const csvContent = [headers, ...rows].map(row => row.join(',')).join('\n');
```

Create a url using a blob with the correct format for CSV.

```javascript
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.

```javascript
this.exportLink.nativeElement.href = url;
this.exportLink.nativeElement.download = 'data.csv';
this.exportLink.nativeElement.click();
```

Here’s the final code for the exportCSV method:

```javascript
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](https://nightwolf.dev) and follow us on [Twitter](https://twitter.com/nightwolfdev)!**