diff --git a/docz/docs/03-demos/07-data/02-storageapi.md b/docz/docs/03-demos/07-data/02-storageapi.md index 66e0b2f..e8bc88c 100644 --- a/docz/docs/03-demos/07-data/02-storageapi.md +++ b/docz/docs/03-demos/07-data/02-storageapi.md @@ -72,7 +72,7 @@ function localStorage_to_sheet() { :::note -This demo was last tested on 2023 February 26. +This demo was last tested on 2023 April 09. ::: @@ -141,7 +141,7 @@ array of pairs. Consider the following data in Local Storage: |:---:|:----------| | "b" | "Logical" | | "n" | "Numeric" | -| "s" | "Textual" | +| "s" | "Textual" | The natural representation is an array of arrays: @@ -155,6 +155,13 @@ The natural representation is an array of arrays: #### Exporting Storage +:::note + +Web Storage iteration order is not defined. By using indices as keys, the row +objects approach has an ordering. That does not apply to the general case. + +::: + In modern browsers, `Object.entries` will generate an array of key/value pairs. `XLSX.utils.aoa_to_sheet` will interpret that array as a worksheet with 2 cols: @@ -177,3 +184,50 @@ function ws_to_localStorage(ws) { aoa.forEach(([key, val]) => localStorage.setItem(key, val)); } ``` + +### Live Demo + +:::note + +This demo was last tested on 2023 April 09. + +::: + +This example fills `localStorage` with 10 random keys and 10 random values, +generates a worksheet from the data and writes to a new file. + +```jsx live +function SheetJSRandomStorage() { + const [out, setOut] = React.useState(""); + const [rows, setRows] = React.useState([]); + const xport = React.useCallback(async() => { + // reset and populate localStorage + localStorage.clear(); + var data = []; + for(let i = 0, last = 0; i < 10; ++i) { + var k = ((Math.random() * 20)|0) + last; + var v = (Math.random() * 16777216).toString(36); + localStorage.setItem(k, v); + data.push([k,v]); + last = k; + } + setRows(Object.entries(localStorage)); + + // create new worksheet from localStorage + const aoa = Object.entries(localStorage); + const new_ws = XLSX.utils.aoa_to_sheet(aoa); + + // create and export workbook + const new_wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(new_wb, new_ws, "Sheet1"); + XLSX.writeFile(new_wb, "SheetJSRandomStorage.xlsx"); + }); + return ( <> + {out && ( <>{url}
{out}> )}
+    {rows.length && (| Key | Value | 
|---|---|
| {k} | {v} | 
URL: {url}
Import: {q1}
Export: {q2}
+    | Index | Nom | 
|---|---|
| {Index} | {Nom} | 
{`\
+{
+  /* add this part before "name" */
+  /* highlight-start */
+  "overrides": {
+    "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
+  },
+  /* highlight-end */
+  "name": "my-project",
+  /* ... more fields ... */
+`}
+"+ln(t)+"
";return s}function bn(e,t,s){var n;s<=0||(n=(t-e.scrollTop)/s*10,setTimeout(function(){e.scrollTop!==t&&(e.scrollTop=e.scrollTop+n,bn(e,t,s-10))},10))}function En(b,e,E,g,m,T){var S={};function A(e){return e&&!1===L.options.casesensitive?e.toLowerCase():e}E=E||{},L.utils.extend(S,E),void 0===S.headers&&(S.headers=!0),e=L.utils.autoExtFilename(e,"xls",E),L.utils.loadBinaryFile(e,!!g,function(e){t=e instanceof ArrayBuffer?(r=function(e){for(var t="",s=0,n=10240;s"+L.pretty(e)+"[ ]
";else if("object"!=typeof s[0]||Array.isArray(s[0]))for(var i=0,o=s.length;i'+(Date.now()-e)+" ms
")}catch(e){L.write(""+L.useid+"> "+t+"
"),L.write(''+e+"
")}}e=r.getBoundingClientRect().top+document.getElementsByTagName("body")[0].scrollTop;bn(document.getElementsByTagName("body")[0],e,500),r.onkeydown=function(e){if(13===e.which){var t=r.value,s=L.useid;r.value="",L.prompthistory.push(t),i=L.prompthistory.length;try{var n=Date.now();L.log(t),L.write('
'+(Date.now()-n)+" ms
")}catch(e){L.write(""+s+"> "+L.pretty(t,!1)+"
"),L.write(''+e+"
")}r.focus(),a.textContent=L.useid;n=r.getBoundingClientRect().top+document.getElementsByTagName("body")[0].scrollTop;bn(document.getElementsByTagName("body")[0],n,500)}else 38===e.which?(--i<0&&(i=0),L.prompthistory[i]&&(r.value=L.prompthistory[i],e.preventDefault())):40===e.which&&(++i>=L.prompthistory.length?(i=L.prompthistory.length,r.value=""):L.prompthistory[i]&&(r.value=L.prompthistory[i],e.preventDefault()))}},M.BeginTransaction=function(e){return Object.assign(this,e)},M.BeginTransaction.prototype.toString=function(){return"BEGIN TRANSACTION"},M.BeginTransaction.prototype.execute=function(e,t,s){return L.databases[e].engineid?L.engines[L.databases[L.useid].engineid].begin(e,s):(s&&s(1),1)},M.CommitTransaction=function(e){return Object.assign(this,e)},M.CommitTransaction.prototype.toString=function(){return"COMMIT TRANSACTION"},M.CommitTransaction.prototype.execute=function(e,t,s){return L.databases[e].engineid?L.engines[L.databases[L.useid].engineid].commit(e,s):(s&&s(1),1)},M.RollbackTransaction=function(e){return Object.assign(this,e)},M.RollbackTransaction.prototype.toString=function(){return"ROLLBACK TRANSACTION"},M.RollbackTransaction.prototype.execute=function(e,t,s){return L.databases[e].engineid?L.engines[L.databases[e].engineid].rollback(e,s):(s&&s(1),1)},L.options.tsql&&(L.stdfn.OBJECT_ID=function(e,t){t=(t=void 0===t?"T":t).toUpperCase();var s,e=e.split("."),n=L.useid,r=e[0],a=(2==e.length&&(n=e[0],r=e[1]),L.databases[n].tables),n=L.databases[n].databaseid;for(s in a)if(s==r)return(!a[s].view||"V"!=t)&&(a[s].view||"T"!=t)?void 0:n+"."+s}),L.options.mysql&&(L.fn.TIMESTAMPDIFF=function(e,t,s){return L.stdfn.DATEDIFF(e,t,s)}),(L.options.mysql||L.options.sqlite)&&(L.from.INFORMATION_SCHEMA=function(e,t,s,n,r){if("VIEWS"!=e&&"TABLES"!=e)throw new Error("Unknown INFORMATION_SCHEMA table");var a,i=[];for(a in L.databases){var o,u=L.databases[a].tables;for(o in u)(u[o].view&&"VIEWS"==e||!u[o].view&&"TABLES"==e)&&i.push({TABLE_CATALOG:a,TABLE_NAME:o})}return i=s?s(i,n,r):i}),L.options.postgres,L.options.oracle,L.options.sqlite,L.into.SQL=function(e,t,s,n,r){"object"==typeof e&&(t=e,e=void 0);var a={};if(L.utils.extend(a,t),void 0===a.tableid)throw new Error("Table for INSERT TO is not defined.");var i="";0===n.length&&"object"==typeof s[0]&&(n=Object.keys(s[0]).map(function(e){return{columnid:e}}));for(var o=0,u=s.length;o",void 0!==h.caption&&(e=h.caption,l+="
")+"",s.forEach(function(e,t){l+=" ");l+="",t&&0",void 0!==e.title&&("function"==typeof e.title?l+=e.title(h,e,t):l+=e.title),l+=" "}),l+="",s.forEach(function(e,t){var s={},n=(Fs(s,h.cell),Fs(s,u.cell),void 0!==h.column&&Fs(s,h.column.cell),Fs(s,e.cell),h.cells&&h.cells[o]&&h.cells[o][t]&&Fs(s,h.cells[o][t]),i[e.columnid]),r=("function"==typeof s.value&&(n=s.value(n,h,i,e,s,o,t)),s.typeid),a=(void 0===(r="function"==typeof r?r(n,h,i,e,s,o,t):r)&&("number"==typeof n?r="number":"string"==typeof n?r="string":"boolean"==typeof n?r="boolean":"object"==typeof n&&n instanceof Date&&(r="date")),""),a=("money"==r?a='mso-number-format:"\\#\\,\\#\\#0\\\\ _р_\\.";white-space:normal;':"number"==r?a=" ":"date"==r?a='mso-number-format:"Short Date";':c.types&&c.types[r]&&c.types[r].typestyle&&(a=c.types[r].typestyle),l+=" ")});return l=(l+="",s.format);if(void 0===n)l+="";else if(void 0!==a)if("function"==typeof a)l+=a(n);else{if("string"!=typeof a)throw new Error("Unknown format type. Should be function or string");l+=n}else l+="number"==r||"date"==r?n.toString():"money"==r?(+n).toFixed(2):n;l+=" "}),l+="