javascript 中从剪贴板抓取部分数据

Grabbing partial data from the clipboard in javascript

我复制了一个 Excel table 大约有一百万行。当我查看系统上的剪贴板时,它似乎包含大约 250MB 的数据。但是,我需要从中获取样式信息,例如:

这整个数据(远远)不到 1MB 的数据。有没有办法像读取文件或流一样读取剪贴板,这样我就可以这样做,例如:

clipboard.read(1024)

否则,如果我顺子走:

evt.clipboardData.getData('text/html')

然后抓取我要的那段数据拿到数据后,我花了10多秒才搞定!虽然我认为事件应该只需要 0.1 秒左右,但如果我能够以部分方式读取剪贴板数据,就好像它是一个文件一样。

我可以在这里做什么?可以在剪贴板上使用 FileReader 吗?如果可以,那该怎么做?

经过大量研究,这在 Javascript 中是不可能的,不支持使用剪贴板对象进行 stream 操作,因此您必须一次阅读全部内容。

但是,您可以使用 MacOS(从您的图片推断)本地工具来处理剪贴板数据:pbcopypbpaste,它们非常快,数量级比 Javascript 更快,因此您可以将繁重的文本处理委托给他们。

所以,在你复制 250MB 的文本后,你可以将它切片并只读取前 n 个字节(在本例中为 1024),然后用它替换剪贴板的内容,所以现在你就可以了您可以在 Javascript:

中使用它
pbpaste | cut -b 1-1024 | pbcopy

如果您需要有关每个终端命令的任何文档,您可以 运行 man command_name。使用这种方法提取剪贴板的前 1024 个字节不到一秒钟。

我用 python 创建的 390MB 示例文本文件测试了这个脚本:

c = 30000000

with open('sample.txt', 'w') as file:
    file.writelines('a sample code' for i in range(c))

Clipboard.read API cited in the comments can return clipboard contents as a list of ClipboardItem objects, from which you can then obtain a Blob object, which you can then .slice to perform partial reads. (The MDN claimsClipboard.read returns 一个 DataTransfer 对象,但这不符合规范,所以我认为这是陈旧的信息,或者只是错误的。 )

const perm = await navigator.permissions.query({ name: 'clipboard-read' });
switch (perm.state) {
case 'granted':
case 'prompt':
    break;
default:
    throw new Error("clipboard-read permission not granted");
}

const items = await navigator.clipboard.read();
for (const item of items) {
    const blob = await item.getType('text/html');
    const first1M = await blob.slice(0, 1048576).arrayBuffer();
    
    /* process first1M */
}

但是,剪贴板 API 目前还远未普及。 Firefox ESR 78.9 没有实现它,而且根据 MDN 的状态,它似乎根本不在 Mozilla 的雷达范围内。 (我还没有尝试过其他浏览器;也许在 Chrome 中它已经可以使用了。)