| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | --- | 
					
						
							| 
									
										
										
										
											2022-08-26 05:39:17 +00:00
										 |  |  | title: Clipboard Data | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_prev: demos/data/index | 
					
						
							|  |  |  | pagination_next: demos/cloud/index | 
					
						
							|  |  |  | sidebar_custom_props: | 
					
						
							|  |  |  |   summary: Reading and writing data and files in the clipboard | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Spreadsheet software like Excel typically support copying and pasting cells and | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | data. This is implemented through the Clipboard ("Pasteboard" in MacOS). | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  | ## Browser Reading (paste)
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Clipboard data can be read from a `paste` event, accessible from the event | 
					
						
							|  |  |  | `clipboardData` property: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | document.onpaste = function(e) { | 
					
						
							| 
									
										
										
										
											2023-06-25 19:57:03 +00:00
										 |  |  |   /* get HTML */ | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  |   var str = e.clipboardData.getData('text/html'); | 
					
						
							|  |  |  |   /* parse */ | 
					
						
							|  |  |  |   var wb = XLSX.read(str, {type: "string"}); | 
					
						
							|  |  |  |   /* DO SOMETHING WITH wb HERE */ | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `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 | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  | function ClipboardRead() { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  |   const [csvs, setCSVs] = React.useState([ "", "", "" ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Set up paste handler */ | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  |   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); | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  |   return ( <> | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  |       {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>)} | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  |       {csvs.every(x => !x) && <b onPaste={paste}>Copy data in Excel, click here, and paste (Control+V)</b>} | 
					
						
							|  |  |  |   </> ); | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  | ### 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) => (<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>)} | 
					
						
							|  |  |  |   </> ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  | ## 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: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  | <table id="srcdata"><tbody> | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  |   <tr><td>SheetJS</td><td>Clipboard</td><td>Demo</td></tr> | 
					
						
							|  |  |  |   <tr><td>bookType</td><td>RTF</td></tr> | 
					
						
							|  |  |  |   <tr><td>source</td><td>HTML Table</td></tr> | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  | </tbody></table> | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  | function ClipboardWrite() { | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  |   /* Set up copy handler */ | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  |   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(); | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2022-10-18 07:55:41 +00:00
										 |  |  |     <b onCopy={copy}>Select this text, copy (Control+C), and paste in Excel</b> | 
					
						
							| 
									
										
										
										
											2022-07-07 04:05:14 +00:00
										 |  |  |   ); | 
					
						
							| 
									
										
										
										
											2022-07-06 05:38:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Electron
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-07 23:23:05 +00:00
										 |  |  | Electron Clipboard API supports HTML and RTF clipboards. | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-07 23:23:05 +00:00
										 |  |  | `clipboard.write` can assign to multiple clipboard types: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | 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"}) | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | :::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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | On the `MacOS` platform, some versions of Excel store a packaged file with key | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | `dyn.ah62d4qmxhk4d425try1g44pdsm11g55gsu1en5pcqzwc4y5tsz3gg3k`.  The package is | 
					
						
							|  |  |  | a simple CFB file that can be parsed: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2022-11-07 23:23:05 +00:00
										 |  |  | const { clipboard } = require('electron'); | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | const buf = clipboard.readBuffer('dyn.ah62d4qmxhk4d425try1g44pdsm11g55gsu1en5pcqzwc4y5tsz3gg3k'); | 
					
						
							| 
									
										
										
										
											2022-07-30 22:17:34 +00:00
										 |  |  | const cfb = XLSX.CFB.read(buf, {type: "buffer"}); | 
					
						
							| 
									
										
										
										
											2022-07-20 08:58:29 +00:00
										 |  |  | const pkg = XLSX.CFB.find(cfb, "Package").content; | 
					
						
							|  |  |  | const wb = XLSX.read(pkg); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: |