如何使用Flask为熊猫数据框设置“以csv格式下载”按钮?

时间:2019-12-06 03:42:16

标签: python pandas csv flask

我正在尝试为熊猫数据框(作为csv)设置下载按钮,但没有成功。

以下是我的views.py的相关功能:

Category

这是html页面,当前我在页面from flask import render_template, make_response from flask import send_file import numpy as np import matplotlib.pyplot as plt import pandas as pd import random import seaborn as sns @app.route("/jinja") def jinja(): my_name = "Testes" return render_template("/public/jinja.html", my_name=my_name) @app.route("/about") def about(): return render_template("/public/about.html") #defining parameters bast_param = [0,5] #ba prefix for below average student avst_param = [5,7] #av prefix for average student aast_param = [7,10] #aa prefix for above average student min_bast = bast_param[0] max_bast = bast_param[1] min_avst = avst_param[0] max_avst = avst_param[1] min_aast = aast_param[0] max_aast = aast_param[1] @app.route("/") def index(): #students quantities per parameter bast_qtd = 5 avst_qtd = 3 aast_qtd = 8 st_total = bast_qtd + avst_qtd + aast_qtd #Defining Subjects subjects = ["Disciplina 1", "Disciplina 2", "Disciplina 3", "Disciplina 4", "Disciplina 5"] students = [] #counter for students ids creation i = 0 #counters and variable for grades creation a = 0 b = 0 newgradeline = [] grade = [] #creating students and grades while(i < st_total): newstudent = random.randint(100000,199999) #excluding duplicates if newstudent not in students: students.append(newstudent) i = i+1 # In[3]: #below averagge students while (a < bast_qtd): b = 0 newgradeline = [] grade.append(newgradeline) while (b<len(subjects)): gen_grade = round(random.uniform(bast_param[0],bast_param[1]),2) newgradeline.append(gen_grade) b = b+1 a = a +1 a = 0 #average students while (a < avst_qtd): b = 0 newgradeline = [] grade.append(newgradeline) while (b<len(subjects)): gen_grade = round(random.uniform(avst_param[0],avst_param[1]),2) newgradeline.append(gen_grade) b = b+1 a = a +1 a = 0 #above average students while (a < aast_qtd): b = 0 newgradeline = [] grade.append(newgradeline) while (b<len(subjects)): gen_grade = round(random.uniform(aast_param[0],aast_param[1]),2) newgradeline.append(gen_grade) b = b+1 a = a +1 # In[4]: #generating table simulation = pd.DataFrame (grade,index=students, columns=subjects) return render_template('/public/index.html',table=simulation.to_html(),download_csv=simulation.to_csv(index=True, sep=";")) @app.route("/parameters") def parameters(): return render_template('/public/parameters.html', min_bast=min_bast, max_bast=max_bast, min_avst=min_avst,max_avst=max_avst, min_aast=min_aast, max_aast=max_aast) 上以文本形式显示csv:

{{download_csv | safe}}

但是我希望此按钮{% extends "/public/templates/public_template.html" %} {% block title %}Simulador{% endblock%} {% block main %} <div class="container"> <div class="row"> <div class="col"> </br> <h1>Simulador</h1> <hr/> {{table| safe}} <br /> <a class="btn btn-primary" href="/" role="button">New simulation</a> <a class="btn btn-primary" href="/parameters" role="button">Edit Parameters</a> </div> </div> <div class="row"> <div class="col"> </br> <hr/> <h1>CSV File</h1> {{download_csv | safe}} </br></br> <a class="btn btn-primary" href="" role="button">Download CSV</a> <hr/> </div> </div> </div> {% endblock %} 触发在我的视图的<a class="btn btn-primary" href="" role="button">Download CSV</a>上创建的名为Simulation的数据框的CSV下载。py

我确实知道我需要在views.py上设置一条新路由来进行此下载,但是我该怎么做?

2 个答案:

答案 0 :(得分:0)

当前,您的按钮下载无效。

1-向其中添加OnClick=someFunction(),以便当用户单击它时someFunction()被执行。

<a class="btn btn-primary" onClick="someFunction()" href="" role="button">Download CSV</a>

2-在您的somFunction()中,将网页重定向到您想要的路线,例如说location.replace("/download");

function someFunction()
{
    //..... You can here send user input from HTML to Flask through Ajax POST request if you wish.........//
    location.replace("/download");

}

3-最后,在Flask中,确保您有一条/download路线来处理csv。

