DEV Community

Cover image for How to download CSV and JSON files in React
Thomas Findlay
Thomas Findlay

Posted on • Originally published at theroadtoenterprise.com

8 4

How to download CSV and JSON files in React

This article was originally published on The Road To Enterprise blog. Read it there for the best reading experience.


There are websites that let users download CSV or JSON data as a file. This functionality can be quite useful, as users can download the data for further processing or to share it. In this article, you will learn how to add the functionality that will allow users to export a table in React and download it in JSON and CSV formats.

You can find the full code example in the GitHub repo.

Project Setup

First, let's create a new React project using Vite.

npm init vite@latest csv-json-files-download -- --template react
Enter fullscreen mode Exit fullscreen mode

After the project is created, cd into it to install dependencies by running npm install and then start the dev server with npm run dev.

Next, we need to modify the App.jsx and App.css files.

src/App.jsx

import React from 'react'

function App() {
  return (
    <div className='App'>
      <h1>How to download CSV and JSON files in React</h1>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

src/App.css

.App {
  max-width: 40rem;
  margin: 2rem auto;
}
Enter fullscreen mode Exit fullscreen mode

That's enough for the initial setup. Let's start by adding functionality to export to JSON.

Export to JSON

Let's start by creating a file with users data that will be used for downloading a file and rendering a table.

src/users.json

{
  "users": [
    {
      "id": 1,
      "name": "Caitlyn",
      "surname": "Kerluke",
      "age": 24
    },
    {
      "id": 2,
      "name": "Rowan ",
      "surname": "Nikolaus",
      "age": 45
    },
    {
      "id": 3,
      "name": "Kassandra",
      "surname": "Haley",
      "age": 32
    },
    {
      "id": 4,
      "name": "Rusty",
      "surname": "Arne",
      "age": 58
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Next, we need to update the App component to utilise the users data and display it in a table. Besides that, we will add a button to trigger the download. Below you can see the code for the App.jsx component. Besides the component. we have two functions: exportToJson and downloadFile. The former one calls the latter with appropriate arguments. The downloadFile function accepts an object as a parameter and expects three properties:

  • data
  • fileName
  • fileType

The data and fileType are used to create a blob that is downloaded. After that, we create an anchor element and dispatch a click event on it.

src/App.jsx

import React from 'react'
import './App.css'
import usersData from './users.json'

const downloadFile = ({ data, fileName, fileType }) => {
  // Create a blob with the data we want to download as a file
  const blob = new Blob([data], { type: fileType })
  // Create an anchor element and dispatch a click event on it
  // to trigger a download
  const a = document.createElement('a')
  a.download = fileName
  a.href = window.URL.createObjectURL(blob)
  const clickEvt = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true,
  })
  a.dispatchEvent(clickEvt)
  a.remove()
}

const exportToJson = e => {
  e.preventDefault()
  downloadFile({
    data: JSON.stringify(usersData.users),
    fileName: 'users.json',
    fileType: 'text/json',
  })
}

function App() {
  return (
    <div className='App'>
      <h1>How to download CSV and JSON files in React</h1>

      <table className='usersTable'>
        <thead>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Surname</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          {usersData.users.map(user => {
            const { id, name, surname, age } = user
            return (
              <tr key={id}>
                <td>{id}</td>
                <td>{name}</td>
                <td>{surname}</td>
                <td>{age}</td>
              </tr>
            )
          })}
        </tbody>
      </table>
      <div className='actionBtns'>
        <button type='button' onClick={exportToJson}>
          Export to JSON
        </button>
      </div>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

We can add a few styles, so the table looks a bit nicer.

src/App.css

.App {
  max-width: 40rem;
  margin: 2rem auto;
}

.usersTable th,
.usersTable td {
  padding: 0.4rem 0.6rem;
  text-align: left;
}

.actionBtns {
  margin-top: 1rem;
}

.actionBtns button + button {
  margin-left: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Great, now you should be able to download the users data as a JSON file by clicking on the Export to JSON button. Next, we will add Export to CSV functionality.

Export to CSV

We need another button that will be used to export data to a CSV file. Besides that, we also need a handler for it. The usersData is in the JSON format, so we will need to convert it to the CSV format, before passing it to the downloadFile function.

src/App.jsx

import React from 'react'
import './App.css'
import usersData from './users.json'

const downloadFile = ({ data, fileName, fileType }) => {
  const blob = new Blob([data], { type: fileType })

  const a = document.createElement('a')
  a.download = fileName
  a.href = window.URL.createObjectURL(blob)
  const clickEvt = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true,
  })
  a.dispatchEvent(clickEvt)
  a.remove()
}

const exportToJson = e => {
  e.preventDefault()
  downloadFile({
    data: JSON.stringify(usersData.users),
    fileName: 'users.json',
    fileType: 'text/json',
  })
}

const exportToCsv = e => {
  e.preventDefault()

  // Headers for each column
  let headers = ['Id,Name,Surname,Age']

  // Convert users data to a csv
  let usersCsv = usersData.users.reduce((acc, user) => {
    const { id, name, surname, age } = user
    acc.push([id, name, surname, age].join(','))
    return acc
  }, [])

  downloadFile({
    data: [...headers, ...usersCsv].join('\n'),
    fileName: 'users.csv',
    fileType: 'text/csv',
  })
}

function App() {
  return (
    <div className='App'>
      <h1>How to download CSV and JSON files in React</h1>

      <table className='usersTable'>
        <thead>
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Surname</th>
            <th>Age</th>
          </tr>
        </thead>
        <tbody>
          {usersData.users.map(user => {
            const { id, name, surname, age } = user
            return (
              <tr key={id}>
                <td>{id}</td>
                <td>{name}</td>
                <td>{surname}</td>
                <td>{age}</td>
              </tr>
            )
          })}
        </tbody>
      </table>
      <div className='actionBtns'>
        <button type='button' onClick={exportToJson}>
          Export to JSON
        </button>
        <button type='button' onClick={exportToCsv}>
          Export to CSV
        </button>
      </div>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Wrap up

There we have it. I hope you enjoyed this article. Now you should be well equipped with knowledge on how to add download files functionality to your own projects. Remember that even though I used React to demonstrate the download examples, you can use the download logic in other frameworks like Vue, Svelte, or Angular.


Want to stay up to date and learn more programming tips? Make sure to follow me on Twitter and subscribe to the newsletter!

Tiugo image

Modular, Fast, and Built for Developers

CKEditor 5 gives you full control over your editing experience. A modular architecture means you get high performance, fewer re-renders and a setup that scales with your needs.

Start now

Top comments (0)

Neon image

Next.js applications: Set up a Neon project in seconds

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay