首页 > 解决方案 > 读取 CSV 并将其呈现为显示为 Datatables 不工作

问题描述

在下面的文件 app.py 中,读取 csv 内容并将其转换为字符串后,呈现的内容在数据表输出中作为单个列组合在一起。我如何将 csv 内容拆分为单独的列,以便它在数据表中正确呈现。我什至尝试将其转换为 to_dict 或 to_html 格式,但它不起作用。到目前为止,以数据表格式呈现我的 csv 内容的最佳输出是通过将其转换为字符串。

应用程序.py

from flask import Flask,url_for, render_template, redirect, request
import csv
import pandas as pd

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def root():
    if request.method == 'GET':
        return render_template('home.html')
    elif request.method == 'POST':
        results = []

        file = request.form['upload-file']
        data = pd.read_csv(file)
        reader = csv.DictReader(data)
        
        for row in reader:
             results.append(dict(row))

        fieldnames = [key for key in results[0].keys()]

        return render_template('home.html', results=results, fieldnames=fieldnames, len=len)

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

主页.html

<!DOCTYPE html>
<html>
  <head>
    <!-- Favicon -->
    <!--link rel="shortcut icon" href="{{url_for('static', filename='images/favicon.ico')}}"-->


    <!-- Bootstrap -->
    <!--<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">-->
    <!-- CSS only -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">

    <!-- JS, Popper.js, and jQuery -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
    <!-- Datatable -->
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.min.css">
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.21/r-2.2.5/datatables.min.css"/>
    <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.21/r-2.2.5/datatables.min.js"></script>
  </head>
  <body>
    <div class="card">
      <div class="card-body">
        <form method="post">
          <input type="file" class="form-control" rows="5" name="upload-file">
          <button class="btn btn-success mt-2">Render CSV</button>
        </form>
        <div class="mt-4">
          {% if request.method == 'POST'%}
            <table id="proxies" class="display table table-striped table-bordered responsive hover nowrap" style="width: 100%">
              <thead>
                <tr>
                  {% for header in results[0].keys() %}
                    <th>{{header}}</th>
                  {% endfor %}
                </tr>
              </thead>
              <tbody>
                {% for row in results %}
                  <tr>
                    {% for index in range(0, len(fieldnames)) %}
                      <td>{{row[fieldnames[index]]}}</td>
                    {% endfor %}
                  </tr>
                {% endfor %}
              </tbody>
            </table>
          {% endif %}
        </div>
      </div>
    </div>
  </body>
  <!-- JQuery -->
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>-->

  <!--dataTables-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
  <script type = "text/javascript" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
  <script type = "text/javascript" src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.min.js"></script>
  <script type = "text/javascript" src="https://cdn.datatables.net/plug-ins/1.10.15/dataRender/datetime.js"></script>



  <script type="text/javascript">
    $('#proxies').DataTable();
  </script>

</html>

输出: 在此处输入图像描述

标签: pythonpandasflaskbootstrap-4datatables

解决方案


使用Flask. 我的 HTML 没有任何 CSS,所以它的格式是默认的。此外,我正在使用端口 3000,因为我正在将端口 5000 用于另一个应用程序。

import pandas as pd, json
from flask import Flask, redirect, url_for, request, render_template, Response

app = Flask(__name__)

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

@app.route('/handle_data', methods=["POST"])
def handle_data():
    df = pd.read_csv("players.csv")
    return Response(df.to_html())

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

主页.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
</head>
<body>
    <main id="main">
        <section id="data-section">
            <h2>Data</h2>
            <div id="data"/>
        </section>
    </main>
</body>
<script>
    function apicall(url) {
        $.ajax({
            type:"POST", url:url, 
            success: (data) => { $("#data").html(data); }
        });
    }
    window.onload = function () {
        apicall("/handle_data");
    }
</script>
</html>

输出

在此处输入图像描述

保留表格格式

这将意味着 DOM 中的表具有与您相同的id 样式home.html

            success: (data) => { 
                $("#data").html(data);
                t = $("#data>table");
                t.attr("id", "proxies");
                t.addClass("display table table-striped table-bordered responsive hover nowrap");
                t.css({"width":"100%"});
             }

推荐阅读