FineReport调用python服务进行大数据量导出
Finereport调用python服务进行大数据量导出
背景:
在使用finereport过程中,我们发现在数据导出这块一直是一个瓶颈,闲来无事,思索一番,想出来一种场景来应对此问题。供各位大佬参考讨论,也欢迎其他大佬提供更好的解决方案。
文笔较差,大佬见谅。
废话不多说,直接上代码,案例。
正文:
首先,我们需要使用python启一个flask服务,来供传递参数,sql等。
本次举例写的固定sql,后续大家可以自行优化扩展。
1.启动flask服务
from flask import Flask, request, jsonify, send_fileimport pymysqlimport pandas as pdimport threadingimport osimport timeapp = Flask(__name__)# 数据库连接配置db_config = { 'host': 'ip', 'user': '用户', 'password': '密码', 'database': '数据库'}# 数据库连接def connect_db(): return pymysql.connect(**db_config)# 导出到CSV函数def export_to_csv(sql, params, output_file): connection = connect_db() try: # 执行查询并使用参数化查询 with connection.cursor() as cursor: cursor.execute(sql, params) # 使用参数化查询 result = cursor.fetchall() # 如果没有结果,返回None if not result: return None # 将查询结果转换为DataFrame并写入CSV df = pd.DataFrame(result, columns= for i in cursor.description]) df.to_csv(output_file, index=False, encoding='utf-8') print(f"CSV文件已生成: {output_file}") return output_file finally: connection.close()# 后台线程处理文件导出def generate_csv(sql, params, output_file): export_to_csv(sql, params, output_file)# 这里为了验证场景使用的get请求,实际大多数情况下都需要传递参数,推荐post请求。@app.route('/run_report', methods=)def run_report(): params = request.args.getlist('params') # 获取URL查询参数 sql = "SELECT * FROM test_table" # 默认的SQL查询 # 生成唯一的输出文件名(可以用时间戳或UUID) output_file = f'output_{int(time.time())}.csv' # 启动后台线程生成CSV文件 thread = threading.Thread(target=generate_csv, args=(sql, params, output_file)) thread.start() # 等待线程完成,确保文件生成后直接返回文件 thread.join() # 确保线程完成后返回 # 如果文件生成成功,直接返回文件 if os.path.exists(output_file): return send_file(output_file, as_attachment=True, mimetype='text/csv') else: return jsonify({'error': '生成CSV文件失败'}), 500if __name__ == '__main__': app.run(debug=True)
2.创建模板:
在按钮点击事件上绑定服务地址即可。
提示这块目前做的比较粗糙,大家可以自行优化。
window.location.href="http://127.0.0.1:5000/run_report"FR.Msg.alert("提示","数据正在下载请稍后");
3.示例模板
后台导出.rar (1.99 K)
4.示例操作
不知道怎么上传视频,大家自己尝试吧
第一次写技术文章,写的不咋好,大家见谅,感谢。顺便吐槽一句,这个发帖写作的好难使用啊。
目前仅为思路的验证,代码健壮性目前比较差,见谅。