--- title: Clipboard Data --- 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: ```js 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). ```jsx live 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] && (
Data from clipboard TSV  (text/plain)
{csvs[0]}
)} {csvs[1] && (
Data from clipboard HTML (text/html)
{csvs[1]}
)} {csvs[2] && (
Data from clipboard RTF  (text/rtf)
{csvs[2]}
)} {csvs.every(x => !x) && Copy data in Excel, click here, and paste (Control+V)} ); } ``` ### 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. ```jsx live 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) => (
      Sheet Names from {f[0]}
{f[1].join("\n")}
))} {!data.length && (Copy files, click here, and paste (Control+V))} ); } ``` ## Browser Writing (copy) Clipboard data can be written from a `copy` event, accessible from the event `clipboardData` property: ```js 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:
SheetJSClipboardDemo
bookTypeRTF
sourceHTML 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 ```jsx live 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 ( Select this text, copy (Control+C), and paste in Excel ); } ``` ## Electron Electron [Clipboard API](https://www.electronjs.org/docs/latest/api/clipboard) 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. :::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: ```js 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); ``` :::