7.5 KiB
title | pagination_prev | pagination_next | sidebar_custom_props | ||
---|---|---|---|---|---|
Clipboard Data | demos/data/index | demos/cloud/index |
|
Spreadsheet software like Excel typically support copying and pasting cells and data. This is implemented through the Clipboard ("Pasteboard" in MacOS).
When copying a selection of cells, Excel for Windows stores a screenshot of the selected cells as an image. It also creates and stores a number of strings and files for the various formats, including TSV, CSV, HTML, RTF, SYLK, DIF, XLSB, XLS (both '97-2004 and '95), and SpreadsheetML 2003.
Not all Clipboard APIs offer access to all clipboard types.
Browser Reading (paste)
Clipboard data can be read from a paste
event, accessible from the event
clipboardData
property:
document.onpaste = function(e) {
/* get TSV */
var str = e.clipboardData.getData('text/html');
/* parse */
var wb = XLSX.read(str, {type: "string"});
/* DO SOMETHING WITH wb HERE */
};
getData
accepts one argument: the desired MIME type. Chrome 103 supports:
MIME type | Data format |
---|---|
text/plain |
TSV (tab separated values) |
text/html |
HTML |
text/rtf |
RTF (rich text format) |
getData
returns a string compatible with the string
type for XLSX.read
.
Live Demo
Open a file in Excel, copy some cells, then come back to this window. Click on "RESULT" below and paste (Control+V for Windows, Command+V for Mac).
function ClipboardRead() {
const [csvs, setCSVs] = React.useState([ "", "", "" ]);
/* Set up paste handler */
const paste = React.useCallback((e) => {
/* this demo will read 3 different clipboard data types */
var mime_arr = [ 'text/plain', 'text/html', 'text/rtf' ];
/* get clipboard data for each type */
var data_arr = mime_arr.map(mime => e.clipboardData.getData(mime));
/* parse each data string into a workbook */
var wb_arr = data_arr.map(str => XLSX.read(str, {type: "string"}));
/* get first worksheet from each workbook */
var ws_arr = wb_arr.map(wb => wb.Sheets[wb.SheetNames[0]]);
/* generate CSV for each "first worksheet" */
var result = ws_arr.map(ws => XLSX.utils.sheet_to_csv(ws));
setCSVs(result);
}, []);
return ( <>
{csvs[0] && (<pre><b>Data from clipboard TSV (text/plain)</b><br/>{csvs[0]}</pre>)}
{csvs[1] && (<pre><b>Data from clipboard HTML (text/html)</b><br/>{csvs[1]}</pre>)}
{csvs[2] && (<pre><b>Data from clipboard RTF (text/rtf)</b><br/>{csvs[2]}</pre>)}
{csvs.every(x => !x) && <b onPaste={paste}>Copy data in Excel, click here, and paste (Control+V)</b>}
</> );
}
Reading Files
Modern browsers support reading files that users have copied into the clipboard.
:::caution
Excel does not copy data into files! Use your system file browser to select and copy spreadsheets into the clipboard.
:::
The event clipboardData.files
property, if it is set, is a list of files.
function ClipboardReadFiles() {
const [data, setData] = React.useState([]);
/* Set up paste handler */
const paste = React.useCallback(async(e)=>{
const result = [];
/* loop over files */
const files = e.clipboardData.files || [];
for(let i = 0; i < files.length; ++i) {
const file = files.item(i);
/* filter MIME type for spreadsheets */
if(!file.type.match(/excel|sheet|csv/)) continue;
/* read data */
const wb = XLSX.read(await file.arrayBuffer());
/* capture sheet names */
result.push([file.name, wb.SheetNames]);
}
setData(result);
}, []);
return ( <>
{data.map((f,idx) => (<pre key={idx}>
<b>Sheet Names from {f[0]}</b><br/>{f[1].join("\n")}
</pre>))}
{!data.length && (<b onPaste={paste}>Copy files, click here, and paste (Control+V)</b>)}
</> );
}
Browser Writing (copy)
Clipboard data can be written from a copy
event, accessible from the event
clipboardData
property:
document.oncopy = function(e) {
/* get HTML of first worksheet in workbook */
var str = XLSX.write(wb, {type: "string", bookType: "html"});
/* set HTML clipboard data */
e.clipboardData.setData('text/html', str);
/* prevent the browser from copying the normal data */
e.preventDefault();
};
setData
accepts two arguments: MIME type and new data. Chrome 103 supports:
MIME type | Data format |
---|---|
text/plain |
TSV (tab separated values) |
text/html |
HTML |
Browsers do not currently support assigning to the text/rtf
clipboard type.
Live Demo
This demo creates a simple workbook from the following HTML table:
SheetJS | Clipboard | Demo |
bookType | RTF | |
source | HTML Table |
Create a new file in Excel then come back to this window. Select the text below and copy (Control+C for Windows, Command+C for Mac). Go back to the excel
function ClipboardWrite() {
/* Set up copy handler */
const copy = React.useCallback((e) => {
/* generate workbook from table */
var wb = XLSX.utils.table_to_book(document.getElementById("srcdata"));
/* get HTML of first worksheet in workbook */
var str = XLSX.write(wb, {type: "string", bookType: "html"});
/* set HTML clipboard data */
e.clipboardData.setData('text/html', str);
/* prevent the browser from copying the normal data */
e.preventDefault();
}, []);
return (
<b onCopy={copy}>Select this text, copy (Control+C), and paste in Excel</b>
);
}
Electron
Electron Clipboard API supports HTML and RTF clipboards.
There are special methods for specific clipboard types:
File Type | Read Clipboard Data | Write Clipboard Data |
---|---|---|
RTF | clipboard.readRTF |
clipboard.writeRTF |
TSV | clipboard.readText |
clipboard.writeText |
HTML | clipboard.readHTML |
clipboard.writeHTML |
Each method operates on JS strings.
clipboard.write
can assign to multiple clipboard types:
const { clipboard } = require('electron');
const XLSX = require('xlsx');
function copy_first_sheet_to_clipboard(workbook) {
clipboard.write({
text: XLSX.write(wb, {type: "string", bookType: "txt"}),
rtf: XLSX.write(wb, {type: "string", bookType: "rtf"}),
html: XLSX.write(wb, {type: "string", bookType: "html"})
});
}
:::caution Experimental Buffer Clipboard Support
Electron additionally supports binary operations using Buffer
objects. This
support is considered "experimental" and is not guaranteed to work on any
platform. Issues should be raised with the Electron project
On the MacOS
platform, some versions of Excel store a packaged file with key
dyn.ah62d4qmxhk4d425try1g44pdsm11g55gsu1en5pcqzwc4y5tsz3gg3k
. The package is
a simple CFB file that can be parsed:
const { clipboard } = require('electron');
const XLSX = require("xlsx");
const buf = clipboard.readBuffer('dyn.ah62d4qmxhk4d425try1g44pdsm11g55gsu1en5pcqzwc4y5tsz3gg3k');
const cfb = XLSX.CFB.read(buf, {type: "buffer"});
const pkg = XLSX.CFB.find(cfb, "Package").content;
const wb = XLSX.read(pkg);
:::