I'm building a Dash app in Python and trying to add a button that lets the user copy the table content to the clipboard so they can paste it into Excel.
The table displays correctly, but when I click the "Copy table" button, nothing is actually copied to the clipboard — even though the message “Table copied” appears.
Here's a simplified version of my code:
from dash import Dash, html, dash_table, dcc, Input, Output, State
import pandas as pd
app = Dash(__name__)
app.layout = html.Div([
html.Button("Copy table", id="copy_btn", n_clicks=0, className="btn btn-primary"),
dcc.Clipboard(id="clipboard_table", style={"display": "none"}),
html.Div(id="message_copy", style={"color": "green"}),
dash_table.DataTable(
id="sales_table",
columns=[
{"name": "Department", "id": "department"},
{"name": "Sales", "id": "sales"},
{"name": "Weight", "id": "weight"},
],
data=[
{"department": "Phones", "sales": 1000, "weight": "55.8%"},
{"department": "Computers", "sales": 600, "weight": "26.1%"},
],
style_table={'overflowX': 'auto'},
)
])
@app.callback(
Output("clipboard_table", "content"),
Output("message_copy", "children"),
Input("copy_btn", "n_clicks"),
State("sales_table", "data"),
prevent_initial_call=True
)
def copy_table(n_clicks, data):
if not data:
return "", "⚠️ No data to copy"
df = pd.DataFrame(data)
text = df.to_csv(sep="\t", index=False)
return text, "✅ Table copied. You can paste it in Excel (Ctrl+V)"
if __name__ == "__main__":
app.run_server(debug=True)
I’ve tried:
Using dcc.Clipboard() as shown in the Dash docs.
Injecting JavaScript with html.Script() to use navigator.clipboard.writeText(text) — but that doesn't run when deployed (Render blocks inline scripts).
Is there a recommended or secure Dash-native way to do this, especially when the app is deployed (e.g., on Render or Heroku)?


pandas) instead of Excel.