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

Dash Plotly点击按钮无法下载处理后Excel文件的问题求助

解决Dash应用无法下载处理后Excel文件的问题

你的代码目前缺少下载功能的核心逻辑:没有存储处理后的DataFrame,也没有针对下载按钮的回调来生成并返回Excel文件。以下是具体修改方案:

关键修改点

  • 添加dcc.Store组件持久化存储处理后的DataFrame(Dash是无状态框架,需要临时存储数据供后续回调调用)
  • 新增下载按钮的回调函数,将存储的DataFrame转换为Excel字节流返回给用户
  • 修复重复初始化Dash应用的冗余代码

修改后的完整代码

import base64
import io
import dash
from dash.dependencies import Input, Output, State
from dash import dcc, html
import plotly.express as px
import pandas as pd

# 修复重复初始化问题
app = dash.Dash(prevent_initial_callbacks=True)

app.layout = html.Div([
    html.H1('Convertion of FMS logdata to parced data'),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'Drag and Drop or ',
            html.B('Select Files')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        },
        multiple=True
    ),
    # 添加Store组件存储处理后的DataFrame(以JSON格式保存)
    dcc.Store(id='processed-data', data={}),
    html.Div(id='output-data-upload'),
    html.Div([
        html.Button("Download xlsx", id="btn"),
        dcc.Download(id="download")
    ])
])

def parse_contents(contents, filename):
    content_type, content_string = contents.split(',')
    decoded = base64.b64decode(content_string)
    df2 = pd.read_excel(io.BytesIO(decoded), skiprows=8, usecols=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11])
    # 返回图表组件和处理后的DataFrame的JSON格式
    return html.Div([
        html.P(f'File: {filename} - Analog Input2 with Respect to Timestamp'),
        dcc.Graph(figure=px.scatter(df2, x="Speed", y="Longitude"))
    ]), df2.to_json(date_format='iso', orient='split')

@app.callback(
    [Output('output-data-upload', 'children'),
     Output('processed-data', 'data')],
    Input('upload-data', 'contents'),
    State('upload-data', 'filename'),
    State('upload-data', 'last_modified')
)
def update_output(list_of_contents, list_of_names, list_of_dates):
    if list_of_contents is not None:
        children = []
        processed_data = {}
        for c, n, d in zip(list_of_contents, list_of_names, list_of_dates):
            component, df_json = parse_contents(c, n)
            children.append(component)
            processed_data[n] = df_json
        return children, processed_data
    return [], {}

@app.callback(
    Output("download", "data"),
    Input("btn", "n_clicks"),
    State("processed-data", "data"),
    prevent_initial_call=True
)
def download_excel(n_clicks, processed_data):
    if not processed_data:
        return dash.no_update
    
    # 创建Excel文件,每个上传的文件对应一个sheet
    output = io.BytesIO()
    with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
        for filename, df_json in processed_data.items():
            df = pd.read_json(df_json, orient='split')
            # 去掉文件名的后缀作为sheet名
            sheet_name = filename.rsplit('.', 1)[0]
            df.to_excel(writer, sheet_name=sheet_name, index=False)
    output.seek(0)
    
    # 返回下载的Excel文件
    return dcc.send_bytes(output.getvalue(), "processed_data.xlsx")

if __name__ == '__main__':
    app.run_server(debug=True)

代码说明

  1. dcc.Store组件:将每个上传文件处理后的DataFrame以JSON格式存储,供下载回调读取
  2. 下载回调函数:
    • 从Store中读取所有处理后的DataFrame
    • 使用pd.ExcelWriter将多个DataFrame写入同一个Excel文件的不同sheet(如果上传多个文件)
    • 通过dcc.send_bytes返回Excel字节流,触发浏览器下载
  3. 修复冗余代码:移除了重复的app = dash.Dash()初始化语句

内容的提问来源于stack exchange,提问作者aparna podili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:51:07