forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			172 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			172 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | --- | ||
|  | title: Dropbox | ||
|  | pagination_prev: demos/ml | ||
|  | pagination_next: solutions/input | ||
|  | --- | ||
|  | 
 | ||
|  | <head> | ||
|  |   <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="4ysmnhy8wtm6k3w"></script> | ||
|  | </head> | ||
|  | 
 | ||
|  | Dropbox is a file hosting service that offers APIs for programmatic file access. | ||
|  | 
 | ||
|  | "Dropbox Apps" are the standard way to interact with the service.  The | ||
|  | ["Dropbox App"](#dropbox-app) section describes how this demo was configured. | ||
|  | 
 | ||
|  | :::note | ||
|  | 
 | ||
|  | The Dropbox API script is loaded in this page with | ||
|  | 
 | ||
|  | ```html | ||
|  | <script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="4ysmnhy8wtm6k3w"></script> | ||
|  | ``` | ||
|  | 
 | ||
|  | The `data-app-key` used in this demo is a "Development" key associated with the | ||
|  | `localhost` and `docs.sheetjs.com` domains.  Dropbox API does not require | ||
|  | "Production" approval for the Chooser or Saver. | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | The live demos require a Dropbox account. | ||
|  | 
 | ||
|  | ## Reading Files | ||
|  | 
 | ||
|  | "Chooser" is a small library that lets users select a file from their account. | ||
|  | 
 | ||
|  | ### Live Demo | ||
|  | 
 | ||
|  | The button must have the following options: | ||
|  | 
 | ||
|  | - `multiselect: false` ensures only one file can be selected | ||
|  | - `folderselect: false` limits selection to real files | ||
|  | - `linkType: "direct"` ensures the link points to a raw file | ||
|  | 
 | ||
|  | When a file is selected, the `success` callback will receive an array of files | ||
|  | (even if `multiselect` is disabled).  Each file object has a `link` file which | ||
|  | corresponds to a temporary URL that can be fetched. | ||
|  | 
 | ||
|  | If the live demo shows a message about `Dropbox` being undefined, please reload | ||
|  | this demo page. | ||
|  | 
 | ||
|  | ```jsx live | ||
|  | function SheetJSChoisissez() { | ||
|  |   const [msg, setMsg] = React.useState("Press the button to show a Chooser"); | ||
|  |   const btn = useRef(), tbl = useRef(); | ||
|  |   React.useEffect(() => { | ||
|  |     /* create button */ | ||
|  |     var button = Dropbox.createChooseButton({ | ||
|  |       /* required settings */ | ||
|  |       multiselect: false, | ||
|  |       folderselect: false, | ||
|  |       linkType: "direct", | ||
|  |       /* optional settings */ | ||
|  |       extensions: ['.xlsx', '.xls', '.numbers'], // list of extensions | ||
|  | 
 | ||
|  |       /* event handlers */ | ||
|  |       cancel: () => setMsg("User Canceled Selection!"), | ||
|  |       success: async(files) => { | ||
|  |         /* get file entry -- note that dropbox API always passes an array */ | ||
|  |         var file = files[0]; | ||
|  |         setMsg(`Selected ${file.name} ID=${file.id}`); | ||
|  | 
 | ||
|  |         /* fetch file and parse */ | ||
|  |         var wb = XLSX.read(await (await fetch(file.link)).arrayBuffer()); | ||
|  | 
 | ||
|  |         /* convert first sheet to HTML table and add to page */ | ||
|  |         tbl.current.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); | ||
|  |       } | ||
|  |     }); | ||
|  |     /* add button to page */ | ||
|  |     btn.current.appendChild(button); | ||
|  |   }, []); | ||
|  |   return ( <><b>{msg}</b><br/><div ref={btn}/><div ref={tbl}/></> ); | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Writing Files | ||
|  | 
 | ||
|  | :::caution | ||
|  | 
 | ||
|  | The Dropbox API was not designed for writing files that are created in the web | ||
|  | browser.  The Data URI approach is a neat workaround but should not be used in | ||
|  | production for larger files.  It is better to create the files in the server | ||
|  | using NodeJS and generate a proper URL for Dropbox to fetch. | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | "Saver" is a small library that lets users save files to their account. | ||
|  | 
 | ||
|  | ### Live Demo | ||
|  | 
 | ||
|  | The file must be written before the Save button is created. Unfortunately the | ||
|  | API does not accept data in the POST body, so the workaround is to create a data | ||
|  | URI by writing with the `base64` type and prepending the URI metadata. | ||
|  | 
 | ||
|  | This demo seeds data by fetching a file and writing to HTML table. The generated | ||
|  | table is scraped to create a new workbook that is written to XLS. | ||
|  | 
 | ||
|  | If the live demo shows a message about `Dropbox` being undefined, please reload | ||
|  | this demo page. | ||
|  | 
 | ||
|  | ```jsx live | ||
|  | function SheetJSEnregistrez() { | ||
|  |   const [msg, setMsg] = React.useState("Press the button to write XLS file"); | ||
|  |   const btn = useRef(), tbl = useRef(); | ||
|  |   React.useEffect(async() => { | ||
|  |     /* fetch data and write table (sample data) */ | ||
|  |     const f = await(await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); | ||
|  |     const wb = XLSX.read(f); | ||
|  |     tbl.current.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); | ||
|  | 
 | ||
|  |     /* create workbook from table */ | ||
|  |     const table = tbl.current.getElementsByTagName("TABLE")[0]; | ||
|  |     const new_wb = XLSX.utils.table_to_book(table); | ||
|  | 
 | ||
|  |     /* write XLS workbook (Base64 string) */ | ||
|  |     const b64 = XLSX.write(new_wb, { type: "base64", bookType: "xls" }); | ||
|  | 
 | ||
|  |     /* create data URI */ | ||
|  |     const url = "data:application/vnd.ms-excel;base64," + b64; | ||
|  | 
 | ||
|  |     /* create save button using the concise function call */ | ||
|  |     var button = Dropbox.createSaveButton( url, "SheetJSDropbox.xls", { | ||
|  |       success: () => setMsg("File saved successfully!"), | ||
|  |       cancel: () => setMsg("User Canceled Selection!"), | ||
|  |     }); | ||
|  |     /* add button to page */ | ||
|  |     btn.current.appendChild(button); | ||
|  |   }, []); | ||
|  |   return ( <><b>{msg}</b><br/><div ref={btn}/><div ref={tbl}/></> ); | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | ## Dropbox App | ||
|  | 
 | ||
|  | This demo requires a "Dropbox app": | ||
|  | 
 | ||
|  | 0) Create a Dropbox app through the Developer tools.  For this demo: | ||
|  | 
 | ||
|  | - "Choose an APU": "Scoped access" | ||
|  | - "Choose the type of access you need": "Full Dropbox" | ||
|  | - "Name": (enter any name) "SheetJS Docs" | ||
|  | 
 | ||
|  | :::caution | ||
|  | 
 | ||
|  | The Dropbox API Terms and Conditions should be reviewed before acceptance. | ||
|  | 
 | ||
|  | ::: | ||
|  | 
 | ||
|  | 1) Configure the Dropbox app in the Developer tools. | ||
|  | 
 | ||
|  | The following permissions should be selected in the "Permissions" tab | ||
|  | 
 | ||
|  | - `files.metadata.write` (View and edit information about your Dropbox files and folders) | ||
|  | - `files.metadata.read` (View information about your Dropbox files and folders) | ||
|  | - `files.content.write` (Edit content of your Dropbox files and folders) | ||
|  | - `files.content.read` (View content of your Dropbox files and folders) | ||
|  | 
 | ||
|  | In the settings tab, under "Chooser / Saver / Embedder domains", the desired | ||
|  | public domains should be added. `localhost` must also be added for development | ||
|  | use (it is not automatically enabled). | ||
|  | 
 |