Copy dataframe to clipboard

Is it possible to copy the data displayed by st.dataframe to the clipboard? The current implementation allows a partial copy paste for single column dataframes, but doesn’t work at all for multi column.

Thanks,
Kieran

Hi @kierancondon, welcome to the Streamlit community!

Can you be more specific of the behavior you are desiring? For a multi-column dataframe, is your desire to be able to still highlight just a single column?

Best,
Randy

1 Like

Hi Randy,

There is no need to select individual columns. The users would just like to be able to select the whole dataframe including the row index, headers and data and copy it all into clipboard, so as to paste it to Excel. The same result as if someone could run “df.to_clipboard()”.

I don’t know why it works better on the dfs in your help documentation than in my app. I can’t even select the index from a dataframe in the app. Nevertheless, even with the dfs in the help documentation, pasting the values in excel gives something very difficult to work with.

Copy/Paste does work well for “st.table”, yet for any dataframe larger than screen size, table is not the right choice.

I believe this development is important because streamlit does not yet offer ways for the user to pull data from the app.

Thank you,
Kieran

Can any one please help here, how to get Dataframe copied at client side instead of Server side. I used pd.to_clipboard and it didnt work on client side but noticed it was copied on clipboard on server side.

I have the same issue

Hi,

One possible way could be to bind clipboard writeText event like this,

import streamlit as st
from bokeh.models.widgets import Button
from bokeh.models import CustomJS
from streamlit_bokeh_events import streamlit_bokeh_events
import pandas as pd

df = pd.DataFrame({"x": [1, 2, 3, 4], "y": ["a", "b", "c", "d"]})

st.dataframe(df)

copy_button = Button(label="Copy DF")
copy_button.js_on_event("button_click", CustomJS(args=dict(df=df.to_csv(sep='\t')), code="""
    navigator.clipboard.writeText(df);
    """))

no_event = streamlit_bokeh_events(
    copy_button,
    events="GET_TEXT",
    key="get_text",
    refresh_on_update=True,
    override_height=75,
    debounce_time=0)

PS. you can always use streamlit bokeh events to run some short javascript code to run something on client side :slight_smile:

Hope it helps @MesumRaza!

3 Likes

it worked like charm, the only modification I did is to set up refresh_on_update=True because in my use case the data I wanted to retrieve changed basis on user choice, and if it set to False doesn’t update de value in the clipboard.

Thank you so much for the solution! @ash2shukla

1 Like

Yes ! Thanks for pointing it out,
I have made the edit :slight_smile:

1 Like

Well done.
I want to know if there have 2 or more dataframe in web page, how should I use the clip function for each dataframe?
And the gif picture is through which method to insert into answer region?
Thank you.

Thankyou so much Lots of Love @ash2shukla. Glad it worked for everyone was a long outstanding query.

1 Like

Is there any long term plan to adapt the streamlit-bokeh-events into streamlit?

1 Like

Hi @ash2shukla I was trying today in production and got some errors like this

Investigated and it was involved in errors around CORS XSRF.

Can you please help.

I think it will work on localhost else it should be served over https.
Is your streamlit server running over https ?

No its HTTP and Its hosted on Internal VM Server and Other users are given access to it via Port Allowance

When I press Copy It copies on VM’s Clipboard rather than Client Side.

Hi Check this link for clipboard api availability. You cant use clipboard api on non secure origins ( http )

https://developer.mozilla.org/en-US/docs/Web/API/Clipboard#clipboard_availability

Okay… sounds like a limitation for now. Any other workaround you may suggest?

Hi, @ash2shukla ! It just doesnt work for me, I tried either to replace “button_click” to ButtonClick module as seen in another post or using another browser (tried on chrome and edge).
It’s almost exactly as you exemplified above

copy_button = Button(label="Copy DF")
    copy_button.js_on_event(ButtonClick, CustomJS(args=dict(df=df_export.to_csv(sep='\t')), code="""
        navigator.clipboard.writeText(df);
        """))
    
    
    no_event = streamlit_bokeh_events(
        copy_button,
        events="GET_TEXT",
        key="get_text",
        refresh_on_update=False,
        override_height=75,
        debounce_time=0)

The output is nothing, doesnt return any error nor paste the data. Is there something i’m missing?

1 Like

Hi @betinhosaad , can u see in console whether any error pops up when u click the button ? Try adding a console.log prior to navigator.clipboard thing to see if the js code runs at all or not.

Uncaught (in promise) DOMException: The Clipboard API has been blocked because of a permissions policy applied to the current document.

Trying to find out how to fix this

Edit:
@ash2shukla is it possible to allow copy paste using bokeh? couldnt find anything helpful :pensive:

2 Likes