React  

Export Table Data as CSV in React Using Axios and react-csv

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" />
  1. Go to the public folder in your project and open the index.html file.
  2. 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.

Globally based Software Developing & Data Processing Company