How to download CSV and JSON files in React
Tags: react, javascript, json, webdev
Published: 2021-09-01 16:30:09

---
title: How to download CSV and JSON files in React
description: In this article you will learn how to implement functionality to allow users to download JSON and CSV files in React.
canonical_url: https://theroadtoenterprise.com/blog/how-to-download-csv-and-json-files-in-react
published: true
tags: react, javascript, json, webdev
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9j4ft0rsojk00xqaldrz.png
---

This article was originally published on [The Road To Enterprise](https://theroadtoenterprise.com/blog/how-to-download-csv-and-json-files-in-react) 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](https://github.com/ThomasFindlay/csv-json-files-download-in-react). 

## Project Setup

First, let's create a new React project using [Vite](https://vitejs.dev).

```sh
npm init vite@latest csv-json-files-download -- --template react
```

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**

```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
```

**src/App.css**

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

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**

```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
    }
  ]
}
```

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**

```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
```

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

**src/App.css**

```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;
}
```

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**

```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
```

## 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](https://twitter.com/thomasfindlay94) and subscribe to the [newsletter](https://theroadtoenterprise.com/blog/subscribe)!