更新:如果您不想使用javascript函数重定向,请尝试以下操作:

1-将index()路由更改为更明显的内容,例如@app.route("/download")

2-将“下载CSV”按钮的href分配给函数的路由

<a class="btn btn-primary" href="{{ url_for('index') }}" role="button">Download CSV</a>

答案 1 :(得分:0)

我要做的是将模拟的创建转移到一个单独的函数create_simulation(),并为下载创建新的路由,如下所示:

from flask import render_template, make_response, Response
from flask import send_file
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import random
import seaborn as sns




@app.route("/jinja")
def jinja():

    my_name = "Testes"

    return render_template("/public/jinja.html", my_name=my_name)

@app.route("/about")
def about():
    return render_template("/public/about.html")

#defining parameters
bast_param = [0,5] #ba prefix for below average student
avst_param = [5,7] #av prefix for average student
aast_param = [7,10] #aa prefix for above average student

min_bast = bast_param[0]
max_bast = bast_param[1]
min_avst = avst_param[0]
max_avst = avst_param[1]
min_aast = aast_param[0]
max_aast = aast_param[1]


@app.route("/")
def index():
    simulation = create_simulation()
    return render_template('/public/index.html',table=simulation.to_html(),download_csv=simulation.to_csv(index=True, sep=";"))


@app.route('/download')
def download():
    # stream the response as the data is generated
    response = Response(create_simulation(), mimetype='text/csv')
    # add a filename
    response.headers.set("Content-Disposition", "attachment", filename="simulation.csv")
    return response


@app.route("/parameters")
def parameters():

    return render_template('/public/parameters.html', min_bast=min_bast, max_bast=max_bast, min_avst=min_avst,max_avst=max_avst, min_aast=min_aast, max_aast=max_aast)


def create_simulation():

    #students quantities per parameter
    bast_qtd = 5
    avst_qtd = 3
    aast_qtd = 8
    st_total = bast_qtd + avst_qtd + aast_qtd

    #Defining Subjects
    subjects = ["Disciplina 1", "Disciplina 2", "Disciplina 3", "Disciplina 4", "Disciplina 5"]

    students = []

    #counter for students ids creation
    i = 0

    #counters and variable for grades creation
    a = 0
    b = 0
    newgradeline = []

    grade = []

    #creating students and grades
    while(i < st_total):
        newstudent = random.randint(100000,199999)
        #excluding duplicates
        if newstudent not in students:
            students.append(newstudent)
            i = i+1


    # In[3]:


    #below averagge students
    while (a < bast_qtd):
        b = 0
        newgradeline = []
        grade.append(newgradeline)
        while (b<len(subjects)):
            gen_grade = round(random.uniform(bast_param[0],bast_param[1]),2)
            newgradeline.append(gen_grade)
            b = b+1
        a = a +1
    a = 0

    #average students
    while (a < avst_qtd):
        b = 0
        newgradeline = []
        grade.append(newgradeline)
        while (b<len(subjects)):
            gen_grade = round(random.uniform(avst_param[0],avst_param[1]),2)
            newgradeline.append(gen_grade)
            b = b+1
        a = a +1
    a = 0

    #above average students
    while (a < aast_qtd):
        b = 0
        newgradeline = []
        grade.append(newgradeline)
        while (b<len(subjects)):
            gen_grade = round(random.uniform(aast_param[0],aast_param[1]),2)
            newgradeline.append(gen_grade)
            b = b+1
        a = a +1


    # In[4]:
    #generating table
    simulation = pd.DataFrame (grade,index=students, columns=subjects)
    return simulation

然后您的html应该看起来像这样,我只将href更改为“ / download”:

{% extends "/public/templates/public_template.html" %}

{% block  title %}Simulador{% endblock%}

{% block main %}
  <div class="container">
    <div class="row">
      <div class="col">
      </br>
        <h1>Simulador</h1>
      <hr/>
        {{table| safe}}
        <br />
      <a class="btn btn-primary" href="/" role="button">New simulation</a>
      <a class="btn btn-primary" href="/parameters" role="button">Edit Parameters</a>
      </div>
    </div>
    <div class="row">
      <div class="col">
      </br>
      <hr/>
        <h1>CSV File</h1>
        {{download_csv | safe}}
      </br></br>
        <a class="btn btn-primary" href="/download" role="button">Download CSV</a>
        <hr/>
    </div>
    </div>
  </div>

{% endblock %}

我基本上遵循以下示例:Create and download a CSV file from a Flask view