| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: HTTP Uploads | 
					
						
							|  |  |  | pagination_prev: demos/net/network/index | 
					
						
							|  |  |  | pagination_next: demos/net/server/index | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <head> | 
					
						
							| 
									
										
										
										
											2024-01-17 20:22:38 +00:00
										 |  |  |   <script src="https://unpkg.com/axios@1.6.5/dist/axios.min.js"></script> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  |   <script src="https://unpkg.com/superagent@8.1.2/dist/superagent.min.js"></script> | 
					
						
							|  |  |  | </head> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import current from '/version.js'; | 
					
						
							|  |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Browsers and other platforms offer solutions for uploading files to servers and | 
					
						
							|  |  |  | cloud storage solutions. Spreadsheets can be written using SheetJS and uploaded. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo explores file uploads using a number of browser APIs and wrapper | 
					
						
							|  |  |  | libraries. The upload process will generate a sample XLSX workbook, upload the | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | file to [a test server](https://s2c.sheetjs.com), and display the response. | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :::info pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo focuses on uploading files. Other demos cover other HTTP use cases: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - ["HTTP Downloads"](/docs/demos/net/network) covers downloading files | 
					
						
							|  |  |  | - ["HTTP Server Processing"](/docs/demos/net/server) covers HTTP servers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution Third-Party Hosts and Binary Data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Third-party cloud platforms such as AWS may corrupt raw binary uploads by | 
					
						
							|  |  |  | encoding requests and responses in UTF-8 strings. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For AWS, in the "Binary Media Types" section of the API Gateway console, the | 
					
						
							|  |  |  | `"multipart/form-data"` type should be added to ensure that AWS Lambda functions | 
					
						
							|  |  |  | can receive uploads from clients. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Uploading Binary Data
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `write` method[^1] generates file data stored in `ArrayBuffer` | 
					
						
							|  |  |  | objects. The `ArrayBuffer` can be added to a `FormData` object. The `FormData` | 
					
						
							|  |  |  | object can be passed along to POST requests. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | flowchart LR | 
					
						
							|  |  |  |   subgraph SheetJS operations | 
					
						
							|  |  |  |     wb(((SheetJS\nWorkbook))) | 
					
						
							|  |  |  |     ab(XLSX Data\nArrayBuffer) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   file(File\nobject) | 
					
						
							|  |  |  |   form(FormData\nobject) | 
					
						
							|  |  |  |   server[[Server\nrecipient]] | 
					
						
							|  |  |  |   wb --> |`write`\n\n| ab | 
					
						
							|  |  |  |   ab --> |new\n\n| file | 
					
						
							|  |  |  |   file --> |new\nappend\n| form | 
					
						
							|  |  |  |   form --> |POST\nrequest| server | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ### Generating Files
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In a typical scenario, a process generates arrays of simple objects. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `json_to_sheet` method[^2] generates a SheetJS worksheet object[^3]. | 
					
						
							|  |  |  | The `book_new` method[^4] creates a workbook object that includes the worksheet. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `write` method[^5] generates the file in memory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The following snippet creates a sample dataset and generates an `ArrayBuffer` | 
					
						
							|  |  |  | object representing the workbook bytes: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="Generating an XLSX file in memory" | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | var ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | var wb = XLSX.utils.book_new(ws, "Sheet1"); | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Creating Form Data
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `File` objects represent files. The `File` constructor accepts an array of data | 
					
						
							|  |  |  | fragments and a filename. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Browser APIs typically represent form body data using `FormData` objects. The | 
					
						
							|  |  |  | `append` method adds fields to the `FormData` object. Adding `File` objects | 
					
						
							|  |  |  | effectively "attaches" a file in the upload. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The following snippet constructs a new `FormData` object. The `file` field in | 
					
						
							|  |  |  | the form will be set to the data from the previous snippet: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="Creating Form Data and attaching the generated file" | 
					
						
							|  |  |  | /* create File */ | 
					
						
							|  |  |  | var file = new File([data], 'sheetjs.xlsx') | 
					
						
							|  |  |  | //    generated XLSX ^^^^    ^^^^^^^^^^^^ file name | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | fdata.append('file', file); | 
					
						
							|  |  |  | //            ^^^^ field name in the form body | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ### POST Request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo explores a number of APIs and libraries for making POST requests. Each | 
					
						
							|  |  |  | approach will upload data stored in `FormData` objects. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This snippet uses `XMLHttpRequest` to upload data to https://s2c.sheetjs.com: | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js title="Uploading Form Data with XMLHttpRequest" | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | /* send data using XMLHttpRequest */ | 
					
						
							|  |  |  | var req = new XMLHttpRequest(); | 
					
						
							|  |  |  | req.open("POST", "https://s2c.sheetjs.com", true); | 
					
						
							|  |  |  | req.send(fdata); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Browser Demos
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When the upload button is clicked, the browser will build up a new workbook, | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | generate a XLSX file, upload it to https://s2c.sheetjs.com and show the | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | response. If the process was successful, a HTML table will be displayed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note Tested Deployments | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-17 20:22:38 +00:00
										 |  |  | Each browser demo was tested in the following environments: | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-24 00:30:01 +00:00
										 |  |  | | Browser      | Date       | | 
					
						
							|  |  |  | |:-------------|:-----------| | 
					
						
							|  |  |  | | Chromium 133 | 2025-03-30 | | 
					
						
							|  |  |  | | Safari 18.3  | 2025-03-30 | | 
					
						
							|  |  |  | | Konqueror 22 | 2025-04-23 | | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | #### Test Server
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | The https://s2c.sheetjs.com service is currently hosted on Deno Deploy. The | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ["Deno Deploy" demo](/docs/demos/cloud/deno#demo) covers the exact steps for | 
					
						
							|  |  |  | deploying the service. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The CORS-enabled service handles POST requests by looking for uploaded files in | 
					
						
							|  |  |  | the `"file"` key. If a file is found, the file will be parsed using the SheetJS | 
					
						
							|  |  |  | `read` method[^6] and the first worksheet will be converted to HTML using the | 
					
						
							|  |  |  | `sheet_to_html` method[^7]. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-17 20:22:38 +00:00
										 |  |  | ### XMLHttpRequest
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | Using the `XMLHttpRequest` API, the `send` method can accept `FormData` objects: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="Uploading Form Data with XMLHttpRequest" | 
					
						
							|  |  |  | /* send data using XMLHttpRequest */ | 
					
						
							|  |  |  | var req = new XMLHttpRequest(); | 
					
						
							|  |  |  | req.open("POST", "https://s2c.sheetjs.com", true); | 
					
						
							|  |  |  | req.send(fdata); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Code Snippet</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJS + XMLHttpRequest example" | 
					
						
							|  |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | // field name ^^^^           file name ^^^^^^^^^^^^ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* send data using XMLHttpRequest */ | 
					
						
							|  |  |  | var req = new XMLHttpRequest(); | 
					
						
							|  |  |  | req.open("POST", "https://s2c.sheetjs.com", true); | 
					
						
							|  |  |  | req.send(fdata); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							| 
									
										
										
										
											2024-01-17 20:22:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live demo</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This demo starts from an array of arrays of data. When the button is clicked, a | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | workbook file will be generated and uploaded to https://s2c.sheetjs.com. The | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | service will return a HTML table. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSXHRUL() { | 
					
						
							|  |  |  |   const [__html, setHTML] = React.useState(""); | 
					
						
							|  |  |  |   const [sz, setSz] = React.useState(0); | 
					
						
							|  |  |  |   const [csv, setCSV] = React.useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* raw data */ | 
					
						
							|  |  |  |   const aoa = [ | 
					
						
							|  |  |  |     ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |     [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  |   /* target URL */ | 
					
						
							|  |  |  |   const url = "https://s2c.sheetjs.com"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Fetch and update HTML */ | 
					
						
							|  |  |  |   const xport = React.useCallback(async() => { try { | 
					
						
							|  |  |  |     /* Make SheetJS Workbook from data */ | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Export to XLSX */ | 
					
						
							|  |  |  |     const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  |     setSz(data.length || data.byteLength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Make FormData */ | 
					
						
							|  |  |  |     const fdata = new FormData(); | 
					
						
							|  |  |  |     fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Upload */ | 
					
						
							|  |  |  |     /* - create XMLHttpRequest */ | 
					
						
							|  |  |  |     const req = new XMLHttpRequest(); | 
					
						
							|  |  |  |     req.open("POST", url, true); | 
					
						
							|  |  |  |     /* - on success, display the contents */ | 
					
						
							|  |  |  |     req.onload = (e) => setHTML(req.responseText); | 
					
						
							|  |  |  |     /* - on error, display "Request failed" */ | 
					
						
							|  |  |  |     req.onerror = (e) => setHTML("Request failed"); | 
					
						
							|  |  |  |     /* - send data */ | 
					
						
							|  |  |  |     req.send(fdata); | 
					
						
							|  |  |  |   } catch(e) { setHTML(e && e.message || e); } }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Display data in CSV form */ | 
					
						
							|  |  |  |   React.useEffect(() => { | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     setCSV(XLSX.utils.sheet_to_csv(ws)); | 
					
						
							|  |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( <pre><b>CSV Data</b><div>{csv}</div> | 
					
						
							|  |  |  |     {sz ? ( <> | 
					
						
							|  |  |  |       <b>Generated file size: {sz} bytes</b> | 
					
						
							|  |  |  |       <div dangerouslySetInnerHTML={{ __html }}/> | 
					
						
							|  |  |  |     </> ) : (<button onClick={xport}><b>Export and Upload!</b></button>)} | 
					
						
							|  |  |  |   </pre> ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### fetch
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `fetch` takes a second parameter which allows for setting POST request body: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ```js title="Uploading Form Data with fetch" | 
					
						
							|  |  |  | /* send data using fetch */ | 
					
						
							|  |  |  | fetch("https://s2c.sheetjs.com", { method: "POST", body: fdata }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Code Snippet</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJS + fetch example" | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | // field name ^^^^           file name ^^^^^^^^^^^^ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* send data using fetch */ | 
					
						
							|  |  |  | fetch("https://s2c.sheetjs.com", { method: "POST", body: fdata }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live demo</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This demo uses `fetch` to upload data to https://s2c.sheetjs.com.  It will parse | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | the workbook and return an HTML table. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSFetchUL() { | 
					
						
							|  |  |  |   const [__html, setHTML] = React.useState(""); | 
					
						
							|  |  |  |   const [sz, setSz] = React.useState(0); | 
					
						
							|  |  |  |   const [csv, setCSV] = React.useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* raw data */ | 
					
						
							|  |  |  |   const aoa = [ | 
					
						
							|  |  |  |     ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |     [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  |   /* target URL */ | 
					
						
							|  |  |  |   const url = "https://s2c.sheetjs.com"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Fetch and update HTML */ | 
					
						
							|  |  |  |   const xport = React.useCallback(async() => { try { | 
					
						
							|  |  |  |     /* Make SheetJS Workbook from data */ | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Export to XLSX */ | 
					
						
							|  |  |  |     const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  |     setSz(data.length || data.byteLength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Make FormData */ | 
					
						
							|  |  |  |     const fdata = new FormData(); | 
					
						
							|  |  |  |     fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Upload */ | 
					
						
							|  |  |  |     const res = await fetch(url, {method:"POST", body: fdata}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Show Server Response */ | 
					
						
							|  |  |  |     setHTML((await res.text())); | 
					
						
							|  |  |  |   } catch(e) { setHTML(e && e.message || e); }}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Display data in CSV form */ | 
					
						
							|  |  |  |   React.useEffect(() => { | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     setCSV(XLSX.utils.sheet_to_csv(ws)); | 
					
						
							|  |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (<pre><b>CSV Data</b><div>{csv}</div> | 
					
						
							|  |  |  |     {sz ? ( <> | 
					
						
							|  |  |  |       <b>Generated file size: {sz} bytes</b> | 
					
						
							|  |  |  |       <div dangerouslySetInnerHTML={{ __html }}/> | 
					
						
							|  |  |  |     </> ) : (<button onClick={xport}><b>Export and Upload!</b></button>)} | 
					
						
							|  |  |  |   </pre>); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Wrapper Libraries
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Before `fetch` shipped with browsers, there were various wrapper libraries to | 
					
						
							|  |  |  | simplify `XMLHttpRequest`.  Due to limitations with `fetch`, these libraries | 
					
						
							|  |  |  | are still relevant. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### axios
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [`axios`](https://axios-http.com/) presents a Promise based interface. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Uploading form data is nearly identical to the `fetch` example: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ```js title="Uploading Form Data with axios" | 
					
						
							|  |  |  | /* send data using axios */ | 
					
						
							|  |  |  | axios("https://s2c.sheetjs.com", { method: "POST", body: fdata }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Code Snippet</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJS + axios example" | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | // field name ^^^^           file name ^^^^^^^^^^^^ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* send data using axios */ | 
					
						
							|  |  |  | axios("https://s2c.sheetjs.com", { method: "POST", data: fdata }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live demo</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This demo uses `axios` to upload data to https://s2c.sheetjs.com.  It will parse | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | the workbook and return an HTML table. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the live demo shows a message | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | ReferenceError: axios is not defined | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | please refresh the page.  This is a known bug in the documentation generator. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSAxiosUL() { | 
					
						
							|  |  |  |   const [__html, setHTML] = React.useState(""); | 
					
						
							|  |  |  |   const [sz, setSz] = React.useState(0); | 
					
						
							|  |  |  |   const [csv, setCSV] = React.useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* raw data */ | 
					
						
							|  |  |  |   const aoa = [ | 
					
						
							|  |  |  |     ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |     [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  |   /* target URL */ | 
					
						
							|  |  |  |   const url = "https://s2c.sheetjs.com"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Fetch and update HTML */ | 
					
						
							|  |  |  |   const xport = React.useCallback(async() => { try { | 
					
						
							|  |  |  |     /* Make SheetJS Workbook from data */ | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Export to XLSX */ | 
					
						
							|  |  |  |     const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  |     setSz(data.length || data.byteLength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Make FormData */ | 
					
						
							|  |  |  |     const fdata = new FormData(); | 
					
						
							|  |  |  |     fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Upload */ | 
					
						
							|  |  |  |     const res = await axios(url, {method:"POST", data: fdata}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Show Server Response */ | 
					
						
							|  |  |  |     setHTML(res.data); | 
					
						
							|  |  |  |   } catch(e) { setHTML(e && e.message || e); }}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Display data in CSV form */ | 
					
						
							|  |  |  |   React.useEffect(() => { | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     setCSV(XLSX.utils.sheet_to_csv(ws)); | 
					
						
							|  |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (<pre><b>CSV Data</b><div>{csv}</div> | 
					
						
							|  |  |  |     {sz ? ( <> | 
					
						
							|  |  |  |       <b>Generated file size: {sz} bytes</b> | 
					
						
							|  |  |  |       <div dangerouslySetInnerHTML={{ __html }}/> | 
					
						
							|  |  |  |     </> ) : (<button onClick={xport}><b>Export and Upload!</b></button>)} | 
					
						
							|  |  |  |   </pre>); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### superagent
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-17 20:22:38 +00:00
										 |  |  | [`superagent`](https://ladjs.github.io/superagent/) is a network request library | 
					
						
							|  |  |  | with a "Fluent Interface". | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The `send` method accepts a `FormData` object as the first argument: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ```js title="Uploading Form Data with superagent" | 
					
						
							|  |  |  | /* send data using superagent */ | 
					
						
							|  |  |  | superagent.post("https://s2c.sheetjs.com").send(fd); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Code Snippet</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJS + superagent example" | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | // field name ^^^^           file name ^^^^^^^^^^^^ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* send data (fd is the FormData object) */ | 
					
						
							|  |  |  | superagent.post("https://s2c.sheetjs.com").send(fd); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live demo</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This demo uses `superagent` to upload data to https://s2c.sheetjs.com.  It will | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | parse the workbook and return an HTML table. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the live demo shows a message | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | ReferenceError: superagent is not defined | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | please refresh the page.  This is a known bug in the documentation generator. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSSuperAgentUL() { | 
					
						
							|  |  |  |   const [__html, setHTML] = React.useState(""); | 
					
						
							|  |  |  |   const [sz, setSz] = React.useState(0); | 
					
						
							|  |  |  |   const [csv, setCSV] = React.useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* raw data */ | 
					
						
							|  |  |  |   const aoa = [ | 
					
						
							|  |  |  |     ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |     [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  |   /* target URL */ | 
					
						
							|  |  |  |   const url = "https://s2c.sheetjs.com"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Fetch and update HTML */ | 
					
						
							|  |  |  |   const xport = React.useCallback(async() => { try { | 
					
						
							|  |  |  |     /* Make SheetJS Workbook from data */ | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Export to XLSX */ | 
					
						
							|  |  |  |     const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  |     setSz(data.length || data.byteLength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Make FormData */ | 
					
						
							|  |  |  |     const fdata = new FormData(); | 
					
						
							|  |  |  |     fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Upload */ | 
					
						
							|  |  |  |     superagent.post(url).send(fdata).end((err, res) => { | 
					
						
							|  |  |  |       /* Show Server Response */ | 
					
						
							|  |  |  |       setHTML(res.text); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } catch(e) { setHTML(e && e.message || e); }}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Display data in CSV form */ | 
					
						
							|  |  |  |   React.useEffect(() => { | 
					
						
							|  |  |  |     const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  |     setCSV(XLSX.utils.sheet_to_csv(ws)); | 
					
						
							|  |  |  |   }, []); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (<pre><b>CSV Data</b><div>{csv}</div> | 
					
						
							|  |  |  |     {sz ? ( <> | 
					
						
							|  |  |  |       <b>Generated file size: {sz} bytes</b> | 
					
						
							|  |  |  |       <div dangerouslySetInnerHTML={{ __html }}/> | 
					
						
							|  |  |  |     </> ) : (<button onClick={xport}><b>Export and Upload!</b></button>)} | 
					
						
							|  |  |  |   </pre>); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## NodeJS Demos
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 04:47:57 +00:00
										 |  |  | These examples show how to upload data in NodeJS scripts. | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### fetch
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | NodeJS `fetch`, available in version 20, mirrors the [browser `fetch`](#fetch). | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :::note Tested Deployments | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | This demo was tested in the following environments: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | NodeJS     | Date       | | 
					
						
							|  |  |  | |:-----------|:-----------| | 
					
						
							| 
									
										
										
										
											2025-01-11 05:52:44 +00:00
										 |  |  | | `22.13.0`  | 2025-01-08 | | 
					
						
							|  |  |  | | `20.18.1`  | 2025-01-08 | | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This demo uses `fetch` to upload data to https://s2c.sheetjs.com.  It will parse | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | the workbook and return data in CSV rows. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Install the [SheetJS NodeJS module](/docs/getting-started/installation/nodejs): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <CodeBlock language="bash">{`\ | 
					
						
							|  |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) Save the following to `SheetJSFetch.js`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJSFetch.js" | 
					
						
							|  |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* build FormData with the generated file */ | 
					
						
							|  |  |  | var fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | // field name ^^^^           file name ^^^^^^^^^^^^ | 
					
						
							|  |  |  | fdata.append('type', 'csv'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (async() => { | 
					
						
							|  |  |  |   /* send data using fetch */ | 
					
						
							|  |  |  |   const res = await fetch("https://s2c.sheetjs.com", { method: "POST", body: fdata }); | 
					
						
							|  |  |  |   const txt = await res.text(); | 
					
						
							|  |  |  |   console.log(txt); | 
					
						
							|  |  |  | })(); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Run the script: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | node SheetJSFetch.js | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It will print CSV contents of the test file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | ### request
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The deprecated [`request`](https://github.com/request/request) library is useful | 
					
						
							|  |  |  | in legacy NodeJS deployments where `fetch` may not be available. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS `write` method will generate NodeJS Buffer objects when the `type` | 
					
						
							|  |  |  | option is set to `"buffer"`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | const data = XLSX.write(wb, {bookType: 'xlsx', type: 'buffer'}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A `request` file object can be built using the Buffer. The file object must | 
					
						
							|  |  |  | include an `options` object that specifies the file name and content type: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* create a file object for the `request` form data */ | 
					
						
							|  |  |  | const request_file = { | 
					
						
							|  |  |  |   /* `value` can be a Buffer object */ | 
					
						
							|  |  |  |   value: data, | 
					
						
							|  |  |  |   options: { | 
					
						
							|  |  |  |     /* `options.filename` is the filename that the server will see */ | 
					
						
							|  |  |  |     filename: "sheetjs.xlsx", | 
					
						
							|  |  |  |     /* `options.contentType` must be set */ | 
					
						
							|  |  |  |     contentType: "application/octet-stream" | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `request` and `request.post` methods accept an options argument. The | 
					
						
							|  |  |  | `formData` property specifies the body to be uploaded. Property names correspond | 
					
						
							|  |  |  | to the uploaded form names and values describe the uploaded content. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `request` file object should be added to the `formData` object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | request({ | 
					
						
							|  |  |  |   // ... other options ... | 
					
						
							|  |  |  |   formData: { | 
					
						
							|  |  |  |     // ... other form fields ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* the server will see the uploaded file in the `file` body property */ | 
					
						
							|  |  |  |     /* highlight-next-line */ | 
					
						
							|  |  |  |     file: request_file | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }, function(err, res) { /* handle response ... */ }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note Tested Deployments | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo was tested in the following environments: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | NodeJS     | `request` | Date       | | 
					
						
							|  |  |  | |:-----------|:----------|:-----------| | 
					
						
							| 
									
										
										
										
											2025-01-11 05:52:44 +00:00
										 |  |  | | `22.13.0`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `20.18.1`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `18.20.5`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `16.20.2`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `14.21.3`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `12.22.12` | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `10.24.1`  | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `8.17.0`   | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `6.17.1`   | `2.88.2`  | 2025-01-08 | | 
					
						
							|  |  |  | | `4.9.1`    | `2.81.0`  | 2025-01-08 | | 
					
						
							|  |  |  | | `0.12.18`  | `2.81.0`  | 2025-01-08 | | 
					
						
							|  |  |  | | `0.10.48`  | `2.81.0`  | 2025-01-08 | | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Complete Example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | This demo uses `request` to upload data to https://s2c.sheetjs.com. It will | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | parse the workbook and return data in CSV rows. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Install the [SheetJS NodeJS module](/docs/getting-started/installation/nodejs) | 
					
						
							|  |  |  | and `request` module: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <CodeBlock language="bash">{`\ | 
					
						
							|  |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz request`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-11 05:52:44 +00:00
										 |  |  | :::note pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The current version of `request` requires NodeJS 6 or later. For older versions | 
					
						
							|  |  |  | of NodeJS, `request` version `2.81.0` should be installed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | 2) Save the following to `SheetJSRequest.js`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="SheetJSRequest.js" | 
					
						
							|  |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | const request = require("request"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* create sample SheetJS workbook object */ | 
					
						
							|  |  |  | var aoa = [ | 
					
						
							|  |  |  |   ["S", "h", "e", "e", "t", "J", "S"], | 
					
						
							|  |  |  |   [  5,   4,   3,   3,   7,   9,   5] | 
					
						
							|  |  |  | ]; | 
					
						
							|  |  |  | const ws = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | const wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* export SheetJS workbook object to XLSX file bytes */ | 
					
						
							|  |  |  | var data = XLSX.write(wb, {bookType: 'xlsx', type: 'buffer'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | request({ | 
					
						
							|  |  |  |   method: "POST", | 
					
						
							|  |  |  |   url: "https://s2c.sheetjs.com", | 
					
						
							|  |  |  |   headers: { | 
					
						
							|  |  |  |     Accept: "text/html" | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  |   formData: { | 
					
						
							|  |  |  |     type: "csv", | 
					
						
							|  |  |  |     file: { | 
					
						
							|  |  |  |       value: data, | 
					
						
							|  |  |  |       options: { | 
					
						
							|  |  |  |         filename: "sheetjs.xlsx", | 
					
						
							|  |  |  |         contentType: "application/octet-stream" | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }, function(err, res, body) { | 
					
						
							|  |  |  |   if(err) return console.error(err); | 
					
						
							|  |  |  |   console.log(body); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Run the script: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | node SheetJSRequest.js | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It will print CSV contents of the test file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For legacy versions of NodeJS, the process may fail with a certificate error: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | { [Error: certificate not trusted] code: 'CERT_UNTRUSTED' } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The environment variable `NODE_TLS_REJECT_UNAUTHORIZED` can be set to `0`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | env NODE_TLS_REJECT_UNAUTHORIZED="0" node SheetJSRequest.js | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **It is strongly recommended to upgrade to a newer version of NodeJS!** | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							| 
									
										
										
										
											2023-11-20 02:51:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Troubleshooting
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Some SheetJS users have reported corrupted files. To diagnose the error, it is | 
					
						
							|  |  |  | strongly recommended to write local files. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For example, using `fetch` in the browser, the bytes can be downloaded using the | 
					
						
							|  |  |  | [HTML5 Download Attribute](/docs/demos/local/file#html5-download-attribute). The | 
					
						
							|  |  |  | highlighted lines should be added immediately after `write`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="Diagnosing issues in a fetch upload" | 
					
						
							|  |  |  | /* Generate XLSX file */ | 
					
						
							|  |  |  | const data = XLSX.write(wb, {bookType: 'xlsx', type: 'array'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // highlight-start | 
					
						
							|  |  |  | /* Write to Local File */ | 
					
						
							|  |  |  | const blob = new Blob([data]); | 
					
						
							|  |  |  | const url = URL.createObjectURL(blob); | 
					
						
							|  |  |  | const a = document.createElement("a"); | 
					
						
							|  |  |  | a.download = "SheetJS.xlsx"; | 
					
						
							|  |  |  | a.href = url; | 
					
						
							|  |  |  | document.body.appendChild(a); | 
					
						
							|  |  |  | a.click(); | 
					
						
							|  |  |  | document.body.removeChild(a); | 
					
						
							|  |  |  | // highlight-end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Make FormData */ | 
					
						
							|  |  |  | const fdata = new FormData(); | 
					
						
							|  |  |  | fdata.append('file', new File([data], 'sheetjs.xlsx')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Upload */ | 
					
						
							|  |  |  | const url = "https://s2c.sheetjs.com"; | 
					
						
							|  |  |  | const res = await fetch(url, {method:"POST", body: fdata}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the generated file is valid, then the issue is in the server infrastructure. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [^1]: See [`write` in "Writing Files"](/docs/api/write-options) | 
					
						
							| 
									
										
										
										
											2024-04-08 03:55:10 +00:00
										 |  |  | [^2]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input) | 
					
						
							|  |  |  | [^3]: See ["Worksheet Object" in "SheetJS Data Model"](/docs/csf/sheet) for more details. | 
					
						
							|  |  |  | [^4]: See [`book_new` in "Utilities"](/docs/api/utilities/wb) | 
					
						
							|  |  |  | [^5]: See [`write` in "Writing Files"](/docs/api/write-options) | 
					
						
							|  |  |  | [^6]: See [`read` in "Reading Files"](/docs/api/parse-options) | 
					
						
							|  |  |  | [^7]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output) |