How can I copy to the clipboard the output of a cell in a Jupyter notebook, without having to select it with drag-and-drop?
-
5Not exactly on point, because you would need to select with the mouse, but I found this helpful. You can use `Shift`+`Right mouse button` to access the browser's native context menu. (Works in Chrome 76, and should work in most modern browsers). – Stephen McAteer Aug 29 '19 at 22:55
10 Answers
Jupyter notebook runs in browser so you can use some javascript to select and copy cells to clipboard. After some trial and error I came up with this bookmarklet:
javascript:(function%20()%20%7B%20function%20SelectText(element)%20%7B%20var%20range%3B%20var%20selection%3B%20if%20(document.body.createTextRange)%20%7B%20range%20%3D%20document.body.createTextRange()%3B%20range.moveToElementText(element)%3B%20range.select()%3B%20copy2clipboard(range.text%2C%20element.innerHTML)%3B%20document.getSelection().removeAllRanges()%3B%20%7D%20else%20if%20(window.getSelection)%20%7B%20selection%20%3D%20window.getSelection()%3B%20range%20%3D%20document.createRange()%3B%20range.selectNodeContents(element)%3B%20selection.removeAllRanges()%3B%20selection.addRange(range)%3B%20copy2clipboard(selection.toString()%2C%20element.innerHTML)%3B%20selection.removeAllRanges()%3B%20%7D%20%7D%3B%20function%20copy2clipboard(text%2C%20html)%20%7B%20function%20listener(e)%20%7B%20e.clipboardData.setData('text%2Fplain'%2C%20text)%3B%20e.clipboardData.setData('text%2Fhtml'%2C%20html)%3B%20e.preventDefault()%3B%20%7D%20document.addEventListener('copy'%2C%20listener)%3B%20document.execCommand('copy')%3B%20document.removeEventListener('copy'%2C%20listener)%3B%20%7D%3B%20%24('%23notebook-container').on('mouseenter'%2C%20'.input%2C%20.output_wrapper'%2C%20function%20()%20%7B%20if%20(%24(this).find('i%3Alast').length)%20%7B%20%24(this).find('i%3Alast').show()%3B%20%7D%20else%20%7B%20%24(this).css(%7B%20'position'%3A%20'relative'%20%7D).append(%24('%3Ci%20style%3D%22position%3Aabsolute%3B%20top%3A7px%3B%20left%3A%207px%3B%22%20class%3D%22fa-copy%20fa%22%3E%3C%2Fi%3E').on('click'%2C%20function%20()%20%7B%20SelectText(%24(this).parent().find('.input_area%2C%20.output')%20%5B0%5D)%3B%20%24(this).slideUp()%3B%20%7D))%3B%20%7D%20%7D)%3B%20%24('%23notebook-container').on('mouseleave'%2C%20'.input%2C%20.output_wrapper'%2C%20function%20()%20%7B%20%24(this).find('i%3Alast').hide()%3B%20%7D)%3B%20%7D)%20()%3B
Add it to your bookmarks and run it on a notebook page.
How it works
- For every input and output cell it adds a small copy icon that shows on hover.
- Clicking on copy icon selects a corresponding cell content, sends it to clipboard and then deselects it. Content is copied in text/plain and text/html format so it can be used to copy text, tables, images and plots with formatting.
- After coping, icon disappears to give some feedback and shows on next hover event.
It should work on any modern browser including IE11.
Here is decoded source:
(function () {
function SelectText(element) {
var range;
var selection;
if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
copy2clipboard(range.text, element.innerHTML);
document.getSelection().removeAllRanges();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
copy2clipboard(selection.toString(), element.innerHTML);
selection.removeAllRanges();
}
};
function copy2clipboard(text, html) {
function listener(e) {
e.clipboardData.setData('text/plain', text);
e.clipboardData.setData('text/html', html);
e.preventDefault();
}
document.addEventListener('copy', listener);
document.execCommand('copy');
document.removeEventListener('copy', listener);
};
$('#notebook-container').on('mouseenter', '.input, .output_wrapper', function () {
if ($(this).find('i:last').length) {
$(this).find('i:last').show();
} else {
$(this).css({
'position': 'relative'
}).append($('<i style=\"position:absolute; top:7px; left: 7px;\" class=\"fa-copy fa\"></i>').on('click', function () {
SelectText($(this).parent().find('.input_area, .output') [0]);
$(this).slideUp();
}));
}
});
$('#notebook-container').on('mouseleave', '.input, .output_wrapper', function () {
$(this).find('i:last').hide();
});
}) ();
Bookmarklet is created by removing newlines from code and running it through encodeURIComponent()
function.
Old answer
There are several ways to copy data to clipboard in python using tkinter, win32 or ctypes. But if you are using Jupyter notebook, you probably also using pandas.
import pandas as pd
df = pd.DataFrame(['Copy me to clipboard'])
df.to_clipboard(index=False,header=False)
-
thanks. It's a bit inconvenient to have to add such piece of code in each cell the output of which one wishes to copy to the clipboard though. – Franck Dernoncourt May 28 '17 at 17:23
-
2I agree - isn't there a way to just copy paste without it selecting the entire page? – Reddspark Aug 23 '17 at 16:36
-
1Also, this would'nt work if your jupyter server is running on a different machine. – Shayan RC Oct 14 '17 at 06:59
-
2
-
1OMG you have just improved my life so much! This also enables reasonable copy+paste of tables (pandas!) into tools like Evernote and OneNote, for which you really want the HTML. – srs Aug 24 '18 at 09:06
-
3I LOVE THIS! Here's the one liner: `pd.DataFrame(['Copy me to clipboard']).to_clipboard(index=False,header=False)` so you don't create a retained data frame. – RufusVS Sep 17 '18 at 16:29
-
I just tried the trick, but multiline strings get pasted with \n instead of actually generating new lines. Anyway to get the formatted string out so it pastes with newlines? – RufusVS Sep 17 '18 at 16:34
-
-
I was trying to use the pandas version as in my earlier comment, but the main thing is: I generate a table which appears in the cells output. I then copy and paste from the output and paste it into a cell. Format is maintained with manual cut-and-paste. Lazy as I am, I'd like the cell to put the output to the clipboard directly for immediate pasting (so I don't have to go through the area-select process.) I'll see if I can make the javascript answer work for me. – RufusVS Sep 18 '18 at 17:49
-
@RufusVS try passing `line_terminator=''` to `to_clipboard()`. Default value is `\n`. – mx0 Sep 18 '18 at 18:27
-
@mx0 pd.DataFrame.to_clipboard() doesn't recognize line_terminator as a keyword argument. It has sep, which didn't seem to help. – RufusVS Sep 18 '18 at 21:38
-
2refer [here](https://mreidsma.github.io/bookmarklets/installing.html) on how to run bookmarklet – Venkatachalam May 01 '20 at 10:14
-
This is great. Can it be added to [jupyter_contrib_nbextensions](https://github.com/ipython-contrib/jupyter_contrib_nbextensions)? – omasoud Jan 06 '22 at 05:44
You can try using pyperclip
- a third-party package that copies strings to the system clipboard.
Given
import pyperclip as clip
# Sample Data
res = [(str(x*100), x) for x in range(1, 10)]
res
Output
[('100', 1), ('200', 2), ('300', 3),
('400', 4), ('500', 5), ('600', 6),
('700', 7), ('800', 8), ('900', 9)]
Code
clip.copy(f"{res}")
#clip.copy("{}".format(res)) # python < 3.6
clip.paste() # or Ctrl + V
Output
[('100', 1), ('200', 2), ('300', 3),
('400', 4), ('500', 5), ('600', 6),
('700', 7), ('800', 8), ('900', 9)]

- 40,867
- 14
- 129
- 121
I use Jupyter Labs. You can right click on the output cell that you want to copy and select
Create New View for Output. That will put the output in a separate screen. On the new output screen, it will let you copy using CRTL + C or using right click.
Hope this helps.

- 191
- 1
- 2
This uses the mouse, but requires no dragging (which can take a long time if you have a lot of pages of text) and is simpler than the code solutions:

- 433
- 4
- 12
On Ubuntu 19.10 / Firefox browser, I can select output cell content as a whole by clicking 3 times consecutively, then as usual CTRL+C to copy.
This can work in Jupyter Lab 3.1.4. Right-click (or click with two fingers on a Mac trackpad) in the cell output area.
A menu will pop up, where the top option is "Copy Output to Clipboard".

- 2,658
- 1
- 10
- 9
In the example below the actual text is not output (though it could be if changing line 6 of the function) instead the one line confirmation that a number of lines have been made available on the clipboard is shown.
The all_data_str is a string whose content will be made available on the clipboard, write your own generation function named dump_data_array.
The paste action is triggered when the user clicks a button which invokes the function:
def on_button_clipboard(b):
out_data.clear_output()
all_data_str=dump_data_array(da)
with out_data:
lineCount=all_data_str.count('\n')-1;
html_div = '<div id="pasting_to_clipboard">'+str(lineCount)+' lines pasted, you can now ^V into Excel</div>'
display(HTML(html_div))
js = """<script>
function copyToClipboard(text) {
var dummy = document.createElement("textarea");
document.body.appendChild(dummy);
dummy.value = text;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
}
</script>"""
display(HTML(js))
js2 = "<script>copyToClipboard(`" + all_data_str + "`);</script>"
display(HTML(js2))

- 347
- 3
- 7
On MacOs using pbcopy and pbpaste:
[1]: copy_value = 'Copy This'
# Copy value to clipboard
[2]: !echo {copy_value} | pbcopy
# Or, copy value to clipboard without trailing newline
[3]: !echo {copy_value} | tr -d '\n'| pbcopy
# Paste value from clipboard
[4]: paste_value = !pbpaste
# Confirm
[5]: copy_value == paste_value[0]
[5]: True

- 51
- 3
for e.g. colab:
from IPython.display import HTML
text = 'hello'
HTML(f"<button onclick=navigator.clipboard.writeText('{text}')>Copy</button>")

- 2,541
- 5
- 31
- 52
- Select text of output cell.
- Click and drag content into a text editor (other window). Finish.

- 1
-
The first sentence of the question state "...without having to select it with drag-and-drop?" – Tzane Aug 29 '23 at 13:52