如何将 json 从 dash dcc.Store 保存到 excel 文件?

Posted

技术标签:

【中文标题】如何将 json 从 dash dcc.Store 保存到 excel 文件?【英文标题】:How to save json from dash dcc.Store to excel file? 【发布时间】:2022-01-01 03:47:32 【问题描述】:

我正在尝试将用户输入存储在 dcc.store 中,然后使用 store 中的数据保存在 excel 文件中,但是将数据保存到 excel 的回调不起作用。我这样做是因为我也想在计算中使用用户输入,所以我没有保存并再次读取它,而是将用户输入保存在 dcc.store 中并执行我的计算,但也想将其保存在 excel 中以供将来使用. 我的应用程序有 3 个选项卡,在第一个选项卡中,我正在接受用户输入并尝试保存输入。 任何人都可以在这里帮忙,下面是代码。

` dash_app = 此处的工作代码

    tabs = dcc.Tabs(
        id="dummy-tabs",
        value="tab1",
        children=[
            dcc.Tab(label="Pricing Inputs", value="tab1"),
            dcc.Tab(label="Tab 2", value="tab2"),
            dcc.Tab(label="Tab 3", value="tab3"),
        ],
    )

    layout = html.Div(
        children=[
            dcc.Store(id="dummy-input-store"),
            tabs,
            html.Div(id="tabs-content"),
        ]
    )
    

    @dash_app.callback(Output("tabs-content", "children"), Input("dummy-tabs", "value"))
    def tab_content_display(tab):
        options2 = ["A","B","C"]
        tab1_content = html.Div(
            [
                html.Label(
                    "Input1",
                    htmlFor="input1",
                    style="margin-right": "2em",
                ),
                dcc.Input(
                    id="input1",
                    type="text",
                    placeholder="input type text",
                    style=
                        "width": "40%",
                        "display": "inline-block",
                        "verticalAlign": "middle",
                    ,
                ),
                html.Br(),
                html.Label(
                    "Input2",
                    htmlFor="input2",
                    style="margin-right": "2em",
                ),
                dcc.Dropdown(
                    id="input2",
                    options=["label": i, "value": i for i in options2],
                    style=
                        "width": "40%",
                        "display": "inline-block",
                        "verticalAlign": "middle",
                    ,
                ),
                html.Br(),
                html.Div(
                    [
                        html.Button(
                            id="reset-button",
                            n_clicks=0,
                            children="Reset",
                            style=
                                "fontWeight": "bold",
                                "textAlign": "center",
                                "marginRight": 25,
                            ,
                            title="Click to clear the inputs",
                        ),
                        html.Button(
                            id="submit-button",
                            n_clicks=0,
                            children="Submit",
                            style=
                                "fontWeight": "bold",
                                "textAlign": "center",
                                "marginRight": 25,
                            ,
                            title="Click to save inputs",
                        ),
                    ]
                ),
                html.Div(id="msg"),
            ]
        )

        tab2_content = html.Div([html.P("This is tab 2!")])
        tab3_content = html.Div([html.P("This is tab 3!")])
        if tab == "tab1":
            return tab1_content
        elif tab == "tab2":
            return tab2_content
        elif tab == "tab3":
            return tab3_content

    @dash_app.callback(
        Output("dummy-input-store", "data"),
        Input("input1", "value"),
        Input("input2", "value"),
    )
    def store_output_tab1(
        input1,
        input2,
    ):
        return json.dumps(
            
                "Input1": input1,
                "Input2": input2,
            
        )

    @dash_app.callback(
        Output("dummy-input-store", "clear_data"), Input("reset-button", "n_clicks")
    )
    def reset_click_tab1(n_click_clear):
        if n_click_clear is not None and n_click_clear > 0:
            return True
        return False

    @dash_app.callback(
        Output("msg", "children"),
        Input("submit-button", "n_clicks"),
        State("dummy-input-store", "data"),
    )
    def print_msg_tab1(n_clicks, data):
        if n_clicks is not None and n_clicks > 0:
            dummy_inputs = pd.DataFrame.from_dict(data, orient="index")
            filepath = r"C:\input_data.xlsx"
            with pd.ExcelWriter(filepath, mode = 'a') as writer:
                dummy_inputs.to_excel(writer,sheet_name = "Dummy_Inputs")
            return html.Div([html.H6(f"Inputs Saved:data")])
        raise PreventUpdate
`

【问题讨论】:

【参考方案1】:

你去吧,虽然 xlsxwriter 中的 mode='a' 可能不是你想要的......我不知道。

