JavaScript: export to CSV using the download attribute

March 17, 2014

Last update: March 28, 2020

The problem

We have to allow our users to download data in CSV format.

A solution

Luckily, HTML5 provides a new download attribute for <a> tag that tells to browsers to download linked resource rather than navigate to it.

Directly client side, we can prepare data and enable download without the need of the server. Of course, this is true if the browser supports the attribute. In case of missing support as fall back we have to rely on the server.

This is the code:

// some data to export var data = [ {"title": "Book title 1", "author": "Name1 Surname1"}, {"title": "Book title 2", "author": "Name2 Surname2"}, {"title": "Book title 3", "author": "Name3 Surname3"}, {"title": "Book title 4", "author": "Name4 Surname4"} ]; // prepare CSV data var csvData = new Array(); csvData.push('"Book title","Author"'); data.forEach(function(item, index, array) { csvData.push('"' + item.title + '","' + item.author + '"'); }); // download stuff var fileName = "data.csv"; var buffer = csvData.join("\n"); var blob = new Blob([buffer], { "type": "text/csv;charset=utf8;" }); var link = document.createElement("a"); if(link.download !== undefined) { // feature detection // Browsers that support HTML5 download attribute link.setAttribute("href", window.URL.createObjectURL(blob)); link.setAttribute("download", fileName); } else { // it needs to implement server side export link.setAttribute("href", "http://www.example.com/export"); } link.innerHTML = "Export to CSV"; document.body.appendChild(link);

Along came IE. All front enders know that Microsoft does a lot of research to make their lives an hell, so let's see what he creates for us this time. IE 10+ doesn't support directly the download attribute, but we can mimic it.

We have to extend our code with this:

if(link.download !== undefined) { // feature detection // Browsers that support HTML5 download attribute ... } else if(navigator.msSaveBlob) { // IE 10+ link.setAttribute("href", "#"); link.addEventListener("click", function(event) { navigator.msSaveBlob(blob, fileName); }, false); } else { // it needs to implement server side export ... }

In my honest opinion, I'll avoid to put proprietary code in scripts. The fall back that relies on the server is good to manage all old browsers or browsers that not support the attribute yet. I've write about this proprietary solution just to be thorough.

The complete example is available on GitHub.

References

  1. Can I use - download attribute

  2. Stack Overflow - How to export JavaScript array info to csv (on client side)?


A photo of Elia Contini
Written by
Elia Contini
Sardinian UX engineer and a Front-end web architect based in Switzerland. Marathoner, traveller, wannabe nature photographer.