如何将 Jupyter 笔记本中单元格的输出复制到剪贴板?

47

如何在 Jupyter Notebook 中将单元格的输出内容复制到剪贴板,而不必用拖放方式选择它呢?

在此输入图片描述


5
这不完全准确,因为你需要用鼠标选择,但我觉得这很有帮助。你可以使用“Shift”+“右键”来访问浏览器的原生上下文菜单。(适用于Chrome 76,并且应该适用于大多数现代浏览器)。 - Stephen McAteer
10个回答

35
Jupyter notebook在浏览器中运行,因此您可以使用一些JavaScript来选择和复制单元格到剪贴板。经过一些尝试和错误,我想出了这个书签小工具:
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

将其添加到书签中,并在笔记本页面上运行。

工作原理

  1. 对于每个输入和输出单元格,它都会添加一个小的复制图标,当鼠标悬停时显示。
  2. 点击复制图标会选择相应的单元格内容,将其发送到剪贴板,然后取消选择。内容以纯文本和HTML格式复制,因此可以用于复制带有格式的文本、表格、图像和图表。
  3. 复制后,图标消失以提供一些反馈,并在下次悬停事件时显示。

它应该适用于包括IE11在内的任何现代浏览器。

以下是解码的源代码:

(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是通过从代码中删除换行符并将其通过encodeURIComponent()函数运行来创建的。

旧答案

有几种方法可以在Python中使用tkinter、win32或ctypes将数据复制到剪贴板。但如果您正在使用Jupyter笔记本,您可能也在使用pandas。

import pandas as pd
df = pd.DataFrame(['Copy me to clipboard'])
df.to_clipboard(index=False,header=False)

2
我同意 - 没有一种方法可以只复制粘贴而不选择整个页面吗? - Reddspark
1
此外,如果您的 Jupyter 服务器在不同的计算机上运行,则这种方法将不起作用。 - Shayan RC
2
@FranckDernoncourt 我已经添加了更好的解决方案。 - mx0
3
我喜欢这个!这是一行代码:pd.DataFrame(['Copy me to clipboard']).to_clipboard(index=False,header=False),这样你就不会创建一个保留的数据框。 - RufusVS
2
请查看此处以了解如何运行书签小程序。 - Venkatachalam
显示剩余8条评论

21
你可以尝试使用第三方包pyperclip,它可以将字符串复制到系统剪贴板中。

要翻译的内容

import pyperclip as clip


# Sample Data
res = [(str(x*100), x) for x in range(1, 10)]
res

输出

[('100', 1), ('200', 2), ('300', 3),
 ('400', 4), ('500', 5), ('600', 6), 
 ('700', 7), ('800', 8), ('900', 9)]

代码

clip.copy(f"{res}")
#clip.copy("{}".format(res))                           # python < 3.6
clip.paste()                                           # or Ctrl + V

输出

[('100', 1), ('200', 2), ('300', 3),
 ('400', 4), ('500', 5), ('600', 6),
 ('700', 7), ('800', 8), ('900', 9)]

19

我使用Jupyter Labs。您可以右键单击要复制的输出单元格,然后选择为输出创建新视图。这将把输出放在一个单独的屏幕中。在新的输出屏幕上,它将允许您使用CRTL + C或右键单击来复制。

希望这有所帮助。


5

这个方法适用于Jupyter Lab 3.1.4。在单元格输出区域右键点击(或在Mac触控板上用两根手指点击)。

会弹出一个菜单,顶部选项是“复制输出到剪贴板”。

menu


5

这个方法使用鼠标,但不需要拖动(如果你有很多页的文本,拖动会花费很长时间),并且比代码解决方案更简单:

  1. 选择输出的第一个字符enter image description here
  2. 使用滚动条到达输出底部(这是更快的部分)
  3. Shift+点击输出底部,从第一个字符扩展到最后一个字符
  4. 按Ctrl+C复制

4

在Ubuntu 19.10 / Firefox浏览器上,我可以通过连续点击3次来选中整个输出单元格内容,然后像平常一样使用CTRL+C来复制。


Mac + Chrome,同样可以使用。 - AJ AJ

1
在下面的示例中,实际文本没有输出(尽管如果更改函数的第6行,则可以输出),而是显示了一行确认,即已在剪贴板上提供了若干行。

all_data_str是一个字符串,其内容将在剪贴板上提供,编写自己的生成函数dump_data_array。

当用户单击调用该函数的按钮时,将触发粘贴操作:

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))

0
在MacOS上使用pbcopypbpaste

[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


0

例如,Colab:

from IPython.display import HTML
text = 'hello'
HTML(f"<button onclick=navigator.clipboard.writeText('{text}')>Copy</button>")

-1
  1. 选择输出单元格的文本。
  2. 点击并拖动内容到文本编辑器中(其他窗口)。 完成。

问题的第一句话是“...不需要使用拖放来选择它吗?” - Tzane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接