You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:10:30