From 32f1324e304de72085f56e817290a41d285cc6e0 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 18 Oct 2022 03:55:41 -0400 Subject: [PATCH] clipboard files --- docz/docs/03-demos/32-clipboard.md | 112 ++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 35 deletions(-) diff --git a/docz/docs/03-demos/32-clipboard.md b/docz/docs/03-demos/32-clipboard.md index 951f294..28084da 100644 --- a/docz/docs/03-demos/32-clipboard.md +++ b/docz/docs/03-demos/32-clipboard.md @@ -43,37 +43,81 @@ 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 Clipboard() { +function ClipboardRead() { const [csvs, setCSVs] = React.useState([ "", "", "" ]); /* Set up paste handler */ - React.useEffect(async() => { - document.onpaste = function(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); - }; + 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 ( - <> + 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)} - - ); + {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 @@ -104,34 +148,32 @@ Browsers do not currently support assigning to the `text/rtf` clipboard type. 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 Clipboard() { +function ClipboardWrite() { /* Set up copy handler */ - React.useEffect(async() => { - document.oncopy = function(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(); - }; + 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 + Select this text, copy (Control+C), and paste in Excel ); } ```