DEV Community

Cover image for Convert an array of objects to CSV string in JavaScript
Sam Jones
Sam Jones

Posted on

Convert an array of objects to CSV string in JavaScript

On some occasions at work, we've needed to generate a CSV string on the server-side to send to our front-end app where the user can download a spreadsheet file e.g. report.

Naturally, there are already packages out there that can handle a variety of CSV use cases, but we just wanted a simple solution in JavaScript as we knew that the data structure coming from our database was always going to be an array of objects.

Before we continue though, it's worth pointing out that we'll be using a few JavaScript methods and techniques in the solution that you may or may not already be familiar with:

If any of the above seem a little alien to you right now, then feel free to take a quick pause here to check them out and come back when you're feeling more comfortable with them.


Welcome back if you took that break 👋

So, how do we get from an array of objects to a CSV string while ensuring that the correct data will be displayed in the column headers and rows?

Let's start by creating our array of objects:

const itemsArray = [
      { itemId: 1, itemRef: "Item 001" },
      { itemId: 2, itemRef: "Item 002" },
      { itemId: 3, itemRef: "Item 003" }
    ];

Enter fullscreen mode Exit fullscreen mode

The first step towards creating the CSV string is to define our column headers and extract the key-value pairs into their own arrays:

const csvString = [
    [
      "Item ID",
      "Item Reference"
    ],
    ...itemsArray.map(item => [
      item.itemId,
      item.itemRef
    ])
  ];

console.log(csvString);
/*
   [
    ["Item ID", "Item Reference"],
    [1, "Item 001"],
    [2, "Item 002"],
    [3, "Item 003"]
   ]
*/
Enter fullscreen mode Exit fullscreen mode

Now that we have all our data in arrays, we can use our .map() and .join() methods to bring everything together:

const csvString = [
    [
      "Item ID",
      "Item Reference"
    ],
    ...itemsArray.map(item => [
      item.itemId,
      item.itemRef
    ])
  ]
   .map(e => e.join(",")) 
   .join("\n");

console.log(csvString);
/*
  "Item ID,Item Reference
  1,Item 001
  2,Item 002
  3,Item 003"
*/
Enter fullscreen mode Exit fullscreen mode

What happens here then? Well, the first map/join combo combines the array of 4 arrays into a single array containing the headers and key-value pairs as string types e.g. "1,Item 001". Then, the final join is needed to convert the single array into a string.


In this post, we managed to convert an array of objects into a CSV string using some helpful array methods and the spread syntax in JavaScript.

Please copy and experiment with the above code and feel free to ask me any questions on here or over on Twitter.

Thanks for reading!

Top comments (6)

Collapse
 
felipperegazio profile image
Felippe Regazio

Just a contribution: To properly escape de resulting CSV, you can add a map to the items array:

const csvString = [
    [
      "Item ID",
      "Item Reference"
    ],
    ...itemsArray.map(item => [
      item.itemId,
      item.itemRef
+    ].map(str => `"${str.replace(/"/g, '\"')}"`)))
  ]
   .map(e => e.join(",")) 
   .join("\n");
Enter fullscreen mode Exit fullscreen mode

This will:

  1. wrap the item with "double quotes"
  2. replace inner double quotes from " to ""

Reference: stackoverflow.com/questions/466379...

Collapse
 
anders profile image
Anders

It would probably be wise to have a step where you properly encode each value before putting it in a CSV "column", this would break if you have certain characters in your value

Collapse
 
jprumekso profile image
Jalu Pujo Rumekso

how do you encode it btw?

Collapse
 
samueldjones profile image
Sam Jones

Good point, Anders!

Collapse
 
loige profile image
Luciano Mammino

Nice article @samueldjones !

A suggestion for a follow-up post, do something similar but using streams, so you can process arbitrarily big datasets 🤓

(I know, I like streams way too much!)

Collapse
 
samueldjones profile image
Sam Jones • Edited

Thanks, Luciano!

Good idea on the streams, I'll make a note of that 📝