在 Mui-Datatables 中上传 CSV 文件

Upload CSV file in Mui-Datatables

如何在Mui-Datatable中上传CSV文件并在table中显示? 我是新手Mui-Datatable

截至目前,MUI DataTable 中还没有现有功能,但这将是一个很好的功能请求。

解决方法是定义您自己的函数来解析 CSV 文件,其中 returns 一个 headers 数组和一个 objects 行记录数组。结果可以通过 props 传递

<MUIDataTable title={"Employee List"} data={myData} columns={myColumns} options={options} />

其中 myDatamyColumns 有 CSV 文件的记录和 headers。

一种将 CSV 文件上传到 MUI Datatables is to use the npm package React-Papaparse 的方法。

我已经设置了一个 Code Sandbox here 作为如何设置的示例。

MockData.csv

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

CSVUploader.jsx

这基本上是从 React-Paparse 文档中提取的,但是使用 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;

CustomToolbar.jsx

在这里,我们有一个 customToolbar 组件,它与默认工具栏基本相同,但我们将添加一个额外的按钮来上传 CSV 文件:

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;

Table.jsx

在这里,我们将 customToolbar 组件传递给 table 选项:

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;