如何在 Dash 中上传多个数据集并输出每个数据帧的表格?

问题描述 投票:0回答:1

我有一个简单的破折号应用程序,用户可以在其中上传数据集,应用程序会在表格中输出数据集。

我希望用户能够上传多个数据集并显示每个数据集的表格。

例如,如果用户要上传三个不同的数据集,则 dash 应用程序将显示要上传的第一个数据集的表格,然后是要上传的第二个数据集的表格,然后是第三个数据集的表格待上传。

我该怎么做?这是我当前的代码:

import base64
import datetime
import io
import plotly.graph_objs as go
import plotly.express as px
import dash
from dash.dependencies import Input, Output, State
from dash import dcc, html, dash_table
import numpy as np
import pandas as pd

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

colors = {"graphBackground": "#F5F5F5", "background": "#ffffff", "text": "#000000"}

app.layout = html.Div(
    [
        dcc.Upload(
            id="upload-data",
            children=html.Div(["Drag and Drop or ", html.A("Select Files")]),
            multiple=True,
        ),
        html.Div(id="output-data-upload"),
    ]
)

def parse_data(contents, filename):
    content_type, content_string = contents.split(",")

    decoded = base64.b64decode(content_string)
    try:
        if "csv" in filename:
            # Assume that the user uploaded a CSV or TXT file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")))
        elif "xls" in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded))
        elif "txt" or "tsv" in filename:
            # Assume that the user upl, delimiter = r'\s+'oaded an excel file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")), delimiter=r"\s+")
    except Exception as e:
        print(e)
        return html.Div(["There was an error processing this file."])

    return df

@app.callback(
    Output("output-data-upload", "children"),
    [Input("upload-data", "contents"), Input("upload-data", "filename")],
)
def update_table(contents, filename):
    table = html.Div()

    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)

        table = html.Div(
            [
                html.H5(filename),
                dash_table.DataTable(
                    data=df.to_dict("rows"),
                    columns=[{"name": i, "id": i} for i in df.columns],
                ),
                html.Hr(),
                html.Div("Raw Content"),
                html.Pre(
                    contents[0:200] + "...",
                    style={"whiteSpace": "pre-wrap", "wordBreak": "break-all"},
                ),
            ]
        )

    return table


if __name__ == "__main__":
    app.run_server(debug=True)
python plotly-dash
1个回答
0
投票

update_table
回调中,您需要将新创建的表 append 到输出 div 中 children
list
,而不是返回新表(这只会重置仅包含该表的列表) .

从 Dash 2.9 开始,我们可以使用 Patch 类进行

部分属性更新

@app.callback(
    Output("output-data-upload", "children"),
    [Input("upload-data", "contents"), Input("upload-data", "filename")],
)
def update_table(contents, filename):
    patched_children = Patch()

    if contents:
        contents = contents[0]
        filename = filename[0]
        df = parse_data(contents, filename)

        table = html.Div(
            [
                html.H5(filename),
                dash_table.DataTable(
                    data=df.to_dict("records"),
                    columns=[{"name": i, "id": i} for i in df.columns],
                ),
                html.Hr(),
                html.Div("Raw Content"),
                html.Pre(
                    contents[0:200] + "...",
                    style={"whiteSpace": "pre-wrap", "wordBreak": "break-all"},
                ),
            ]
        )

        patched_children.append(table)

    return patched_children

另请注意,

data=df.to_dict("rows")
无效(
orient='rows'
不存在),您可能指的是
data=df.to_dict("records")

© www.soinside.com 2019 - 2024. All rights reserved.