Looking for a way to add an "Export to CSV" button to a react-table which is an npmjs package ().

I need to add a custom button for exporting the table data to an excel sheet in the csv or xls format?

3

4 Answers

Take a look at this npm library -

For example -

import {CSVLink, CSVDownload} from 'react-csv'; const csvData =[ ['firstname', 'lastname', 'email'] , ['John', 'Doe' , ''] , ['Jane', 'Doe' , ''] ]; <CSVLink data={csvData} >Download me</CSVLink> // or <CSVDownload data={csvData} target="_blank" /> 
2

Here is how integration will look like

import React from "react"; import "react-dropdown/style.css"; import "react-table/react-table.css"; import ReactTable from "react-table"; import { CSVLink } from "react-csv"; const columns = [ { Header: "name", accessor: "name", // String-based value accessors! }, { Header: "age", accessor: "age", }, ]; class AllPostPage extends React.Component { constructor(props) { super(props); this.download = this.download.bind(this); this.state = { tableproperties: { allData: [ { name: "ramesh", age: "12" }, { name: "bill", age: "13" }, { name: "arun", age: "9" }, { name: "kathy", age: "21" }, ], }, dataToDownload: [], }; } download(event) { const currentRecords = this.reactTable.getResolvedState().sortedData; var data_to_download = []; for (var index = 0; index < currentRecords.length; index++) { let record_to_download = {}; for (var colIndex = 0; colIndex < columns.length; colIndex++) { record_to_download[columns[colIndex].Header] = currentRecords[index][columns[colIndex].accessor]; } data_to_download.push(record_to_download); } this.setState({ dataToDownload: data_to_download }, () => { // click the CSVLink component to trigger the CSV download this.csvLink.link.click(); }); } render() { return ( <div> <div> <button onClick={this.download}>Download</button> </div> <div> <CSVLink data={this.state.dataToDownload} filename="data.csv" className="hidden" ref={(r) => (this.csvLink = r)} target="_blank" /> </div> <div> <ReactTable ref={(r) => (this.reactTable = r)} data={this.state.tableproperties.allData} columns={columns} filterable defaultFilterMethod={(filter, row) => String(row[filter.id]) .toLowerCase() .includes(filter.value.toLowerCase()) } /> </div> </div> ); } } export default AllPostPage; 

This will work with filters as well.

7

I have it implemented like this in React + Typescript (no dependency):

 /** * @desc get table data as json * @param data * @param columns */ const getTableDataForExport = (data: any[], columns: any[]) => data?.map((record: any) => columns .reduce((recordToDownload, column) => ( { ...recordToDownload, [column.Header]: record[column.accessor] } ), {})); /** * @desc make csv from given data * @param rows * @param filename */ const makeCsv = async (rows: any[], filename: string) => { const separator: string = ';'; const keys: string[] = Object.keys(rows[0]); const csvContent = `${keys.join(separator)}\n${ rows.map((row) => keys.map((k) => { let cell = row[k] === null || row[k] === undefined ? '' : row[k]; cell = cell instanceof Date ? cell.toLocaleString() : cell.toString().replace(/"/g, '""'); if (cell.search(/("|,|\n)/g) >= 0) { cell = `"${cell}"`; } return cell; }).join(separator)).join('\n')}`; const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); if (navigator.msSaveBlob) { // In case of IE 10+ navigator.msSaveBlob(blob, filename); } else { const link = document.createElement('a'); if (link.download !== undefined) { // Browsers that support HTML5 download attribute const url = URL.createObjectURL(blob); link.setAttribute('href', url); link.setAttribute('download', filename); link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } }; 

the table:

<Table data={data} columns={columns} /> 

and the button:

 <button type="button" onClick={() => makeCsv(getTableDataForExport(data, columns), `${filename}.csv`)} > Download table data CSV </button> 
1

I thought I'd piggyback on best wishes' extremely valuable answer with a simplified download implementation.

 export = e => { const currentRecords = this.ReactTable.getResolvedState().sortedData; this.setState({ dataToDownload: this.dataToDownload(currentRecords, columns) }, () => this.csvLink.link.click() ); } dataToDownload = (data, columns) => data.map(record => columns.reduce((recordToDownload, column) => { recordToDownload[column.Header] = record[column.accessor]; return recordToDownload; }, {}) ); 

I used this to allow multiple table exports in one component by adding additional export functions.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy