There can be cases, especially in Single Page Applications, when you have some data in the browser already that you have probably received via an Ajax call that you'd like to let your users download.

CSV is a nice and simple format to keep tabular information.

In this simple example you'll see how to let your users save data from the browser.

This solution only works in the simple case, but it could be improved to handle some of the stranger cases as well.


var data = [
   ['Foo', 'programmer'],
   ['Bar', 'bus driver'],
   ['Moo', 'Reindeer Hunter']

function download_csv() {
    var csv = 'Name,Title\n';
    data.forEach(function(row) {
            csv += row.join(',');
            csv += "\n";

    var hiddenElement = document.createElement('a');
    hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv); = '_blank'; = 'people.csv';;

<button onclick="download_csv()">Download CSV</button> 

The data is just some array of arrays holding, well, the data. It does not really matter how it got into the browser.

The download_csv function that is triggered by the click of the button, will create a string that will become the content of the file on the disk of the user. In the first line we add the header row and finish it with a newline (\n). Then using a forEach loop we add additional lines separating the values with comma (,). After all we are creating a file with comma separated values. Each line is finished with a newline.

Once we have the content in some variable we create a an a element and in the link (the href part) we add the URI-encoded version of the future CSV file. We can even add the future name of the file which is 'people.csv' in our case. Without that Chrome just saved the file calling it 'download.csv'.

The last step is to trigger the newly created element which tell the browser to download the "file".


This solution only handles the case when the data is "simple". If the data might have comma , in it then, in order for the file to work properly we'll have to put the value with the comma in it inside quotes. This can be added quite easily.

However, what happens if the data can also contain quotes? We will then have to escape those.

This is not "unsolvable" of course, but it needs some more work and currently I did not have the need for that.