Da sh скачать сгенерированный в памяти файл при нажатии кнопки: Как указать имя файла? - PullRequest
0 голосов
/ 29 мая 2020

Я генерирую в памяти файл Excel через pd.ExcelWriter и BytesIO для события щелчка в моем приложении Python3 .8 da sh.

Все работает как надо. Когда я загружаю свой файл, я получаю это всплывающее сообщение с вопросом, хочу ли я продолжить загрузку / открытие сгенерированного файла. Тем не менее, всплывающее сообщение показывает эту (я думаю, кодированную base64) строку (или путь?), Например ...ydaHdjhgk328AAAAnxsAA==, и после загрузки загрузка получает (случайно назначенный?) Набор символов в качестве имени файла (например, ZySzsdn1.xlsx) .

Как я могу настроить это так, чтобы он отображал и назначал имя файла примерно как download.xlsx? Я предполагаю, что это как-то связано с base64 в кодировке href.

Функция для создания файла Excel:

def write_product_file():
    output = BytesIO()
    writer = pd.ExcelWriter(output, engine="xlsxwriter")
    upload_df = pd.DataFrame()
    upload_df.to_excel(writer, index=False, sheet_name="sheet1")
    writer.save()
    return output

Кнопка в моем Da sh application:

html.Div(
  id="select-upload-form",
  style={"width": "100%"},
  children=[
    dbc.Button(
      "Download the upload form",
      id="download-excel",
      color="secondary",
      external_link="true",
      target="",
      href="",
    ),
  ],
),

И, наконец, мой обратный вызов:

@app.callback(
    [
        Output("download-excel", "href"),
        Output("download-excel", "color"),
        Output("download-excel", "target"),
    ],
    [Input("download-excel", "n_clicks")],
)
def download_template_file(n_clicks):
    if n_clicks:
        excelfile = write_product_file()
        excelfile.seek(0)
        media_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        data = base64.b64encode(excelfile.read()).decode("utf-8")
        href_data = f"data:{media_type};base64,{data}"
        return href_data, "success", href_data,
    else:
        return None, "secondary", None

1 Ответ

2 голосов
/ 29 мая 2020

Вы можете использовать компонент Download из пакета da sh -extensions,

pip install dash-extensions == 0.0.18

Синтаксис проще, и он имеет аргумент filename. Вот небольшой пример:

import dash
import dash_html_components as html
import numpy as np
import pandas as pd

from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_bytes

# Generate some example data.
data = np.column_stack((np.arange(10), np.arange(10) * 2))
df = pd.DataFrame(columns=["a column", "another column"], data=data)
# Create app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download xlsx", id="btn"), Download(id="download")])


@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def generate_xlsx(n_nlicks):

    def to_xlsx(bytes_io):
        xslx_writer = pd.ExcelWriter(bytes_io, engine="xlsxwriter")
        df.to_excel(xslx_writer, index=False, sheet_name="sheet1")
        xslx_writer.save()

    return send_bytes(to_xlsx, "some_name.xlsx")


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

Отказ от ответственности: я являюсь автором пакета da sh -extensions.

...