如何在Flask中完成文件上传后发送成功提示并保留变量?
解决方案
要解决上传后显示成功提示、保留DataFrame变量的问题,需要针对Flask后端和HTML模板做两处核心修改,同时处理HTTP无状态特性带来的变量持久化问题:
一、修改Flask后端代码
Flask的flash提示依赖Session机制,必须先设置secret_key;上传成功后触发提示,同时将DataFrame序列化后存入Session(或服务器端存储)以保留数据:
import requests import pandas as pd import pickle from flask import request, Flask, render_template, flash, session app = Flask(__name__) # 必须设置secret_key才能使用flash和Session,生产环境请用随机复杂字符串 app.secret_key = 'your-custom-secret-key' @app.route('/') def main(): return render_template("index.html") @app.route('/', methods=['POST']) def upload(): if request.method == 'POST': # 读取上传的Excel文件 dataframe_1 = pd.read_excel(request.files.get('file_1')) dataframe_2 = pd.read_excel(request.files.get('file_2')) # 触发上传成功提示 flash('文件上传完成!已加载两个Excel数据表', 'success') # 将DataFrame序列化后存入Session(注意:pickle序列化存在安全风险,生产环境建议用Redis等专业存储) session['dataframe_1'] = pickle.dumps(dataframe_1) session['dataframe_2'] = pickle.dumps(dataframe_2) return render_template("index.html") if __name__ == '__main__': app.run(debug=True)
二、修改HTML模板
在模板中添加Flash消息展示区域,让用户能直观看到上传成功提示:
<!-- 新增:在表单前后合适位置添加提示展示区 --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}"> {{ message }} </div> {% endfor %} {% endif %} {% endwith %} <form method="POST" action="/" enctype="multipart/form-data" class="form-horizontal" id="form"> <div class="row form-group"> <div class="col-12 col-md-12"> <div class="control-group" id="fields"> <label class="control-label" for="formFile"> Chis Ativo </label> <label class="control-label2" for="formFile2"> Gis Mensal </label> <div class="controls"> <div class="entry input-group upload-input-group"> <input class="form-control" name="file_1" type="file" id="formFile" accept="xlsx" required> <input class="form-control" name="file_2" type="file" id="formFile2" accept="xlsx" required> </div> </div> <button class="btn btn-primary" type="submit" value="Submit">Upload</button> </div> </div> </div> </form>
三、关于DataFrame持久化的补充说明
Session存储限制:用pickle将DataFrame存在Session中仅适合小体积Excel文件(Session默认存在客户端Cookie,有大小限制)。若处理大文件,建议改用服务器端存储:
- 开发环境可临时用全局字典:
# 在app初始化后定义 uploaded_data = {} # 上传时用Session ID作为键存储数据 session_id = request.cookies.get('session') uploaded_data[session_id] = (dataframe_1, dataframe_2) - 生产环境推荐用Redis等键值数据库存储序列化后的DataFrame。
- 开发环境可临时用全局字典:
安全提示:pickle序列化存在反序列化风险,生产环境请勿处理不可信来源的文件上传,或改用更安全的序列化方式(如将DataFrame转为JSON字符串,但会丢失部分复杂数据类型)。
四、后续VLOOKUP功能示例
若要实现类似Excel的VLOOKUP逻辑,可在需要的路由中读取存储的DataFrame进行合并操作:
# 示例:新增路由处理VLOOKUP逻辑 @app.route('/vlookup', methods=['GET']) def vlookup(): if 'dataframe_1' in session and 'dataframe_2' in session: df1 = pickle.loads(session['dataframe_1']) df2 = pickle.loads(session['dataframe_2']) # 假设以'匹配列'作为关联键,实现左连接(对应VLOOKUP的近似匹配逻辑) result_df = pd.merge(df1, df2, on='匹配列', how='left') # 可将结果传给模板展示,或生成下载链接 return render_template('result.html', result=result_df.to_html()) return '请先上传文件'
内容的提问来源于stack exchange,提问作者Roberto
相关产品推荐
相关产品推荐

