前言
为了解决总是人为导出Excel这种繁琐而又重复性的工作,因此应用Flask+xlsxwriter开发了一个接口,直接请求导出excel就OK了,所以分享下这个过程碰到的问题。
环境
操作系统:mac
语言: Python3
web服务:uWSGI
生成Excel
业务逻辑就不再这里讲述了,以及xlswriter的应用可以详见官方文档
首先创建一个excel.py作为导出excel的逻辑层,先来看下生成excel的代码
#模块不存在的话,pip install 下
import numpy as np
import pandas as pd
from io import BytesIO
class Excel:
def export(self):
#创建数据流
output = BytesIO()
#创建excel work book
writer = pd.ExcelWriter(output, engine='xlsxwriter')
workbook = writer.book
#创建excel sheet
worksheet= workbook.add_worksheet('sheet1')
#cell 样式
cell_format = workbook.add_format({
'bold': 1,
'border': 1,
'align': 'center',
'valign': 'vcenter',
'fg_color': '#f4cccc'})
col=0
row=1
#写入列名
columns=['A','B','C','D','E']
for item in columns:
worksheet.write(0, col,item,cell_format)
col+=1
#写入数据
index=0
while index<10:
for co in columns:
worksheet.write(row,columns.index(co),index)
row+=1
index+=1
print('row===%s,index===%s'%(row,index))
#设置A-E的宽
worksheet.set_column('A:E', 20)
writer.close()
output.seek(0)
return output
这样呢,写入excel的数据就有了,然后先忙让我们来看下通过访问http://localhost:5001/index 如何导出一个excel文件
Flask Send_file
这时候得应用flask的send_file方法,新建app.py文件。代码如下:
from flask import Flask, send_file
from excel import Excel
app = Flask(__name__)
@app.route('/index')
def index():
#获取字节流
output=Excel().export()
return send_file(output,attachment_filename="testing.xlsx",
as_attachment=True)
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=5001)
启动执行命令
python app.py
这是时候请求一些http://localhost:5001/index
这个样就生成了一个testing.xlsx,打开看下结果:
这样就可以导出excel.
神奇在哪里
很简单对吧,也没有什么高深的东东。测试服务器、开发环境都没有问题,可是偏偏到线上就出了问题,神奇问题在哪里呢?经过排除是可能是因为uWSGI的原因。然后再本地搭建了uWSGI后,发现也可以正常导出,其中uwsgi.ini配置文件内容如下:
[uwsgi]
virtualenv =/home/ubuntu/virtualenv/tianfu3k
http-socket = 0.0.0.0:5001
wsgi-file = main.py
callable = app
processes = 4
threads = 5
wsgi-disable-file-wrapper = true
lazy-apps = true
跟线上的配置还是有很多差距的,线上的这个问题依然再追踪中
终极解决方案
名字很犀利,但是写法却很简单,无非就是应用flask的make_response,然后看下代码:
from flask import Flask, send_file,make_response
from excel import Excel
app = Flask(__name__)
@app.route('/index')
def index():
return 'Hello World'
@app.route('/export')
def export():
output=Excel().export()
return send_file(output,attachment_filename="testing.xlsx",
as_attachment=True)
@app.route('/new_export')
def new_export():
output=Excel().export()
resp = make_response(output.getvalue())
resp.headers["Content-Disposition"] ="attachment; filename=testing.xlsx"
resp.headers['Content-Type'] = 'application/x-xlsx'
return resp
if __name__ == '__main__':
app.run(debug=True)
测试: http://localhost:5001/new_export 则正常导出