docs.sheetjs.com/docz/docs/03-demos/27-local/05-clipboard.md

260 lines
9.1 KiB
Markdown
Raw Normal View History

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.
2023-11-30 07:10:37 +00:00
:::note Tested Deployments
2023-09-02 09:26:57 +00:00
Each browser demo was tested in the following environments:
2025-04-24 00:30:01 +00:00
| Browser | Architecture | Date | Notes |
|:-------------|:-------------|:-----------|:--------------------------------|
2026-05-28 02:51:38 +00:00
| Chromium 146 | `darwin-arm` | 2026-05-16 | `text/rtf` did not work |
| Safari 26.2 | `darwin-arm` | 2026-05-16 | `text/rtf` not supported |
| Chromium 147 | `win11-arm` | 2026-05-26 | |
| Edge 148 | `win11-arm` | 2026-05-26 | |
2026-06-14 23:29:38 +00:00
| Chromium 147 | `linux-arm` | 2026-06-14 | `text/rtf` did not work |
| Konqueror 25 | `linux-arm` | 2026-06-14 | `text/rtf` not supported |
2025-04-24 00:30:01 +00:00
Windows and macOS tests were run against Excel, while Linux tests were run
against Gnumeric.
2023-09-02 09:26:57 +00:00
:::
2022-07-07 04:05:14 +00:00
## Browser Reading (paste)
2022-07-06 05:38:24 +00:00
2023-09-02 09:26:57 +00:00
Clipboard data can be read from a `paste` event.
The event `clipboardData` property has a `getData` method which returns a string
compatible with the `"string"` type in the SheetJS `read` method[^1].
The following example reads from the HTML clipboard and generates a XLSX file
using the SheetJS `writeFile` method[^2]:
2022-07-06 05:38:24 +00:00
```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
```
2023-09-02 09:26:57 +00:00
`getData` accepts one argument: the desired MIME type. Tested browsers support:
2022-07-06 05:38:24 +00:00
| MIME type | Data format |
|:-------------|:---------------------------|
| `text/plain` | TSV (tab separated values) |
| `text/html` | HTML |
| `text/rtf` | RTF (rich text format) |
### 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.
2023-09-02 09:26:57 +00:00
:::caution pass
2022-10-18 07:55:41 +00:00
2023-09-02 09:26:57 +00:00
Due to browser API limitations, the system file browser should be used to select
and copy spreadsheets into the clipboard.
2022-10-18 07:55:41 +00:00
:::
2026-06-14 23:29:38 +00:00
The event `clipboardData.files` property, if it is set, is a list of
[`File`](/docs/demos/local/file#blob-and-file) objects.
The `arrayBuffer` method of the `File` object returns a `Promise` that resolves
to an `ArrayBuffer` with binary data. The `ArrayBuffer` can be parsed by the
SheetJS [`read`](/docs/api/parse-options) method.
The following example parses copied files and displays all sheet names:
2022-10-18 07:55:41 +00:00
```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)
2023-09-02 09:26:57 +00:00
Clipboard data can be written from a `copy` event.
The event `clipboardData` property has a `setData` method which accepts a string
that can be generated using `type: "string"` in the SheetJS `write` method[^3].
2024-12-22 04:47:57 +00:00
The following example generates an HTML string from the first sheet of a SheetJS
workbook object and loads the string into the HTML clipboard:
2022-07-07 04:05:14 +00:00
```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();
};
```
2023-09-02 09:26:57 +00:00
`setData` accepts two arguments: MIME type and new data.
2022-07-07 04:05:14 +00:00
2023-09-02 09:26:57 +00:00
The following table lists the supported MIME types and the `bookType`[^4] value
that must be passed to the SheetJS `write` method:
| MIME type | Data format | `bookType` |
|:-------------|:---------------------------|:-----------|
| `text/plain` | TSV (tab separated values) | `txt` |
| `text/html` | HTML | `html` |
2022-07-07 04:05:14 +00:00
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
2023-09-02 09:26:57 +00:00
Excel file, select cell A1, and paste.
2022-07-07 04:05:14 +00:00
```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
2026-06-14 23:29:38 +00:00
:::caution pass
When the clipboard contains a full HTML document, Gnumeric prepends the title to
the table. The first row of the table will be "SheetJS Table Export". This does
not affect Excel or other popular spreadsheet software.
:::
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 |
|:----------|:---------------------|:----------------------|
| TSV | `clipboard.readText` | `clipboard.writeText` |
| HTML | `clipboard.readHTML` | `clipboard.writeHTML` |
2023-09-02 09:26:57 +00:00
| RTF | `clipboard.readRTF` | `clipboard.writeRTF` |
2022-07-20 08:58:29 +00:00
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"})
});
}
```
2023-09-02 09:26:57 +00:00
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^2]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
[^4]: See ["Supported Output Formats" in "Writing Files"](/docs/api/write-options#supported-output-formats) for details on `bookType`