Skip to content Skip to sidebar Skip to footer

How To Upload A File And Populate Parts Of The Website With Its Content?

There are related questions here and here but they don't solve my problem. Let's say I have a file testdata.csv like this: A,B 1,3 2,4 and I want the user allow to upload the file

Solution 1:

@charlietfl in the comments and this link got me on the right track. One can use FormData and then an .ajax call to achieve the desired outcome. So the important parts of above's link are (the complete files can be found below):

<form method="POST" enctype="multipart/form-data" id="fileUploadForm">
    <div class="custom-file">
       <input id="myfile" name="myfile" type="file" class="custom-file-input">

         <label for="myfile" class="custom-file-label">
             Choose file...
         </label>
    </div>
</form>

and

// Get form
var form = $('#fileUploadForm')[0];

// Create an FormData object
var data = new FormData(form);

and

$.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/_get_table",
        data: data,
        processData: false,

The processData: false, is important to prevent jQuery form transforming the data into a query string as explained in the link above.

On the flask site, we can then easily retrieve the file by doing:

file = request.files['myfile']

df = pd.read_csv(file)

which turns the .csv into a pandas dataframe. Clearly, there should be checks etc before doing this.

The entire HTML page index_formdata.html would look like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link  href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
    <link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" >
  </head>
  <body>
    <div class="container">
      <div class="header">
        <h3 class="text-center text-muted">Some great stuff</h3>
      </div>

      <hr class="mb-4">
      <form method="POST" enctype="multipart/form-data" id="fileUploadForm">
        <div class="custom-file">
           <input id="myfile" name="myfile" type="file" class="custom-file-input">

           <label for="myfile" class="custom-file-label">
             Choose file...
           </label>
        </div>
      </form><br><br>

      <button class="btn btn-primary" type="button" id="upload_document">Upload and process!</button>

      <hr class="mb-4">

      <table id="pretty_table" class="table table-striped"></table>

      <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
      <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
      <script type="text/javascript">
        $(document).ready(function () {

            var table = null;

            $("#upload_document").click(function (event) {

                //stop submit the form, we will post it manually.
                event.preventDefault();

                // Get form
                var form = $('#fileUploadForm')[0];

                // Create an FormData object
                var data = new FormData(form);

                // disabled the submit button
                $("#upload_document").prop("disabled", true);

                $.ajax({
                    type: "POST",
                    enctype: 'multipart/form-data',
                    url: "/_get_table",
                    data: data,
                    processData: false,
                    contentType: false,
                    cache: false,
                    timeout: 600000,
                    success: function (data) {

                      if (table !== null) {
                        table.destroy();
                        table = null;
                        $("#pretty_table").empty();
                      }
                      table = $("#pretty_table").DataTable({
                        data: data.my_table,
                        columns: data.columns

                      });
                      $("#upload_document").prop("disabled", false);

                    },
                    error: function (e) {

                        alert(e.responseText);
                        console.log("ERROR : ", e);
                        $("#upload_document").prop("disabled", false);

                    }
                });

            });
            $('.custom-file-input').on('change', function() {
               let fileName = $(this).val().split('\\').pop();
               $(this).next('.custom-file-label').addClass("selected").html(fileName);
            });

        });
      </script>
  </body>
</html>

the flask file as follows:

from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json

# Initialize the Flask application
app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index_formdata.html')


@app.route('/_get_table', methods=["POST", "GET"])
def get_table():

    # catch file from the form; if you have several files, just make several requests (access by name)
    file = request.files['myfile']

    df = pd.read_csv(file)

    return jsonify(my_table=json.loads(df.to_json(orient="split"))["data"],
                   columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])

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

and the testdata.csv file

A,B,C
1,3,123
2,4,456

Post a Comment for "How To Upload A File And Populate Parts Of The Website With Its Content?"