How to upload CSV file in Mui-Datatables and display in the table? I am new to Mui-Datatable
A way to upload CSV files to MUI Datatables is to use the npm package React-Papaparse.
I have set up a Code Sandbox here as an example of how it could be set up.
name,city,company,state
Hansiain Babar,Richmond,Mybuzz,Virginia
Carissa Lenormand,Pittsburgh,Yambee,Pennsylvania
Weber Skeath,Young America,Mymm,Minnesota
Ashton Pashan,Loretto,Brainsphere,Minnesota
Willi Martignoni,Minneapolis,Realmix,Minnesota
Aarika Philippart,Tacoma,Fadeo,Washington
Crichton Worpole,Inglewood,Edgetag,California
Marna Climer,Colorado Springs,Flashspan,Colorado
Gilemette Arington,Amarillo,Trudeo,Texas
Maryanne Gostage,Richmond,Skyba,Virginia
This is essentially pulled from the React-Paparse Docs, but with the config={{headers: true}}:
import React from "react";
import { CSVReader } from "react-papaparse";
const buttonRef = React.createRef();
const CSVReader1 = (props) => {
const { setCSVData } = props;
const handleOpenDialog = (e) => {
// Note that the ref is set async, so it might be null at some point
if (buttonRef.current) {
buttonRef.current.open(e);
}
};
const handleOnFileLoad = (data) => {
console.log("---------------------------");
console.log(data);
/* *** When the headers config option is set to 'true', it
returns an empty object as the last item in the array,
so we need to remove it: *** */
data.pop();
setCSVData(data);
console.log("---------------------------");
};
const handleOnError = (err, file, inputElem, reason) => {
console.log("---------------------------");
console.log(err);
console.log("---------------------------");
};
const handleOnRemoveFile = (data) => {
console.log("---------------------------");
console.log(data);
console.log("---------------------------");
};
const handleRemoveFile = (e) => {
// Note that the ref is set async, so it might be null at some point
if (buttonRef.current) {
buttonRef.current.removeFile(e);
}
};
return (
<>
<h5>Basic Upload</h5>
<CSVReader
ref={buttonRef}
onFileLoad={handleOnFileLoad}
onError={handleOnError}
noClick
noDrag
config={{ header: true }}
onRemoveFile={handleOnRemoveFile}
>
{({ file }) => (
<aside
style={{
display: "flex",
flexDirection: "row",
marginBottom: 10
}}
>
<button
type="button"
onClick={handleOpenDialog}
style={{
borderRadius: 0,
marginLeft: 0,
marginRight: 0,
width: "40%",
paddingLeft: 0,
paddingRight: 0
}}
>
Browse file
</button>
<div
style={{
borderWidth: 1,
borderStyle: "solid",
borderColor: "#ccc",
height: 45,
lineHeight: 2.5,
marginTop: 5,
marginBottom: 5,
paddingLeft: 13,
paddingTop: 3,
width: "60%"
}}
>
{file && file.name}
</div>
<button
style={{
borderRadius: 0,
marginLeft: 0,
marginRight: 0,
paddingLeft: 20,
paddingRight: 20
}}
onClick={handleRemoveFile}
>
Remove
</button>
</aside>
)}
</CSVReader>
</>
);
};
export default CSVReader1;
Here, we have a customToolbar component, which is basically the same a the default toolbar but with an extra button we will add to upload the CSV file:
import React, { useEffect, useState } from "react";
import IconButton from "@material-ui/core/IconButton";
import Tooltip from "@material-ui/core/Tooltip";
import AddCircleOutlineIcon from "@material-ui/icons/AddCircleOutline";
import { makeStyles } from "@material-ui/core/styles";
import Modal from "@material-ui/core/Modal";
import Button from "@material-ui/core/Button";
import CSVUploader from "./CSVUploader.jsx";
const useStyles = makeStyles((theme) => ({
paper: {
margin: "0 auto",
top: "25vh",
position: "relative",
width: 400,
backgroundColor: theme.palette.background.paper,
border: "2px solid #000",
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3)
}
}));
const CustomToolbar = (props) => {
const { setDataForTable } = props;
const classes = useStyles();
const [open, setOpen] = useState(false);
const [CSVData, setCSVData] = useState([]);
// When CSVData is updated, parse it and pass it up to the Table:
useEffect(() => {
const dataArr = Array.from(CSVData).map((data) => {
// Make sure values are truth before returning:
if (data.data.name && data.data.city) {
return {
name: data.data.name,
company: data.data.company,
city: data.data.city,
state: data.data.state
};
}
});
setDataForTable(dataArr);
}, [CSVData, setDataForTable]);
// Open and close modal
const handleOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
/* Custom Button to open upload modal */
return (
<>
<Tooltip title={"Add data from CSV"}>
<IconButton>
<AddCircleOutlineIcon onClick={handleOpen} />
</IconButton>
</Tooltip>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<div className={classes.paper}>
<h2 id="simple-modal-title">Upload CSV Data</h2>
<CSVUploader setCSVData={setCSVData} />
<Button onClick={handleClose}>Close Modal</Button>
</div>
</Modal>
</>
);
};
export default CustomToolbar;
And here, we pass the customToolbar component to the table options:
import React, { useState } from "react";
import MUIDataTable from "mui-datatables";
import CustomToolbar from "./CustomToolbar.jsx";
const columns = [
{
name: "name",
label: "Name",
options: {
filter: true,
sort: true
}
},
{
name: "company",
label: "Company",
options: {
filter: true,
sort: true
}
},
{
name: "city",
label: "City",
options: {
filter: true,
sort: true
}
},
{
name: "state",
label: "State",
options: {
filter: true,
sort: true
}
}
];
const Table = () => {
// Parse csv data from CustomToolbar:
const [dataForTable, setDataForTable] = useState();
// Custom Table options with custom toolbar:
const options = {
filterType: "checkbox",
customToolbar: () => {
return <CustomToolbar setDataForTable={setDataForTable} />;
}
};
// Table
return (
<MUIDataTable
title={"Employee List"}
data={dataForTable}
columns={columns}
options={options}
/>
);
};
export default Table;