How to Let Users Download JavaScript Array Data as a CSV on Client-Side?

Sometimes, we may want to let users download a nested array with data as a CSV text file.

In this article, we’ll look at how to let users download a JavaScript array’s data as a CSV on the client-side.

Using the window.open Method

We can use the window.open method to open a URL encoded string to let users download that to their computer.

For instance, we can write:

const rows = [
  ["name1", "new york", "abc"],
  ["name2", "san francisco", "def"]
];

let csvContent = "data:text/csv;charset=utf-8,";

for (const rowArray of rows) {
  const row = rowArray.join(",");
  csvContent += `${row}rn`;
}
const encodedUri = encodeURI(csvContent);
window.open(encodedUri);

We have the rows nested array that we want to convert to a CSV string and let users download it.

To do the conversion, we first define the beginning of the csvContent string which specifies the MIME type and the character set.

Then we loop through the rows entries, join each row’s entries and append them to the csvContent string with newline characters.

Then we call encodeURI with the csvContent string to encode it to a URL encoded string.

And finally, we can download the string as a file with window.open .

We can also shorten the for-of with the map method:

const rows = [
  ["name1", "new york", "abc"],
  ["name2", "san francisco", "def"]
];

const csvContent = `data:text/csv;charset=utf-8,${rows
  .map((e) => e.join(","))
  .join("n")}`;

const encodedUri = encodeURI(csvContent);
window.open(encodedUri);

We just call map on rows to map each row to a comma-separated string with join .

Then we call join on the mapped strings.

Download the file this way doesn’t let us set the file name.

To let us set the file name, we can create an invisible link and click on it programmatically.

To do that, we weiter:

const rows = [
  ["name1", "new york", "abc"],
  ["name2", "san francisco", "def"]
];
const csvContent = `data:text/csv;charset=utf-8,${rows
  .map((e) => e.join(","))
  .join("n")}`;
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "data.csv");
document.body.appendChild(link);
link.click()

We call createElement to create an a element.

Then we set the href to the encodedUri .

And then we set the download attribute to the file name with setAttribute .

Next, we call appendChild with the link to attach it to the body.

And then we call click on it to click it to start the download.

Save the Data as a Blob

We can save the data as a blob by rewriting the example above.

For instance, we can write:

const rows = [
  ["name1", "new york", "abc"],
  ["name2", "san francisco", "def"]
];
const csvContent = rows
  .map((e) => e.join(","))
  .join("n");
const blob = new Blob([csvContent], {
  type: 'text/csv;charset=utf-8;'
});
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", "data.csv");
document.body.appendChild(link);
link.click()
URL.revokeObjectURL(link.href)

We have the csvContent string that only has the CSV string content.

Then we create a blob from it with the Blob constructor.

In the 2nd argument of it, we set the type to the data type of the blob.

Next, we call URL.createObjectURL to create an encoded URL that we can download.

And we create the link element the same way as before, but with url created from URL.createObjectURL instead.

Also, we’ve to call URL.revokeObjectURL to free up resources after the download is done.

Conclusion

We can let generate CSVs from nested arrays on client-side and let users download them with some JavaScript code.