Flask文件上传问题:路径查询、文件调用及前后端代码关联
Flask文件上传全流程解决方案:从表单关联到CSV图表生成
核心问题修正与实现说明
1. 解决无上传入口、表单关联问题
原代码GET请求未返回页面内容,且配置项大小写不统一导致路径失效。以下是修正后的完整实现,整合Flask后端与HTML表单,确保二者正常对接:
2. 文件存储位置与调用逻辑
- 上传文件夹默认设为当前项目根目录下的
uploads,自动创建无需手动操作 - 原始文件与转换后的CSV文件均存储在此目录,操作结果会通过提示消息显示具体路径
3. 上传转CSV+生成图表实现
通过pandas处理文件格式转换,使用plotly生成可视化图表并直接嵌入页面展示
完整可运行代码
from flask import Flask, flash, request, redirect, url_for, render_template_string from werkzeug.utils import secure_filename import os import pandas as pd import plotly.graph_objects as go from plotly.io import to_html # 配置上传文件夹:当前项目目录下的uploads文件夹(自动适配跨平台路径) upload_folder = os.path.join(os.getcwd(), 'uploads') # 允许的文件格式:添加Excel/CSV以支持表格处理 allowed_extensions = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'xlsx', 'xls', 'csv'} app = Flask(__name__) app.secret_key = 'supersecretkey' # 用于flash消息加密 app.config['UPLOAD_FOLDER'] = upload_folder # 统一配置项大小写 # 自动创建上传文件夹(不存在时创建) os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in allowed_extensions @app.route('/', methods=['GET', 'POST']) def upload_file(): chart_html = None if request.method == 'POST': # 检查请求是否包含文件部分 if 'file' not in request.files: flash('未找到文件部分') return redirect(request.url) file = request.files['file'] # 处理用户未选择文件的情况 if file.filename == '': flash('未选择文件') return redirect(request.url) if file and allowed_file(file.filename): filename = secure_filename(file.filename) # 原始文件存储路径 file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) # 转换为CSV格式 try: # 根据文件类型读取数据 ext = filename.rsplit('.', 1)[1].lower() if ext in ['xlsx', 'xls']: df = pd.read_excel(file_path) else: df = pd.read_csv(file_path) # 生成CSV文件并保存 csv_filename = f"{filename.rsplit('.', 1)[0]}.csv" csv_path = os.path.join(app.config['UPLOAD_FOLDER'], csv_filename) df.to_csv(csv_path, index=False) flash(f"文件已转换为CSV,存储路径:{csv_path}") # 生成可视化图表(示例为柱状图,使用前两列数据) if len(df.columns) >= 2: fig = go.Figure(data=[go.Bar(x=df.iloc[:,0], y=df.iloc[:,1])]) fig.update_layout(title='上传数据可视化图表', xaxis_title=df.columns[0], yaxis_title=df.columns[1]) chart_html = to_html(fig, full_html=False) except Exception as e: flash(f"文件处理出错:{str(e)}") return render_template_string(html_template, chart_html=chart_html) # GET请求返回上传表单页面 return render_template_string(html_template, chart_html=chart_html) # 内置HTML模板(整合表单、消息提示与图表展示) html_template = '''<!DOCTYPE html> <html> <head> <meta charset='utf-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <title>文件上传工具</title> <meta name='viewport' content='width=device-width, initial-scale=1'> <style> .container { max-width: 800px; margin: 20px auto; padding: 0 20px; } .flash { padding: 10px; margin: 10px 0; border-radius: 4px; background-color: #f8d7da; color: #721c24; } .chart-container { margin-top: 30px; } </style> </head> <body> <div class="container"> <div class="Headers"> <h1> 上传文件 </h1> </div> <!-- 操作提示消息 --> {% with messages = get_flashed_messages() %} {% if messages %} {% for message in messages %} <div class="flash">{{ message }}</div> {% endfor %} {% endif %} {% endwith %} <div> <form method="POST" action="" enctype="multipart/form-data"> <p><input type="file" name="file"></p> <p><input type="submit" value="提交"></p> </form> </div> <!-- 图表展示区域 --> {% if chart_html %} <div class="chart-container"> {{ chart_html|safe }} </div> {% endif %} </div> </body> </html>''' if __name__ == '__main__': app.run(debug=True)
关键注意事项
- 启动项目后访问
http://127.0.0.1:5000即可看到上传入口 - 表单的
name="file"必须与Flask代码中request.files['file']的键名完全一致 - 若需自定义图表类型,修改plotly的图表生成逻辑即可
内容的提问来源于stack exchange,提问作者Armin Alborzi
相关产品推荐
相关产品推荐

