| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | # XMLHttpRequest and fetch
 | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | `XMLHttpRequest` and `fetch` browser APIs enable binary data transfer between | 
					
						
							|  |  |  | web browser clients and web servers.  Since this library works in web browsers, | 
					
						
							|  |  |  | server conversion work can be offloaded to the client!  This demo shows a few | 
					
						
							|  |  |  | common scenarios involving browser APIs and popular wrapper libraries. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | ## Demos
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The included demos focus on an editable table.  There are two separate flows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - When the page is accessed, the browser will attempt to download `sheetjs.xlsx` | 
					
						
							|  |  |  |   and read the workbook.  The old table will be replaced with an editable table | 
					
						
							|  |  |  |   whose contents match the first worksheet.  The table is generated using the | 
					
						
							|  |  |  |   `sheet_to_html` utility with `editable:true` option | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - When the upload button is clicked, the browser will generate a new worksheet | 
					
						
							|  |  |  |   using `table_to_book` and build up a new workbook.  It will then attempt to | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  |   generate a file and upload it to the server. | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### Demo Server
 | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `server.js` nodejs server serves static files on `GET` request.  On a `POST` | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  | request to `/upload`, the server processes the body and looks for uploaded file. | 
					
						
							|  |  |  | It will write the data for the first file to the indicated file name. | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | To start the demo, run `npm start` and navigate to <http://localhost:7262/> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ## XMLHttpRequest
 | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | For downloading data, the `arraybuffer` response type generates an `ArrayBuffer` | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | that can be viewed as an `Uint8Array` and fed to `XLSX.read` using `array` type: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* set up an async GET request */ | 
					
						
							|  |  |  | var req = new XMLHttpRequest(); | 
					
						
							|  |  |  | req.open("GET", url, true); | 
					
						
							|  |  |  | req.responseType = "arraybuffer"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | req.onload = function(e) { | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  |   /* parse the data when it is received */ | 
					
						
							|  |  |  |   var data = new Uint8Array(req.response); | 
					
						
							|  |  |  |   var workbook = XLSX.read(data, {type:"array"}); | 
					
						
							|  |  |  |   /* DO SOMETHING WITH workbook HERE */ | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | req.send(); | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  | For uploading data, this demo populates a `FormData` object with an ArrayBuffer | 
					
						
							|  |  |  | generated with the `array` output type: | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  | /* generate XLSX as array buffer */ | 
					
						
							|  |  |  | var data = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'}); | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fd = new FormData(); | 
					
						
							| 
									
										
										
										
											2018-03-13 02:51:54 +00:00
										 |  |  | fd.append('data', new File([data], 'sheetjs.xlsx')); | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* send data */ | 
					
						
							|  |  |  | var req = new XMLHttpRequest(); | 
					
						
							|  |  |  | req.open("POST", "/upload", true); | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | req.send(fd); | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | ### superagent Wrapper Library
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `superagent` library usage mirrors XHR: | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ```js | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | /* set up an async GET request with superagent */ | 
					
						
							|  |  |  | superagent.get(url).responseType('arraybuffer').end(function(err, res) { | 
					
						
							|  |  |  |   /* parse the data when it is received */ | 
					
						
							|  |  |  |   var data = new Uint8Array(res.body); | 
					
						
							|  |  |  |   var workbook = XLSX.read(data, {type:"array"}); | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  |   /* DO SOMETHING WITH workbook HERE */ | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | The upload portion only differs in the actual request command: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* send data (fd is the FormData object) */ | 
					
						
							|  |  |  | superagent.post("/upload").send(fd); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-03 20:46:32 +00:00
										 |  |  | ### axios Wrapper Library
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `axios` library presents a Promise interface.  The axios demo uses a single | 
					
						
							|  |  |  | promise, but for production deployments it may make sense to separate parsing: | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | ```js | 
					
						
							|  |  |  | /* set up an async GET request with axios */ | 
					
						
							|  |  |  | axios(url, {responseType:'arraybuffer'}).catch(function(err) { | 
					
						
							|  |  |  |   /* error in getting data */ | 
					
						
							|  |  |  | }).then(function(res) { | 
					
						
							|  |  |  |   /* parse the data when it is received */ | 
					
						
							|  |  |  |   var data = new Uint8Array(res.data); | 
					
						
							|  |  |  |   var workbook = XLSX.read(data, {type:"array"}); | 
					
						
							|  |  |  |   return workbook; | 
					
						
							|  |  |  | }).catch(function(err) { | 
					
						
							|  |  |  |   /* error in parsing */ | 
					
						
							|  |  |  | }).then(function(workbook) { | 
					
						
							|  |  |  |   /* DO SOMETHING WITH workbook HERE */ | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | The upload portion only differs in the actual request command: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* send data (fd is the FormData object) */ | 
					
						
							|  |  |  | axios("/upload", {method: "POST", data: fd}); | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## fetch
 | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | For downloading data, `response.blob()` resolves to a `Blob` object that can be | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | converted to `ArrayBuffer` using a `FileReader`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | fetch(url).then(function(res) { | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  |   /* get the data as a Blob */ | 
					
						
							|  |  |  |   if(!res.ok) throw new Error("fetch failed"); | 
					
						
							|  |  |  |   return res.blob(); | 
					
						
							|  |  |  | }).catch(function(err) { | 
					
						
							|  |  |  |   /* error in getting data */ | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | }).then(function(blob) { | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  |   /* configure a FileReader to process the blob */ | 
					
						
							|  |  |  |   var reader = new FileReader(); | 
					
						
							|  |  |  |   reader.addEventListener("loadend", function() { | 
					
						
							|  |  |  |     /* parse the data when it is received */ | 
					
						
							|  |  |  |     var data = new Uint8Array(this.result); | 
					
						
							|  |  |  |     var workbook = XLSX.read(data, {type:"array"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* DO SOMETHING WITH workbook HERE */ | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   reader.readAsArrayBuffer(blob); | 
					
						
							| 
									
										
										
										
											2017-09-12 20:02:06 +00:00
										 |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-09-05 05:26:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-24 23:40:09 +00:00
										 |  |  | The upload code is identical to `axios`, except for the variable name: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | fetch("/upload", {method: "POST", body: fd}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [](https://github.com/SheetJS/js-xlsx) |