背景介绍
标题有点绕…不过确实是这么回事:
Flask里面用Alchemy进行ORM数据映射后指定条件查询用户表>扔给Pandas实例化DataFrame对象>调用DataFrame的to_excel()方法将转换的xlsx文件数据存放在内存中的一个BytesIO对象中>再生成response响应返回给浏览器
好吧,我觉得时间长了我怕自己都记不清当时是在干什么了,不嫌啰嗦~
具体步骤:
实例化一个io.BytesIO对象传给pandas.ExcelWriter用,实现将df.to_excel()方法输出的xlsx数据到内存中,然后再使用Flask的make_response生成一个response响应,并设置headers让浏览器解析为文件下载.
下面代码例子是在蓝图中实现的,其中users为Flask-SQLAlchemy部分进行的ORM映射取的查询.
import io
import pandas as pd
from flask import Blueprint, render_template, request, jsonify, make_response
from pandas import ExcelWriter
bp = Blueprint('admin', __name__, url_prefix='/admin')
@bp.route('/exportUser')
def export_user():
"""
导出用户数据表为可下载的excel文件
Returns:
"""
# SQLAlchemy中的模型查询
users = User.query.filter(User.role == 1)
# 实例化字节类型IO对象,用来在内存中存储对象,不用在磁盘上生成临时文件了
out = io.BytesIO()
# 实例化输出xlsx的writer对象
writer = ExcelWriter(out, engine='openpyxl')
# 将SQLAlchemy模型的查询对象拆分SQL语句和连接属性传给pandas的read_sql方法
df = pd.read_sql(users.statement, users.session.bind)
# 简单数据切片,选择所有行,第六列到最后一列范围
df = df.iloc[:, 5:]
# 对df列名重命名
df.rename(columns={
'xm': '姓名',
'sfzh': '身份证号',
'csny': '出生年月',
'xb': '性别',
'bm': '部门',
'zw': '职务',
'jb': '级别',
'vcode': '校验码'
}, inplace=True)
# 将df转excel保存在内存writer变量中,转换结果中不要包含index行号
df.to_excel(writer, index=False)
# 这一步不能漏了,不save的话浏览器下载的xls文件里面啥也没有
writer.save()
# 重置一下IO对象的指针到开头
out.seek(0)
# IO对象使用getvalue()可以返回二进制的原始数据,用来给要生成的response的data
resp = make_response(out.getvalue())
# 设置response的header,让浏览器解析为文件下载行为
resp.headers['Content-Disposition'] = 'attachement; filename=users.xlsx'
resp.headers['Content-Type'] = 'application/vnd.ms-excel; charset=utf-8'
return resp
模板HTML中可以直接用<a href="/admin/exportUser">下载</a>点击浏览器就会弹出保存文件的效果.