import dash
from dash import html, dcc, Input, Output, State
from dash.exceptions import PreventUpdate
import json
import pandas as pd

dash_app = dash.Dash(__name__)
dash_app.config.suppress_callback_exceptions = True

tabs = dcc.Tabs(
    id="dummy-tabs",
    value="tab1",
    children=[
        dcc.Tab(label="Pricing Inputs", value="tab1"),
        dcc.Tab(label="Tab 2", value="tab2"),
        dcc.Tab(label="Tab 3", value="tab3"),
    ],
)

layout = html.Div(
    children=[
        dcc.Store(id="dummy-input-store"),
        tabs,
        html.Div(id="tabs-content"),
    ]
)

dash_app.layout = layout

@dash_app.callback(Output("tabs-content", "children"), Input("dummy-tabs", "value"))
def tab_content_display(tab):
    options2 = ["A","B","C"]
    tab1_content = html.Div(
        [
            html.Label(
                "Input1",
                htmlFor="input1",
                style="margin-right": "2em",
            ),
            dcc.Input(
                id="input1",
                type="text",
                placeholder="input type text",
                style=
                    "width": "40%",
                    "display": "inline-block",
                    "verticalAlign": "middle",
                ,
            ),
            html.Br(),
            html.Label(
                "Input2",
                htmlFor="input2",
                style="margin-right": "2em",
            ),
            dcc.Dropdown(
                id="input2",
                options=["label": i, "value": i for i in options2],
                style=
                    "width": "40%",
                    "display": "inline-block",
                    "verticalAlign": "middle",
                ,
            ),
            html.Br(),
            html.Div(
                [
                    html.Button(
                        id="reset-button",
                        n_clicks=0,
                        children="Reset",
                        style=
                            "fontWeight": "bold",
                            "textAlign": "center",
                            "marginRight": 25,
                        ,
                        title="Click to clear the inputs",
                    ),
                    html.Button(
                        id="submit-button",
                        n_clicks=0,
                        children="Submit",
                        style=
                            "fontWeight": "bold",
                            "textAlign": "center",
                            "marginRight": 25,
                        ,
                        title="Click to save inputs",
                    ),
                ]
            ),
            html.Div(id="msg"),
        ]
    )

    tab2_content = html.Div([html.P("This is tab 2!")])
    tab3_content = html.Div([html.P("This is tab 3!")])
    if tab == "tab1":
        return tab1_content
    elif tab == "tab2":
        return tab2_content
    elif tab == "tab3":
        return tab3_content

@dash_app.callback(
    Output("dummy-input-store", "data"),
    Input("input1", "value"),
    Input("input2", "value"),
)
def store_output_tab1(
    input1,
    input2,
):
    data = 
        "Input1": [input1],
        "Input2": [input2],
    

    return pd.DataFrame.from_dict(data, orient='index').to_dict('records')

@dash_app.callback(
    Output("dummy-input-store", "clear_data"), Input("reset-button", "n_clicks")
)
def reset_click_tab1(n_click_clear):
    if n_click_clear is not None and n_click_clear > 0:
        return True
    return False

@dash_app.callback(
    Output("msg", "children"),
    Input("submit-button", "n_clicks"),
    State("dummy-input-store", "data"),
)
def print_msg_tab1(n_clicks, data):
    if n_clicks is not None and n_clicks > 0:
        dummy_inputs = pd.DataFrame.from_dict(data)
        filepath = r"C:\input_data.xlsx"
        
        try:
            with pd.ExcelWriter(filepath, engine="openpyxl", mode="a") as writer:
                dummy_inputs.to_excel(writer, sheet_name = "Dummy_Inputs")
        except FileNotFoundError:
            dummy_inputs.to_excel(filepath, sheet_name = "Dummy_Inputs")
        return html.Div([html.H6(f"Inputs Saved:data")])
    raise PreventUpdate

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

【讨论】:

感谢您指出问题出在 excel writer 而不是破折号。您的建议是为每个新条目创建一个新标签。所以我决定使用 csv 模块中的 Dictwriter 并将我的数据保存在 csv 文件中。

以上是关于如何将 json 从 dash dcc.Store 保存到 excel 文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 DCC.Store 组件的复杂 numpy 数组 (Dash/Python)

如何从我的自定义制作 DASH 之类的视频播放器中制作 HLS 视频播放器?

如何在 freemarker 模板处理中转义 unicode 符号?

如何从客户端应用程序 (Dash.js) 向 OpenFlow 交换机发送消息

如何将 Dash 布局保存到 HTML 文件

如何通过 Python 中的 Plotly 从 Dash 的下拉列表中选择数据集列?