Skip to main content

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.

Tested Deployments

Each browser demo was tested in the following environments:

BrowserDateNotes
Chrome 1212024-02-21
Safari 17.32024-02-21text/rtf not supported
Brave 1.592024-02-21

Browser Reading (paste)

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 method1.

The following example reads from the HTML clipboard and generates a XLSX file using the SheetJS writeFile method2:

document.onpaste = function(e) {
/* get HTML */
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. Tested browsers support:

MIME typeData format
text/plainTSV (tab separated values)
text/htmlHTML
text/rtfRTF (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).

Result
Loading...
Live Editor
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.

Due to browser API limitations, the system file browser should be used to select and copy spreadsheets into the clipboard.

The event clipboardData.files property, if it is set, is a list of files.

Result
Loading...
Live Editor
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.

The event clipboardData property has a setData method which accepts a string that can be generated using type: "string" in the SheetJS write method3.

The following example generates a HTML string from the first sheet of a workbook object and loads the string into the HTML clipboard:

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.

The following table lists the supported MIME types and the bookType4 value that must be passed to the SheetJS write method:

MIME typeData formatbookType
text/plainTSV (tab separated values)txt
text/htmlHTMLhtml

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 file, select cell A1, and paste.

Result
Loading...
Live Editor
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 TypeRead Clipboard DataWrite Clipboard Data
TSVclipboard.readTextclipboard.writeText
HTMLclipboard.readHTMLclipboard.writeHTML
RTFclipboard.readRTFclipboard.writeRTF

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"})
});
}

Footnotes

  1. See read in "Reading Files"

  2. See writeFile in "Writing Files"

  3. See write in "Writing Files"

  4. See "Supported Output Formats" in "Writing Files" for details on bookType