source

React.js에서 CSV 파일을 업로드하고 읽는 방법은 무엇입니까?

lovecheck 2023. 3. 28. 21:53
반응형

React.js에서 CSV 파일을 업로드하고 읽는 방법은 무엇입니까?

사용자가 .csv 파일을 업로드한 후 브라우저로 해당 파일의 데이터를 해석할 수 있도록 하고 싶습니다.React JS를 사용하고 있습니다.이게 어떻게 작동할까요?감사해요.

알아냈어.react-file-reader와 HTML5의 FileReader의 조합(이 페이지 참조).

렌더 내부에 react-file-reader 비트를 배치했습니다.

<ReactFileReader handleFiles={this.handleFiles} fileTypes={'.csv'}>
    <button className='btn'>Upload</button>
</ReactFileReader>

그리고 위에 이거.

handleFiles = files => {
    var reader = new FileReader();
    reader.onload = function(e) {
        // Use reader.result
        alert(reader.result)
    }
    reader.readAsText(files[0]);
}

Papa Parse(https://www.npmjs.com/package/papaparse)를 사용합니다.다음은 반응 컴포넌트의 예입니다.

class FileReader extends React.Component {
  constructor() {
    super();
    this.state = {
      csvfile: undefined
    };
    this.updateData = this.updateData.bind(this);
  }

  handleChange = event => {
    this.setState({
      csvfile: event.target.files[0]
    });
  };

  importCSV = () => {
    const { csvfile } = this.state;
    Papa.parse(csvfile, {
      complete: this.updateData,
      header: true
    });
  };

  updateData(result) {
    var data = result.data;
    console.log(data);
  }

  render() {
    console.log(this.state.csvfile);
    return (
      <div className="App">
        <h2>Import CSV File!</h2>
        <input
          className="csv-input"
          type="file"
          ref={input => {
            this.filesInput = input;
          }}
          name="file"
          placeholder={null}
          onChange={this.handleChange}
        />
        <p />
        <button onClick={this.importCSV}> Upload now!</button>
      </div>
    );
  }
}

export default FileReader;

React(React.js)에서 CSV 파일을 업로드 및 읽는 가장 쉬운 방법은 react-paparse(Home | Demo | Docs | Github )입니다.

다음의 간단한 예를 참조해 주세요.

import React, { Component } from 'react'
import { CSVReader } from 'react-papaparse'

const buttonRef = React.createRef()

export default class CSVReader1 extends Component {
  handleOpenDialog = (e) => {
    // Note that the ref is set async, so it might be null at some point
    if (buttonRef.current) {
      buttonRef.current.open(e)
    }
  }

  handleOnFileLoad = (data) => {
    console.log('---------------------------')
    console.log(data)
    console.log('---------------------------')
  }

  handleOnError = (err, file, inputElem, reason) => {
    console.log(err)
  }

  handleOnRemoveFile = (data) => {
    console.log('---------------------------')
    console.log(data)
    console.log('---------------------------')
  }

  handleRemoveFile = (e) => {
    // Note that the ref is set async, so it might be null at some point
    if (buttonRef.current) {
      buttonRef.current.removeFile(e)
    }
  }

  render() {
    return (
      <>
        <h5>Basic Upload</h5>
        <CSVReader
          ref={buttonRef}
          onFileLoad={this.handleOnFileLoad}
          onError={this.handleOnError}
          noClick
          noDrag
          onRemoveFile={this.handleOnRemoveFile}
        >
          {({ file }) => (
            <aside
              style={{
                display: 'flex',
                flexDirection: 'row',
                marginBottom: 10
              }}
            >
              <button
                type='button'
                onClick={this.handleOpenDialog}
                style={{
                  borderRadius: 0,
                  marginLeft: 0,
                  marginRight: 0,
                  width: '40%',
                  paddingLeft: 0,
                  paddingRight: 0
                }}
              >
                Browe 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={this.handleRemoveFile}
              >
                Remove
              </button>
            </aside>
          )}
        </CSVReader>
      </>
    )
  }
}

다른 답변에서는 Papa Parse를 사용한 브라우저 기반 파싱에 대해 언급하고 있습니다.또한 gluestick(https://github.com/hotgluexyz/gluestick)은 사전 빌드된 React 컴포넌트와 백엔드 기반 파싱을 사용합니다.

입력 데이터 또는 열 매핑에 대한 검증을 수행할 경우 React 구성 요소와 함께 패키지된 Python 백엔드 API를 볼 것을 권장합니다.

Repo는 CodeSandbox(https://1c1dl.csb.app/) 데모를 링크합니다.

2022년 5월 갱신

앞서 언급한 바와 같이 https://github.com/GrillWork/react-file-reader은 권장되지 않으며 https://github.com/mholt/PapaParse의 마지막 릴리스는 2020년 8월입니다.

노드 및 브라우저용 csv-browser https://csv.js.org/parse/을 사용하였습니다.

CSB -> https://codesandbox.io/s/react-file-upload-parse-csv-09plq1?file=/src/App.tsx

App.tsx

import { ChangeEvent, useState } from "react";
import { Button, Box } from "@mui/material";
import { DataGrid } from "@mui/x-data-grid";
import UploadFileIcon from "@mui/icons-material/UploadFile";
import { parse } from "csv-parse/browser/esm/sync";

type cvsItem = {
  id: string;
  value: string;
};

const columns = [
  {
    field: "id",
    headerName: "Id"
  },
  {
    field: "value",
    headerName: "Value"
  }
];

export default function App() {
  const [csvData, setCsvData] = useState<cvsItem[]>([]);
  const [filename, setFilename] = useState("");

  const handleFileUpload = (e: ChangeEvent<HTMLInputElement>) => {
    if (!e.target.files) {
      return;
    }
    const file = e.target.files[0];
    const { name } = file;
    setFilename(name);

    const reader = new FileReader();
    reader.onload = (evt) => {
      if (!evt?.target?.result) {
        return;
      }
      const { result } = evt.target;
      const records = parse(result as string, {
        columns: ["id", "value"],
        delimiter: ";",
        trim: true,
        skip_empty_lines: true
      });
      setCsvData(records);
    };
    reader.readAsBinaryString(file);
  };

  return (
    <>
      <Button
        component="label"
        variant="outlined"
        startIcon={<UploadFileIcon />}
      >
        Upload CSV
        <input type="file" accept=".csv" hidden onChange={handleFileUpload} />
      </Button>
      <Box>{filename}</Box>
      <DataGrid
        autoHeight
        rows={csvData}
        columns={columns}
        hideFooter
        sx={{ mt: 1 }}
      />
    </>
  );
}

test File.csv

1;one
2;two
3;three

다음은 CSV의 콘텐츠를 업로드/읽기 위한 순수 JS 솔루션(React에서 작동)입니다.

<input
  accept=".csv"
  hidden
  id="csvInput"
  onChange={() => {
    const reader = new FileReader();
    reader.onload = () => {
      // @ts-ignore
      document.getElementById('out').innerHTML = reader.result;
    };
    // start reading the file. When it is done, calls the onload event defined above.
    // @ts-ignore
    reader.readAsBinaryString(document.getElementById('csvInput').files[0]);
  }}
  type="file"
/>
<pre id="out"><p>File contents will appear here</p></pre>

언급URL : https://stackoverflow.com/questions/44769051/how-to-upload-and-read-csv-files-in-react-js

반응형