How To Export Data to Excel in Angular
Tags: angular, excel
Published: 2020-06-17 19:30:09

---
title: How To Export Data to Excel in Angular
published: true
description: Data export to Excel is a common task in modern business-facing apps and this short post helps you accomplish just that.
tags: angular, excel
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/k7lk9ana27zk911bdtdb.jpg
---

Data export to Excel is a common task in modern business-facing apps and of course we have npm packages to help us do just that. An amazing one to consider is [Angular Material Table Exporter](https://www.npmjs.com/package/mat-table-exporter). But there are a big prerequisite to use it. Your data has to be rendered using Material Table. If you are OK with it, then follow the docs for the mat-table-exporter package for a painless integration - it works like a charm. One gotcha that you may face is the bundle size. If you follow the default integration steps and add **MatTableExporterModule** to `shared.module.ts`, your bundle size may gain 1.5Mb. Of course you can lazy-load it, move to the server completely, or use the method below.

## Meet excel-export Service
We will be using only one fairly low-level dependency - `xlsx` and go from there. Let’s make sure we have the latter installed:

```bash
npm i xlsx
```

Now we have access to a plethora of methods and options provided by this awesome package which will be integrated into `excel-export.service.ts`.

TLDR: Here’s what the service looks like:

```ts
// excel-export.service.ts

import { utils as XLSXUtils, writeFile } from 'xlsx';
import { WorkBook, WorkSheet } from 'xlsx/types';

import { Injectable } from '@angular/core';

export interface IExportAsExcelProps {
  readonly data: any[];
  readonly fileName: string;
  readonly sheetName?: string;
  readonly header?: string[];
  readonly table?: HTMLElement;
}

@Injectable({
  providedIn: 'root'
})
export class ExcelExportService {
  fileExtension = '.xlsx';

  public exportAsExcel({
    data,
    fileName,
    sheetName = 'Data',
    header = [],
    table
  }: IExportAsExcelProps): void {
    let wb: WorkBook;

    if (table) {
      wb = XLSXUtils.table_to_book(table);
    } else {
      const ws: WorkSheet = XLSXUtils.json_to_sheet(data, { header });
      wb = XLSXUtils.book_new();
      XLSXUtils.book_append_sheet(wb, ws, sheetName);
    }

    writeFile(wb, `${fileName}${this.fileExtension}`);
  }
}
```

#### What’s going on above?
First, official xlsx docs tell you to import everything from `xlsx`:

```ts
import * as XLSX from 'xlsx';
```

It works, but my personal preference is to import individual methods, interfaces, types, and not pull the whole library along. Hence the adjusted import declarations:

```ts
import { utils as XLSXUtils, writeFile } from 'xlsx';
import { WorkBook, WorkSheet } from 'xlsx/types';
```

We will have only one public method `exportAsExcel` that takes the following props: `data, fileName, sheetName, header, table` with the following interface:

```ts
export interface IExportAsExcelProps {
  readonly data: any[];
  readonly fileName: string;
  readonly sheetName?: string;
  readonly header?: string[];
  readonly table?: HTMLElement;
}
```

The `data` has to be in JSON format to make `json_to_sheet` util method happy. Read more about it in the docs: [json_to_sheet](https://www.npmjs.com/package/xlsx#array-of-objects-input)

If you prefer to grab the DOM’s `<table>` Element and convert its contents into Excel doc, just pass the desired HTMLElement through and our service will use `table_to_book` method. More info on that in the docs: [table_to_book](https://www.npmjs.com/package/xlsx#html-table-input)

Well, `fileName` and `sheetName` are self-explanatory, se we are left with the last optional prop: `header`. 

This is an array of keys from your data Object that controls the column order. If you don’t explicitly pass it, xlsx defaults to `Object.keys`. Read more on `header`: https://github.com/SheetJS/sheetjs#array-of-objects-input

I believe this is all. Just massage the data you want to send down or play with the `<table>` contents and you have a working **Export as Excel** service you can call whenever you need it.