Engineering

Simplified function instead of bloated npm package

Hey my fellow folks on the internet. I am Vijayendren, a Web App Developer for past 1 year. Here I share the approach towards building JSON to CSV function with React. Let’s jump into the content.

Why this post ?

There are node packages for converting the JSON data into .csv file and let user to download it.

For example,

  • react-csv
  • react-csv-download

Some prefer packages and some don’t. I am here for those developer’s who don’t prefer packages, a simple trick can make your own funtion to convert JSON to CSV and allow us to download it.

export const generateCSV=(header, data, filename)=>{
const csvData=arrayToCsv(header,data);
download(csvData,filename);
};

“What two line function to make the .csv file ?”

- Nah Nah! Folk. Still you can achieve it easily.

The above function is like a wrapper. We need two more child function, which allows us to convert the array into csv.

Function for Array to CSV


// Function to convert the JSON(Array of objects) to CSV.
const arrayToCsv = (headers, data) => {
const csvRows = [];
 // getting headers. 
const headerValues = headers.map(header => header.label); 
csvRows.push(headerValues.join(',')); // Push into array as comma separated values. 

// Getting rows. for (const row of data)
 { const rowValues = headers.map(header => { 
const escaped = ('' + row[header.key]).replace(/"/g, '\\"'); // To replace the unwanted quotes.
 return `"${escaped}"` // To escape the comma in a address like string.
 }); 
csvRows.push(rowValues.join(',')); // Push into array as comma separated values. } 
return csvRows.join('\n'); // To enter the next rows in the new line '\n' 
};

The above code has the snippets/comments to understand, “what it is doing ?”. Here is the funtion that allows to convert array into csv data. The arrayToCsv function accepts header array and data array as arguments. It returns the required csv data.

For freshers who are here to read, this is not a big trouble to learn or write. Just grab it tight, simple learning of array handling is enough, to get “what is going on here ?”.

Function to download the csv data


// Function to download the generated CSV as a .csv file.
const download = (data, fileName) => {
    const blob = new Blob([data], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.setAttribute('hidden', '');
    a.setAttribute('href', url);
    a.setAttribute('download', fileName + '.csv');
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
};

This function receives converted csv data and file name. It returns nothing, but it is doing a lot.

  1. We use the Blob to create a file in text/csv format. It accepts data and assign it to the constant blob.
  2. Constant url contains the url of the constant blob.(window.URL.createObjectURL helps us to create a url for our blob object.)
  3. On the third step, let’s create an anchor tag. Assign the url to anchor tag’s href attribute.
  4. Lets give our file a name, which is accepted as an argument.
  5. Then append the anchor tag as a child, give it a click event.
  6. Once we notice the a.click(), lets remove the anchor tag from child.

Now look these pieces into a single file.


// Function to convert the JSON(Array of objects) to CSV.
const arrayToCsv = (headers, data) => {
const csvRows = [];
 // getting headers. 
const headerValues = headers.map(header => header.label); 
csvRows.push(headerValues.join(',')); // Push into array as comma separated values. 

// Getting rows. for (const row of data)
 { const rowValues = headers.map(header => { 
const escaped = ('' + row[header.key]).replace(/"/g, '\\"'); // To replace the unwanted quotes.
 return `"${escaped}"` // To escape the comma in a address like string.
 }); 
csvRows.push(rowValues.join(',')); // Push into array as comma separated values. } 
return csvRows.join('\n'); // To enter the next rows in the new line '\n' 
};

// Function to download the generated CSV as a .csv file.
const download = (data, fileName) => {
    const blob = new Blob([data], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.setAttribute('hidden', '');
    a.setAttribute('href', url);
    a.setAttribute('download', fileName + '.csv');
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
};

export const generateCSV=(header, data, filename)=>{
const csvData=arrayToCsv(header,data);
download(csvData,filename);
};

You can simply import this function on any component and use it on “onClick” event. Don’t get confused. The following image is a sample/answer for the question “How to use this ?”


import React from "react";
import "./style.css";
import { generateCSV } from './generateCSV';

const csvHeader = [
  { label: "ID", key: "id" },
  { label: "Developer", key: "devName" },
  { label: "Age", key: "age" },
  { label: "Country", key: "country" }
];

const data = [
  {id: 1, devName: 'Vismeya', age: 23, country: 'India'},
  {id: 2, devName: 'Vinith', age: 24, country: 'India'},
  {id: 3, devName: 'Yoganandham', age: 23, country: 'India'},
  {id: 4, devName: 'Vivek', age: 24, country: 'India'},
  {id: 5, devName: 'Tharun', age: 24, country: 'Canada'},
  {id: 6, devName: 'Revanth', age: 21, country: 'India'},
  {id: 7, devName: 'Sabarish', age: 25, country: 'India'},
  {id: 8, devName: 'Rahul', age: 20, country: 'India'},
  {id: 9, devName: 'Siva', age: 24, country: 'United States'},
  {id: 10, devName: 'Naveen', age: 20, country: 'India'},
];

}

Constant csvHeader and data are the sample data for generateCSV functions argument/parameter.

In this sample, I have simply created a button and used the generateCSV function as onClick event. The file name can be any thing you like to remember. This is how our .csv file looks, when opened.

Conclusion

This function works efficiently for our requirements. Instead of searching package, a simple trick will satisfy our requirements. A general understanding of array handling can help us to succeed a lot. I hope this doesn’t confuse a lot. Give it a try, you play with this on your own. Do share how we can improve this further and can be optimized.

“Gain Knowledge, Spread Knowledge”

2 thoughts on “Simplified function instead of bloated npm package

Leave a Reply to logeshwaran Cancel reply

Your email address will not be published. Required fields are marked *