如何上传文件并用其内容填充网站的某些部分? [英] How to upload a file and populate parts of the website with its content?

查看:100
本文介绍了如何上传文件并用其内容填充网站的某些部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处

There are related questions here and here but they don't solve my problem.

假设我有一个文件testdata.csv如下:

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 and then - just for simplicity - display its content on the same page without affecting any other elements on this page. So my desired outcome would look like this:

我该怎么做?我发现了几种使用form加载文件并将其(修改后的)内容发送回(例如下载)的方法,但是我很难找到一种解决方法来将JSON响应传回以修改页面(此处:添加表格).

How would I do this? I found a couple of approaches that use a form to load the file and send its (modified) content back (to e.g. download it) but I struggle to find a solution to pass the JSON response back to modify the page (here: add the table).

这是我的完整代码:

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.html')


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

    # how to catch the file here and send its content back?
    # file = ????
    # print(file)
    df = pd.DataFrame({"A": [1, 2], "B": [3, 4]})

    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 I use a form, I can use
    # file = request.files['myfile']
    # however, how do I then send the JSON response?

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

和我的index.html文件:

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" 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" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <div class="header">
        <h3 class="text-center text-muted">Some great stuff</h3>
      </div>

      <hr class="mb-4">

      <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><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').bind('click', function() {

            $.getJSON('/_get_table', {
              // what to pass here?
            }, function(data) {

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

              });
            });
            return 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>

注释中的

推荐答案

@charlietfl和

@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>

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

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

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

processData: false,对于防止jQuery形式将数据转换为查询字符串很重要,如上面的链接所述.

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

然后在flask网站上,我们可以通过以下操作轻松地检索文件:

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

file = request.files['myfile']

df = pd.read_csv(file)

会将.csv转换为熊猫数据框.显然,在执行此操作之前,应该先进行检查等.

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

整个HTML页面index_formdata.html看起来像这样:

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

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" 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" rel="stylesheet">
  </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>

flask文件如下:

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)

testdata.csv文件

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

这篇关于如何上传文件并用其内容填充网站的某些部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