In many web applications, exporting data is a must-have feature for users who need to download and analyze data offline. In this article, we’ll learn how to fetch data from an API using Axios and export it as a CSV file using the react-CSV library.
This article is perfect for React developers looking to integrate CSV download functionality in their apps.
Prerequisites
To follow along, make sure you have,
- Basic knowledge of React
- Node.js and npm installed
- A React project set up
Step 1. Set Up Your React App.
If you haven’t already created a React project, you can do so using the following steps.
In my previous article, I provided a step-by-step guide to setting up a React.js application with Material-UI. Please read it's beneficial for beginners: “How To Integrate Material UI With React.js"
I'll explain this again shortly. These steps.
npx create-react-app react-csv-export
cd react-csv-export
npm start
The command npx create-react-app react-csv-export is used to create a new React application react-csv-export using the Create React App tool. It creates a ready-to-use React project with all the necessary files and configurations. After the project is created, cd react-csv-export changes the current directory to the new project folder so you can start working inside it. Finally, npm start launches the development server and opens the app in your default browser, allowing you to see your React application running locally.
![Create React App]()
Image 1. The react-csv-export project is created
Install the Material UI
Go to the Material-UI website and get some instructions. There are some types of versions(V4, V5, V6, and V7) in Material-UI.
![Material UI]()
Image 2. Types of versions(V4, V5, V6, and V7) in Material-UI.
Now I'm going to install the Mui and Style.
npm install @mui/material @emotion/react @emotion/styled
Google Web Fonts
To install Roboto via the Google Web Fonts CDN, insert the following code inside the <head> tag of your project.
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;600;700&display=swap" />
- Go to the public folder in your project and open the index.html file.
- Copy the CDN code and paste it inside the <head> tag of the index.html.
Run the app and get out like this.
![Run app]()
Image 3. See the view.
Now we will create the Custom Table component and use it there.
Create the components folder, add the BasicTable.jsx file, and update it with the following code. This sample table for viewing purposes demonstrates how to use the MUI Table component.
BasicTable.jsx
import React from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';
import "../App.css";
const BasicTable = () => {
const rows = [
{ name: 'John', age: 28, city: 'New York' },
{ name: 'Anna', age: 22, city: 'London' },
{ name: 'Mike', age: 32, city: 'Paris' },
];
return (
<TableContainer component={Paper} className="tableStyles">
<Table>
<TableHead className="tableHeadStyles">
<TableRow>
<TableCell>Name</TableCell>
<TableCell>Age</TableCell>
<TableCell>City</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, index) => (
<TableRow key={index}>
<TableCell>{row.name}</TableCell>
<TableCell>{row.age}</TableCell>
<TableCell>{row.city}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
export default BasicTable;
Add the CSS part to this.
.tableStyles {
border: '1px solid black';
border-collapse: collapse;
}
.tableHeadStyles {
font-size: 16px;
font-weight: bold;
}
App.js is called the BasicTable component.
import React from "react";
import "./App.css";
import BasicTable from "./component/BasicTable";
function App() {
return (
<div className="App">
<header className="App-header">
<div>Exporting Table Data to CSV in React</div>
</header>
<main>
<div className="App-content">
<BasicTable />
</div>
</main>
</div>
);
}
export default App;
Now we can see the view.
![View]()
Image 4. See the Table view with sample data.
Step 2. Install Axios.
We’ll use Axios to fetch the data and handle CSV export.
npm install axios
Now I'm going to install Axios.
Axios is installed in React to easily make HTTP requests (like GET, POST) to servers.
It simplifies handling requests and responses compared to the native fetch API.
Fetch API Data from a fake API
Here I'm using jsonplaceholder fake Api
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get("https://jsonplaceholder.typicode.com/users");
setData(response.data);
} catch (error) {
console.error("Error fetching data:", error);
}
};
fetchData();
}, []);
console.log("Data fetched from API:---->", data);
const [data, setData] = useState([]);
This creates a piece of state called data. It starts as an empty array.
SetData is a function that lets you change data.
useEffect(() => { ... }, []);
This is a React hook that runs some code after the component is first loaded (mounted).
The empty array [] means it runs only once, not on every render.
Inside useEffect, there's a function called fetchData.
- It uses axios.get(...) to fetch data from a fake API (https://jsonplaceholder.typicode.com/users).
- If successful, it stores the result in data using setData(...).
- If there’s an error, it prints an error message in the console.
fetchData() is called immediately inside useEffect to start the fetching.
console.log("Data fetched from API:---->", data);
This prints the data to the console each time the component renders.
![Console]()
Image 5. Console mock user data.
Now we going to map the data to our table.
We're passing a prop called data to the BasicTable component.
The right-hand data is the variable from useState.
<BasicTable data={data} />
import React from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';
import "../App.css";
const BasicTable = ({ data }) => {
if (!data || data.length === 0) {
return <div>No data available</div>;
}
return (
<TableContainer component={Paper} className="tableStyles">
<Table>
<TableHead className="tableHeadStyles">
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Name</TableCell>
<TableCell>Username</TableCell>
<TableCell>Email</TableCell>
<TableCell>City</TableCell>
<TableCell>Phone</TableCell>
<TableCell>Website</TableCell>
<TableCell>Company Name</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id} className="tableRowStyles">
<TableCell className="tableCellStyles">{row.id}</TableCell>
<TableCell className="tableCellStyles">{row.name}</TableCell>
<TableCell className="tableCellStyles">{row.username}</TableCell>
<TableCell className="tableCellStyles">{row.email}</TableCell>
<TableCell className="tableCellStyles">{row.address.city}</TableCell>
<TableCell className="tableCellStyles">{row.phone}</TableCell>
<TableCell className="tableCellStyles">{row.website}</TableCell>
<TableCell className="tableCellStyles">{row.company.name}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
export default BasicTable;
![Table]()
Image 6. Mock user data mapped.
Step 3. Install react-csv.
The react-csv package is a simple and helpful library that lets you export data as a CSV file in a React app.
CSV = Comma-Separated Values, a plain text format often used for spreadsheets (like Excel or Google Sheets). Each row is a line of text, and a comma separates each column.
npm install react-csv
Now I'm going to install react-csv.
I’m adding this code to app.js.
<div className="export-button-container">
{data && (
<>
<Button variant="contained" color="primary">
<CSVLink
data={data}
headers={headers}
filename={"table-data.csv"}
className="btn btn-primary"
target="_blank"
>
Export to CSV
</CSVLink>
</Button>
</>
)}
</div>
The <CSVLink> component creates a downloadable CSV file link in a React app. It takes in a data prop, the actual array of data you want to export, and a headers prop to define custom column labels and the order in which they appear in the file. The filename prop sets the name of the file that will be downloaded—in this case, "table-data.csv". It also has a className for styling, often using Bootstrap to make it look like a button, and the target="_blank" attribute ensures the download opens in a new tab if needed. When users click the "Export to CSV" link, the data is automatically formatted into a CSV and downloaded to their device.
{data && (...)}
This checks if data exists. If it does, the button is shown. If the data is empty or null, nothing is rendered.
<CSVLink>
This comes from the react-csv library. It wraps around the button and handles the CSV file creation and download.
Props inside CSVLink.
- data={data}: the actual data to export.
- headers={headers}: optional column headers for the CSV.
- filename={"table-data.csv"}: the name of the file to download.
- target="_blank": opens the download in a new tab.
The text inside the CSVLink — "Export to CSV" — is what users see and click.
The peace of the code is to be updated in app.js and BasicTable
App.js
import React, { useEffect, useState } from "react";
import axios from "axios";
import "./App.css";
import BasicTable from "./component/BasicTable";
import { CSVLink, CSVDownload } from "react-csv";
import { Button } from "@mui/material";
function App() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
setData(response.data);
} catch (error) {
console.error("Error fetching data:", error);
}
};
fetchData();
}, []);
console.log("Data fetched from API:---->", data);
const headers = [
{ label: "ID", key: "id" },
{ label: "Name", key: "name" },
{ label: "Username", key: "username" },
{ label: "Email", key: "email" },
{ label: "Phone", key: "phone" },
{ label: "Website", key: "website" }
];
return (
<div className="App">
<header className="App-header">
<div>Exporting Table Data to CSV in React</div>
<div className="export-button-container">
{data && (
<>
<Button variant="contained" color="primary">
<CSVLink
data={data}
headers={headers}
filename={"table-data.csv"}
className="btn btn-primary"
target="_blank"
>
Export to CSV
</CSVLink>
</Button>
</>
)}
</div>
</header>
<main>
<div className="App-content">
<BasicTable data={data} headers={headers} />
</div>
</main>
</div>
);
}
export default App;
BasicTable.jsx
import React from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';
import "../App.css";
const BasicTable = ({ data, headers }) => {
if (!data || data.length === 0) {
return <div>No data available</div>;
}
return (
<TableContainer component={Paper} className="tableStyles">
<Table>
<TableHead className="tableHeadStyles">
<TableRow>
{headers.map((header) => (
<TableCell key={header.key}>{header.label}</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{data.map((row, rowIndex) => (
<TableRow key={rowIndex} className="tableRowStyles">
{headers.map((header) => (
<TableCell key={header.key} className="tableCellStyles">
{header.key.split('.').reduce((acc, key) => acc && acc[key], row)}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
};
export default BasicTable;
I'm going to run my app.
![Export]()
Image 7. The Download button is available.
No, I'm going to click on the Export CSV button.
![Csv]()
Image 8. See here, it has been downloaded successfully.
Will check the Excel view.
![Excel]()
Image 9. See the view.
Conclusion
With just a few lines of code, you can fetch data using Axios and export it to CSV using react-csv. This feature is handy for admin panels, data management tools, and reporting dashboards.