Flask 结合 pandas.DataFrame 输出文件(excel/csv)

Flask 是使用 Python 编写的一个轻量级web框架,使用 Flask 可以快速的搭建起一个网站,轻量级体现在框架提供了基础的应用框架(定义app、templates、Field等),其余目的的可以使用外部包达成。
pandas 是基于 Numpy 的一种工具,该工具是为了解决数据分析而创建的,在 Numpy 的快速计算基础上增加了行和列名,可以读取文件、数据库数据并进行交互,pandas.DataFrame 是 pandas 中的一种表型数据结构。
本文就是使用功能 pandas.DataFrame 将数据流以表格的形式返回到客户端。

一、建立应用

使用 flask 创建应用,并创建相应文件

│	├── flask                            // 源码目录
│   ├── templates                          // 模板
│   │   ├── index.html                        // 首页页面
│   │   ├── extraction.html                   // 提取页面
│   ├── app.py                             // 应用
│   ├── textraction.py                     // 提取应用

1.app.py 代码

from flask import Flask, render_template
import os
from extraction import Submit, GetData


app = Flask(__name__)
SECRET_KEY = os.urandom(32)
app.config['SECRET_KEY'] = SECRET_KEY


@app.route('/')
def index():
	# 首页
    return render_template('index.html')


@app.route('/extraction/', methods=['GET', 'POST'])
def extraction():
	# 提取页面
    form = Submit()
    if form.validate_on_submit():
        return GetData()()
    return render_template('extraction.html', form=form)


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=80)

首先是注册app,然后定义首页url和提取页面url以及对应逻辑。其中extraction页面中要是用 GET 和 POST 两种方法,因为 GET 方法返回页面,POST 方法返回数据

2.index.html 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
这是首页
<hr />
{% block body %}
<a class="extraction" href="/extraction/"> 数据提取演示 </a>
{% endblock %}
</body>
</html>

定义页面内容,这里没有太多东西,就是简单说明这是首页,并且提供一个链接指向提取页面,而且是用 {% block body %} 将这部分变成一个块,可以在以后继续使用这个模板。

3. extraction.html 代码

{% extends "index.html" %}
{% block body %}
<form action="" method="post" novalidate>
    {{ form.hidden_tag() }}
    <p>{{ form.submit() }}</p>
</form>
{% endblock %}

使用 {% extends “index.html” %} 直接继承模板,直接重写body块的内容,形成一个表单。

二、使用 pandas.DataFrame 制造数据

import pandas as pd
data = pd.DataFrame(['Geeks', 'For', 'Geeks', 'is', 'portal', 'for', 'Geeks'])

三、使用 make_response 将数据流返回客户端

Flask 官方提供了 make_response 将数据封装成 response 类以供开发者使用。具体介绍可以搜索点击链接apimake_response查看。
方法很简单,直接将数据封装成 response 然后返回

response = make_response(value)
return response

四、将 pandas.DataFrame 的数据流写入response并返回

返回页面的数据不能直接使用 pandas.DataFrame, 因为这只是一个数据结构,所以需要将 pandas.DataFrame 转化为数据流,然后以需要的形式发送至客户端。
这里的数据流实现方式就是使用 IO 模块将数据写入内存,最后再“读取”到 make_response 中。

out = io.BytesIO()
writer = pd.ExcelWriter(out, engine='xlsxwriter')
data.to_excel(excel_writer=writer, index=False, sheet_name='示例')
writer.save()
writer.close()

这样数据流就在 out 对象中了,然后就可以结合 make_response 制造 response 对象。
下面直接贴成型代码:

from flask_wtf import FlaskForm
import pandas as pd
import io
from flask import make_response
from wtforms import SubmitField
import time


class GetData:
    def __init__(self):
        self.data = pd.DataFrame(['Geeks', 'For', 'Geeks', 'is', 'portal', 'for', 'Geeks'])

    def __call__(self):
        df = self.data
        out = io.BytesIO()
        writer = pd.ExcelWriter(out, engine='xlsxwriter')
        df.to_excel(excel_writer=writer, index=False, sheet_name='示例')
        writer.save()
        writer.close()
        file_name = time.strftime('%Y%m%d', time.localtime(time.time())) + '.xlsx'
        response = make_response(out.getvalue())
        response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name
        response.headers["Content-type"] = "application/x-xls"
        """ 如果输出的是 csv 文件
        df = self.data
        out = io.StringIO()
        df.to_csv(out, index=False)
        file_name = time.strftime('%Y%m%d', time.localtime(time.time())) + '.csv'
        response = make_response(out.getvalue())
        response.headers["Content-Disposition"] = "attachment; filename=%s" %file_name
        response.headers["Content-type"] = "text/csv"
        """
        return response


class Submit(FlaskForm):
    submit = SubmitField('提取数据')

注释部分还提供了 csv 文件的处理方法,不同的地方在数据写入方式 df.to_csv 和 response.headers 的 Content-type 部分(可以参照HTTP Content-type 对照表

五、扩展

一般输出的会是有多个数据表,但是数据流只有一份,所以如果想要同时输出多份数据只能将数据写入一个文件或将多个文件打包成压缩文件,总之最后返回的只能是一个数据。比如上面的例子可以

df.to_excel(excel_writer=writer, index=False, sheet_name='示例')
df.to_excel(excel_writer=writer, index=False, sheet_name='示例1')

这样在 excel 文件中就会包含两个sheet “示例” 和“示例1”。

所有文件可以下载

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值