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
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
src/App.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
{
"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
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
.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
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 and subscribe to the newsletter!
Top comments (0)