W
e
l
c
o
m
e
: )

Finereport调用python服务进行大数据量导出

Aerial view of woman using a computer laptop on a marble table

背景:

在使用finereport过程中,我们发现在数据导出这块一直是一个瓶颈,闲来无事,思索一番,想出来一种场景来应对此问题。供各位大佬参考讨论,也欢迎其他大佬提供更好的解决方案。

正文:

首先,我们需要使用python启一个flask服务,来供传递参数,sql等。

本次举例写的固定sql,后续大家可以自行优化扩展。

1.启动flask服务

from flask import Flask, request, jsonify, send_file
import pymysql
import pandas as pd
import threading
import os
import time

app = 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=[i[0] 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=['GET'])
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文件失败'}), 500

if __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.示例操作

img

不知道怎么上传视频,大家自己尝试吧

目前仅为思路的验证,代码健壮性目前比较差,见谅。

posted @ 2024-12-19 16:40  水一RAR  阅读(66)  评论(0编辑  收藏  举报