我有一个简单的破折号应用程序,用户可以在其中上传数据集,应用程序会在表格中输出数据集。
我希望用户能够上传多个数据集并显示每个数据集的表格。
例如,如果用户要上传三个不同的数据集,则 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)
在
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")
。