简体   繁体   中英

Displaying a CSV file using react frontend and flask backend

I'm trying to read a csv file using flask and then display it through react (The display part should be compulsorily done through react). I'm stuck at the return part of js file.

This is the flask( .py )code:

from flask import Flask,render_template,request
import os
import pandas as pd

app=Flask(__name__)
app.secret_key="123"

app.config["UPLOAD_FOLDER1"]="static/csv"

@app.route("/upload",methods=['GET','POST'])
def upload():
    return render_template("UploadCsv.html")

@app.route("/display",methods=["GET","POST"])
def display():
    upload_file = request.files['upload_csv']
    if upload_file.filename != '':
            file_path = os.path.join(app.config["UPLOAD_FOLDER1"], upload_file.filename)
            upload_file.save(file_path)
            data=pd.read_csv(file_path,sep=",")
            return render_template("CsvContent.html",data=data.to_html(index=False))

if __name__=='__main__':
    app.run(debug=True)

And here are the two HTMLs used in the.py file above: UploadCsv.html

<html>
    <head>
        <title>Upload CSV File</title>
    </head>
    <body>
        <div class="col-md-offset-3 col-md-5" style="margin-top:70px">
            <form method="POST" action="http://127.0.0.1:5000/display" enctype="multipart/form-data">
                <h3 class="page-header text-primary">Upload CSV File</h3>
                <div class="form-group">
                    <label>Browse CSV File</label>
                    <input type="file" class="form-control" name="upload_csv">
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-success btn-block">Upload CSV</button>
                </div>
            </form>
        </div>
    </body>
</html>

CsvContent.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSV File</title>
</head>
<body>
    <h2>Here's your uploaded CSV file :</h2>
    {{data|safe}}
</body>
</html>

This successfully reads and displays the CSV file completely through Flask. Now, here's the catch, I have to integrate react too. And this is where I'm messing up. Here's my React code, if it helps.

 const[csvupload,setCsvUpload] = useState()

useEffect(()=> {

  fetch('http://127.0.0.0:5000/display',{

    'method':'POST',

    headers: {

      'Content-Type' : 'application/json'

    }

  })

  .then(resp => resp.json())

  .then(resp => setCsvUpload(resp))

  .catch(error => console.log(error))

},[])

  return (

   

    <Fragment>

      <div className="upload" >

          Upload Your CSV File
       
            <Row md={12}>

                <Col md={6} className="body-upload">

                <input type="file" accept=".csv" onChange={handleFileUpload} multiple />  

                <button onClick={modalOpen}> UPLOAD </button>

                </Col>
            </Row>

            {csvupload.map(csv =>{

              return( 
(**What should be here?**)

                <div>


                </div>

              )

            })}

      </div>

    </Fragment>

  );

};

export default UploadFile;

How can I return the CSV file through react? I am using fetch here, is it even the right method? What should I put inside the return method so that when I upload the csv, it should read the file, store in "static/csv" (as given in the flask code) and display the file below before clicking Upload. I know its a long question, but please help. Any kinda help would be appreciated and I'm willing to provide information required.

Few things you can do:

  1. The call you make to /display has no payload being sent. If that is the case, you can change to a GET call

  2. Parsing the csv directly on the frontend can be resource intensive depending on the content. It would be better for you to parse it on the backend itself and then send the JSON to react that looks like the following (or any other structure based on your needs):

 // option1 { row1: [col1, col2], row2: [col1, col2] } // or send an array of rows // option2 [[col1, col2], [col1, col2]]

  1. Once you have the parsed csv content you can use it like this on react:

 // option 2 { csvupload.map((row) => { // you can format as per your requirement // col1=row[0] and col2=row[1] return <div>{row}</div>; }) }

 // option 1 { Object.keys(csvupload).map((rowIndex) => { // you can format as per your requirement // col1=csvupload[rowIndex][0] and col2=csvupload[rowIndex][1] return <div>{csvupload[rowIndex]}</div>; }) }

Personally, I feel option 1 would be better. But you can change this structure based on whatever best fits your requirements.

Edit: based on comment

  1. This answer might help for parsing what to do ,
  2. and the docs for the function used further info in docs
  3. In option1, Object.keys(csvupload) returns an array of keys. rowIndex is an index of this array. When passed into the csvupload JSON, it returns the column array [col1, col2]
  4. In option2, row is the array of columns in that specific row [col1, col2] (same as option1)
  5. Both options give the same result. It's just a difference of how you are accessing the value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM