| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | <!DOCTYPE html> | 
					
						
							| 
									
										
										
										
											2022-10-20 18:47:20 +00:00
										 |  |  |  | <!-- sheetjs (C) 2013-present  SheetJS https://sheetjs.com --> | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | <!-- vim: set ts=2: --> | 
					
						
							|  |  |  |  | <html lang="en" style="height: 100%"> | 
					
						
							|  |  |  |  | <head> | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | 
					
						
							|  |  |  |  |   <title>SheetJS React Demo</title> | 
					
						
							|  |  |  |  |   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> | 
					
						
							|  |  |  |  |   <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | 
					
						
							|  |  |  |  |   <script src="https://unpkg.com/react/umd/react.production.min.js"></script> | 
					
						
							|  |  |  |  |   <script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script> | 
					
						
							|  |  |  |  |   <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js"></script> | 
					
						
							|  |  |  |  |   <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | 
					
						
							|  |  |  |  |   <style>body, #app { height: 100%; }</style> | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | </head> | 
					
						
							|  |  |  |  | <body> | 
					
						
							| 
									
										
										
										
											2022-10-20 18:47:20 +00:00
										 |  |  |  |   <div class="container-fluid"><h1><a href="https://sheetjs.com">SheetJS × React Demo</a></h1><br /></div> | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |   <div id="app" class="container-fluid"></div> | 
					
						
							|  |  |  |  |   <script type="text/babel"> | 
					
						
							| 
									
										
										
										
											2022-10-20 18:47:20 +00:00
										 |  |  |  |     /* sheetjs (C) 2013-present  SheetJS -- https://sheetjs.com */ | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* Notes: | 
					
						
							|  |  |  |  |        - usage: `ReactDOM.render( <SheetJSApp />, document.getElementById('app') );` | 
					
						
							|  |  |  |  |        - xlsx.full.min.js is loaded in the head of the HTML page | 
					
						
							|  |  |  |  |        - this script should be referenced with type="text/babel" | 
					
						
							|  |  |  |  |        - babel.js in-browser transpiler should be loaded before this script | 
					
						
							|  |  |  |  |     */ | 
					
						
							|  |  |  |  |     const { read, writeFile } = XLSX; | 
					
						
							|  |  |  |  |     const { decode_range, encode_col, sheet_to_json, aoa_to_sheet, book_new, book_append_sheet } = XLSX.utils; | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* generate an array of column objects */ | 
					
						
							|  |  |  |  |     const make_cols = refstr => Array.from({length: decode_range(refstr).e.c + 1}, (_, i) => ({ name: encode_col(i), key: i})); | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* main component */ | 
					
						
							|  |  |  |  |     function SheetJSApp() { | 
					
						
							|  |  |  |  |       const [data, setData] = React.useState([]); | 
					
						
							|  |  |  |  |       const [cols, setCols] = React.useState([]); | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |       const handleFile = (file) => { | 
					
						
							|  |  |  |  |         const reader = new FileReader(); | 
					
						
							|  |  |  |  |         reader.onload = (e) => { | 
					
						
							|  |  |  |  |           /* Parse data */ | 
					
						
							|  |  |  |  |           const ab = e.target.result; | 
					
						
							|  |  |  |  |           const wb = read(ab, { type: 'array' }); | 
					
						
							|  |  |  |  |           /* Get first worksheet */ | 
					
						
							|  |  |  |  |           const wsname = wb.SheetNames[0]; | 
					
						
							|  |  |  |  |           const ws = wb.Sheets[wsname]; | 
					
						
							|  |  |  |  |           /* Convert array of arrays */ | 
					
						
							|  |  |  |  |           const data = sheet_to_json(ws, { header: 1 }); | 
					
						
							|  |  |  |  |           /* Update state */ | 
					
						
							|  |  |  |  |           setData(data); | 
					
						
							|  |  |  |  |           setCols(make_cols(ws['!ref'])) | 
					
						
							|  |  |  |  |         }; | 
					
						
							|  |  |  |  |         reader.readAsArrayBuffer(file); | 
					
						
							|  |  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |       const exportFile = () => { | 
					
						
							|  |  |  |  |         /* convert state to workbook */ | 
					
						
							|  |  |  |  |         const ws = aoa_to_sheet(data); | 
					
						
							|  |  |  |  |         const wb = book_new(); | 
					
						
							|  |  |  |  |         book_append_sheet(wb, ws, "SheetJS"); | 
					
						
							|  |  |  |  |         /* generate XLSX file and send to client */ | 
					
						
							|  |  |  |  |         writeFile(wb, "sheetjs.xlsx") | 
					
						
							|  |  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |       return ( | 
					
						
							|  |  |  |  |         <DragDropFile handleFile={handleFile}> | 
					
						
							|  |  |  |  |           <div className="row"><div className="col-xs-12"> | 
					
						
							|  |  |  |  |             <DataInput handleFile={handleFile} /> | 
					
						
							|  |  |  |  |           </div></div> | 
					
						
							|  |  |  |  |           <div className="row"><div className="col-xs-12"> | 
					
						
							|  |  |  |  |             {data.length ? <button className="btn btn-success" onClick={exportFile}>Export</button> : ""} | 
					
						
							|  |  |  |  |           </div></div> | 
					
						
							|  |  |  |  |           <div className="row"><div className="col-xs-12"> | 
					
						
							|  |  |  |  |             <OutTable data={data} cols={cols} /> | 
					
						
							|  |  |  |  |           </div></div> | 
					
						
							|  |  |  |  |         </DragDropFile> | 
					
						
							|  |  |  |  |       ); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* -------------------------------------------------------------------------- */ | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* | 
					
						
							|  |  |  |  |       Simple HTML5 file drag-and-drop wrapper | 
					
						
							|  |  |  |  |       usage: <DragDropFile handleFile={handleFile}>...</DragDropFile> | 
					
						
							|  |  |  |  |         handleFile(file:File):void; | 
					
						
							|  |  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     function DragDropFile({ handleFile, children }) { | 
					
						
							|  |  |  |  |       const suppress = (e) => { e.stopPropagation(); e.preventDefault(); }; | 
					
						
							|  |  |  |  |       const handleDrop = (e) => { | 
					
						
							|  |  |  |  |         e.stopPropagation(); e.preventDefault(); | 
					
						
							|  |  |  |  |         const files = e.dataTransfer.files; | 
					
						
							|  |  |  |  |         if (files && files[0]) handleFile(files[0]); | 
					
						
							|  |  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |       return ( <div onDrop={handleDrop} onDragEnter={suppress} onDragOver={suppress}>{children}</div> ); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* | 
					
						
							|  |  |  |  |       Simple HTML5 file input wrapper | 
					
						
							|  |  |  |  |       usage: <DataInput handleFile={callback} /> | 
					
						
							|  |  |  |  |         handleFile(file:File):void; | 
					
						
							|  |  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     function DataInput({ handleFile }) { | 
					
						
							|  |  |  |  |       const handleChange = (e) => { | 
					
						
							|  |  |  |  |         const files = e.target.files; | 
					
						
							|  |  |  |  |         if (files && files[0]) handleFile(files[0]); | 
					
						
							|  |  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |       return ( | 
					
						
							|  |  |  |  |         <form className="form-inline"> | 
					
						
							|  |  |  |  |           <div className="form-group"> | 
					
						
							|  |  |  |  |             <label htmlFor="file">Drag or choose a spreadsheet file</label><br /> | 
					
						
							|  |  |  |  |             <input type="file" className="form-control" id="file" accept={SheetJSFT} onChange={handleChange} /> | 
					
						
							|  |  |  |  |           </div> | 
					
						
							|  |  |  |  |         </form> | 
					
						
							|  |  |  |  |       ) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     /* list of supported file types */ | 
					
						
							|  |  |  |  |     const SheetJSFT = [ | 
					
						
							|  |  |  |  |       "xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm" | 
					
						
							|  |  |  |  |     ].map(x => `.${x}`).join(","); | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* | 
					
						
							|  |  |  |  |       Simple HTML Table | 
					
						
							|  |  |  |  |       usage: <OutTable data={data} cols={cols} /> | 
					
						
							|  |  |  |  |         data:Array<Array<any> >; | 
					
						
							|  |  |  |  |         cols:Array<{name:string, key:number|string}>; | 
					
						
							|  |  |  |  |     */ | 
					
						
							|  |  |  |  |     function OutTable({ data, cols }) { | 
					
						
							|  |  |  |  |       return ( | 
					
						
							|  |  |  |  |         <div className="table-responsive"> | 
					
						
							|  |  |  |  |           <table className="table table-striped"> | 
					
						
							|  |  |  |  |             <thead> | 
					
						
							|  |  |  |  |               <tr>{cols.map((c) => <th key={c.key}>{c.name}</th>)}</tr> | 
					
						
							|  |  |  |  |             </thead> | 
					
						
							|  |  |  |  |             <tbody> | 
					
						
							|  |  |  |  |               {data.map((r, i) => <tr key={i}> | 
					
						
							|  |  |  |  |                 {cols.map(c => <td key={c.key}>{r[c.key]}</td>)} | 
					
						
							|  |  |  |  |               </tr>)} | 
					
						
							|  |  |  |  |             </tbody> | 
					
						
							|  |  |  |  |           </table> | 
					
						
							|  |  |  |  |         </div> | 
					
						
							|  |  |  |  |       ); | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  |  |     /* React 18 uses ReactDOM.createRoot; < 18 should use ReactDOM.render */ | 
					
						
							|  |  |  |  |     const root_elt = document.getElementById('app'); | 
					
						
							|  |  |  |  |     if(typeof ReactDOM.createRoot !== "undefined") { | 
					
						
							|  |  |  |  |       const root = ReactDOM.createRoot(root_elt); | 
					
						
							|  |  |  |  |       root.render(<SheetJSApp/>); | 
					
						
							|  |  |  |  |     } else { | 
					
						
							|  |  |  |  |       ReactDOM.render(<SheetJSApp />, root_elt); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   </script> | 
					
						
							| 
									
										
										
										
											2022-08-17 07:10:01 +00:00
										 |  |  |  | </body> | 
					
						
							|  |  |  |  | </html> |