From 073f8a3be3d510348a6ecbe55c062437d3013614 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Mon, 13 Nov 2023 06:17:25 -0500 Subject: [PATCH] dta --- docz/docs/03-demos/01-frontend/02-vue.md | 130 ++++++++++++++++--- docz/docs/03-demos/04-static/09-nuxtjs.md | 11 +- docz/docs/03-demos/06-desktop/01-electron.md | 2 +- docz/docs/03-demos/06-desktop/03-wails.md | 2 +- docz/docs/03-demos/32-extensions/10-stata.md | 9 +- docz/docs/03-demos/42-engines/21-boa.md | 2 +- docz/docs/12-constellation/21-dta.md | 90 +++++++++++++ docz/docusaurus.config.js | 2 +- docz/static/dta/dta.min.js | 2 + docz/static/dta/pres.dta | Bin 0 -> 595 bytes 10 files changed, 229 insertions(+), 21 deletions(-) create mode 100644 docz/docs/12-constellation/21-dta.md create mode 100644 docz/static/dta/dta.min.js create mode 100644 docz/static/dta/pres.dta diff --git a/docz/docs/03-demos/01-frontend/02-vue.md b/docz/docs/03-demos/01-frontend/02-vue.md index fd70559..6f33d35 100644 --- a/docz/docs/03-demos/01-frontend/02-vue.md +++ b/docz/docs/03-demos/01-frontend/02-vue.md @@ -345,16 +345,23 @@ function exportFile() { ``` -
How to run the example (click to show) +
How to run the example (click to hide) -:::note + + -This demo was last run on 2023 August 27 using `vue@3.3.4`. When running -`npm init`, the package `create-vue@3.7.3` was installed. +:::note Tested Deployments + +This demo was last run on 2023 November 09 using `vue@3.3.8`. When running +`npm init`, the package `create-vue@3.8.0` was installed. ::: -1) Run `npm init vue@latest -- sheetjs-vue --default`. +1) Create a new site: + +```bash +npm init vue@latest -- sheetjs-vue --default +``` 2) Install the SheetJS dependency and start the dev server: @@ -373,7 +380,7 @@ The page will refresh and show a table with an Export button. Click the button and the page will attempt to download `SheetJSVueAoA.xlsx`. There may be a delay since Vite will try to optimize the SheetJS library on the fly. -5) Build the site: +5) Stop the dev server and build the site: ```bash npm run build @@ -390,6 +397,58 @@ npx http-server dist Access the displayed URL (typically `http://localhost:8080`) with a web browser and test the page. + + + +:::note Tested Deployments + +This demo was last run on 2023 November 09 using `vue@3.3.8`. When running +`npm init`, the package `nuxi@3.9.1` was installed. + +::: + +1) Create a new site: + +```bash +npx nuxi@latest init sheetjs-nuxt --packageManager npm --no-install --no-gitInit +``` + +2) Install the SheetJS dependency and start the dev server: + +{`\ +cd sheetjs-nuxt +npm i +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz +npm run dev`} + + +3) Open a web browser and access the displayed URL (`http://localhost:3000`) + +4) Replace `App.vue` with the `src/SheetJSVueAoO.vue` example. + +The page will refresh and show a table with an Export button. Click the button +and the page will attempt to download `SheetJSVueAoA.xlsx`. + +5) Stop the dev server and build the site: + +```bash +npm run generate +``` + +The generated site will be placed in the `dist` folder. + +6) Start a local web server: + +```bash +npx http-server .output/public/ +``` + +Access the displayed URL (typically `http://localhost:8080`) with a web browser +and test the page. + + + +
### HTML @@ -440,16 +499,23 @@ function exportFile() { ``` -
How to run the example (click to show) +
How to run the example (click to hide) -:::note + + -This demo was last run on 2023 August 27 using `vue@3.3.4`. When running -`npm init`, the package `create-vue@3.7.3` was installed. +:::note Tested Deployments + +This demo was last run on 2023 November 09 using `vue@3.3.8`. When running +`npm init`, the package `create-vue@3.8.0` was installed. ::: -1) Run `npm init vue@latest -- sheetjs-vue --default`. +1) Create a new site: + +```bash +npm init vue@latest -- sheetjs-vue --default +``` 2) Install the SheetJS dependency and start the dev server: @@ -468,7 +534,7 @@ The page will refresh and show a table with an Export button. Click the button and the page will attempt to download `SheetJSVueHTML.xlsx`. There may be a delay since Vite will try to optimize the SheetJS library on the fly. -5) Build the site: +5) Stop the dev server and build the site: ```bash npm run build @@ -485,11 +551,42 @@ npx http-server dist Access the displayed URL (typically `http://localhost:8080`) with a web browser and test the page. + + -5) Build the site: +:::note Tested Deployments + +This demo was last run on 2023 November 09 using `vue@3.3.8`. When running +`npm init`, the package `nuxi@3.9.1` was installed. + +::: + +1) Create a new site: ```bash -npm run build +npx nuxi@latest init sheetjs-nuxt --packageManager npm --no-install --no-gitInit +``` + +2) Install the SheetJS dependency and start the dev server: + +{`\ +cd sheetjs-nuxt +npm i +npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz +npm run dev`} + + +3) Open a web browser and access the displayed URL (`http://localhost:3000`) + +4) Replace `src/App.vue` with the `src/SheetJSVueHTML.vue` example. + +The page will refresh and show a table with an Export button. Click the button +and the page will attempt to download `SheetJSVueHTML.xlsx`. + +5) Stop the dev server and build the site: + +```bash +npm run generate ``` The generated site will be placed in the `dist` folder. @@ -497,12 +594,15 @@ The generated site will be placed in the `dist` folder. 6) Start a local web server: ```bash -npx http-server dist +npx http-server .output/public/ ``` Access the displayed URL (typically `http://localhost:8080`) with a web browser and test the page. + + +
### Rows and Columns diff --git a/docz/docs/03-demos/04-static/09-nuxtjs.md b/docz/docs/03-demos/04-static/09-nuxtjs.md index f74cee9..cded035 100644 --- a/docz/docs/03-demos/04-static/09-nuxtjs.md +++ b/docz/docs/03-demos/04-static/09-nuxtjs.md @@ -18,7 +18,7 @@ data from spreadsheets. This demo uses NuxtJS and SheetJS to pull data from a spreadsheet and display the content in an HTML table. -:::info pass +:::note pass There were breaking changes between VueJS 2.x and VueJS 3.x. Since many projects still use VueJS 2.x, this demo includes examples for both versions of VueJS. @@ -31,6 +31,15 @@ Content v1 (paired with VueJS 2.x and NuxtJS 2.x) The ["Nuxt Content v2"](#nuxt-content-v2) section explores "transformers" for NuxtJS Content v2 (paired with VueJS 3.x and NuxtJS 3.x) +:::info pass + +This demo focuses on server-side processing with NuxtJS and VueJS. + +The [VueJS demo](/docs/demos/frontend/vue) includes examples of NuxtJS sites +that process spreadsheets in the browser. + +::: + :::note The following deployments were tested: diff --git a/docz/docs/03-demos/06-desktop/01-electron.md b/docz/docs/03-demos/06-desktop/01-electron.md index d3de6a1..b4f312b 100644 --- a/docz/docs/03-demos/06-desktop/01-electron.md +++ b/docz/docs/03-demos/06-desktop/01-electron.md @@ -187,7 +187,7 @@ This demo was tested in the following environments: | macOS 13.5.1 | x64 | `26.1.0` | 2023-09-03 | | macOS 13.5.1 | ARM | `26.1.0` | 2023-09-03 | | Windows 10 | x64 | `26.1.0` | 2023-09-03 | -| Windows 10 | ARM | `26.1.0` | 2023-09-24 | +| Windows 11 | ARM | `26.1.0` | 2023-09-24 | | Linux (HoloOS) | x64 | `27.0.0` | 2023-10-11 | | Linux (Debian) | ARM | `26.1.0` | 2023-09-03 | diff --git a/docz/docs/03-demos/06-desktop/03-wails.md b/docz/docs/03-demos/06-desktop/03-wails.md index c5be9d8..bd5c9d5 100644 --- a/docz/docs/03-demos/06-desktop/03-wails.md +++ b/docz/docs/03-demos/06-desktop/03-wails.md @@ -291,7 +291,7 @@ async function exportFile(table_element) { ## Complete Example -:::note +:::note Tested Deployments This demo was tested in the following environments: diff --git a/docz/docs/03-demos/32-extensions/10-stata.md b/docz/docs/03-demos/32-extensions/10-stata.md index 5c4ae07..fc304b2 100644 --- a/docz/docs/03-demos/32-extensions/10-stata.md +++ b/docz/docs/03-demos/32-extensions/10-stata.md @@ -35,7 +35,14 @@ generate variables for each column. A sample Stata session is shown below: ![Stata commands](pathname:///stata/commands.png) -:::note +:::info pass + +This demo covers Stata extensions. For directly processing Stata DTA files, the +["Stata DTA Codec"](/docs/constellation/dta) works in the browser or NodeJS. + +::: + +:::note Tested Deployments This demo was last tested by SheetJS users on 2023 November 05. diff --git a/docz/docs/03-demos/42-engines/21-boa.md b/docz/docs/03-demos/42-engines/21-boa.md index f81dd5e..cc8b7c9 100644 --- a/docz/docs/03-demos/42-engines/21-boa.md +++ b/docz/docs/03-demos/42-engines/21-boa.md @@ -114,7 +114,7 @@ various SheetJS API functions. ## Complete Example -:::note +:::note Tested Deployments This demo was tested in the following deployments: diff --git a/docz/docs/12-constellation/21-dta.md b/docz/docs/12-constellation/21-dta.md new file mode 100644 index 0000000..cc765b6 --- /dev/null +++ b/docz/docs/12-constellation/21-dta.md @@ -0,0 +1,90 @@ +--- +title: Stata DTA File Processor +sidebar_label: Stata DTA Codec +hide_table_of_contents: true +--- + + + + + +:::info pass + +This discussion focuses on the Stata DTA codec. For integrating SheetJS in a +Stata extension, there is a [dedicated demo](/docs/demos/extensions/stata). + +::: + +[Stata](https://stata.com/) is a statistical software package. Econometricians +and social scientists have used Stata for data processing and statistical +analysis. Many legacy datasets are only available in Stata DTA data files. + +The SheetJS DTA Codec enables websites and automated data pipelines to integrate +data from DTA files. + +Source code and project documentation are hosted on the SheetJS git server at + + +:::caution DTA support is considered experimental. + +Great open source software grows with user tests and reports. Issues should be +reported to [the issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues). + +::: + +## Live Demo + +This demo fetches a [sample DTA file](pathname:///dta/pres.dta), parses the data +using the SheetJS DTA Codec and displays the data in an HTML table using the +`sheet_to_html` method[^1]. + +:::tip pass + +The file input element can be used to parse a file on your computer. + +**All work is performed in the web browser! Data never leaves your machine!** + +If you find any unexpected results or errors in testing, please report an issue +at [the issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues). + +::: + +```jsx live +function SheetJSDTA() { + const [__html, setHTML] = React.useState(""); + const [text, setText] = React.useState(""); + + const process = (u8) => { + try { + /* Initial Setup */ + if(typeof DTA == "undefined") return setText("ERROR: Reload this page!"); + DTA.set_utils(XLSX.utils); + + /* Parse DTA */ + const wb = DTA.parse(u8); + + /* Generate HTML */ + setHTML(XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]])); + setText(""); + } catch(e) { setText("ERROR: " + (e && e.message || e)); } + }; + + React.useEffect(() => { (async() => { + /* Fetch file */ + process(new Uint8Array(await (await fetch("/dta/pres.dta")).arrayBuffer())); + })(); }, []); + const goodstyle = { backgroundColor: "#C6EFCE", color: "#006100" }; + const badstyle = { backgroundColor: "#FFC7CE", color: "#9C0006" }; + + return ( <> + {/* Import Button */} + { + process(new Uint8Array(await e.target.files[0].arrayBuffer())); + }}/> + {text && {text}} +
+ ); +} +``` + +[^1]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output) diff --git a/docz/docusaurus.config.js b/docz/docusaurus.config.js index b67738d..1deaac8 100644 --- a/docz/docusaurus.config.js +++ b/docz/docusaurus.config.js @@ -141,7 +141,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, - additionalLanguages: [ "visual-basic", "swift", "java", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart", "wolfram", "matlab" ], + additionalLanguages: [ "visual-basic", "swift", "java", "csharp", "perl", "ruby", "cpp", "applescript", "liquid", "rust", "dart", "wolfram", "matlab", "stata" ], }, liveCodeBlock: { playgroundPosition: 'top' diff --git a/docz/static/dta/dta.min.js b/docz/static/dta/dta.min.js new file mode 100644 index 0000000..6d47997 --- /dev/null +++ b/docz/static/dta/dta.min.js @@ -0,0 +1,2 @@ +var DTA=(()=>{var O=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var j=r=>O(r,"__esModule",{value:!0});var q=(r,t)=>{for(var s in t)O(r,s,{get:t[s],enumerable:!0})},z=(r,t,s,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let c of K(t))!J.call(r,c)&&(s||c!=="default")&&O(r,c,{get:()=>t[c],enumerable:!(e=I(t,c))||e.enumerable});return r};var H=(r=>(t,s)=>r&&r.get(t)||(s=z(j({}),t,1),r&&r.set(t,s),s))(typeof WeakMap!="undefined"?new WeakMap:0);var re={};q(re,{parse:()=>te,set_utils:()=>Q});var k;function Q(r){k=r}function W(r){return new DataView(r.buffer,r.byteOffset,r.byteLength)}function i(r,t){return r.str.slice(r.ptr,r.ptr+t.length)!=t?!1:(r.ptr+=t.length,!0)}function X(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);r.ptr=s+t.length}function p(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);let e=r.raw.slice(r.ptr,s),c={ptr:0,raw:e,str:r.str.slice(r.ptr,s),dv:W(e)};return r.ptr=s+t.length,c}function F(r,t){r.ptr+=8;let s=r.dv.getFloat64(r.ptr-8,t);return s>8988e304?null:s}function R(r,t){r.ptr+=4;let s=r.dv.getFloat32(r.ptr-4,t);return s>1701e35?null:s}function g(r,t){return r.ptr+=4,r.dv.getUint32(r.ptr-4,t)}function V(r,t){r.ptr+=4;let s=r.dv.getInt32(r.ptr-4,t);return s>2147483620?null:s}function P(r,t){return r.ptr+=2,r.dv.getUint16(r.ptr-2,t)}function C(r,t){r.ptr+=2;let s=r.dv.getInt16(r.ptr-2,t);return s>32740?null:s}function x(r){return r.raw[r.ptr++]}function G(r){let t=r.raw[r.ptr++];return t=t<128?t:t-256,t>100?null:t}var Y=["117","118"];function Z(r){let t="Not a DTA file",s=new TextDecoder("latin1").decode(r),e={ptr:0,raw:r,str:s,dv:W(r)},c=118,n=!0,b=0,S=0,$=0,D=0,M="",A="",T=[],d=[],h=[];if(!i(e,""))throw t;{if(!i(e,"
"))throw t;{if(!i(e,""))throw t;let o=p(e,"");if(Y.indexOf(o.str)==-1)throw`Unsupported DTA ${o.str} file`;c=+o.str}{if(!i(e,""))throw t;let o=p(e,"");switch(o.str){case"MSF":n=!1;break;case"LSF":n=!0;break;default:throw`Unsupported byteorder ${o.str}`}}{if(!i(e,""))throw t;let o=p(e,"");b=P(o,n)}{if(!i(e,""))throw t;let o=p(e,"");if(c==117)S=$=g(o,n);else{let a=g(o,n),l=g(o,n);S=n?($=a)+(D=l)*Math.pow(2,32):($=l)+(D=a)*Math.pow(2,32)}S>1e6&&console.error("More than 1 million observations -- extra rows will be dropped")}{if(!i(e,""),a=c>=118?2:1,l=a==1?x(o):P(o,n);if(l+a!=o.str.length)throw`Expected string length ${l} but actual length was ${o.str.length-a}`;l>0&&(M=new TextDecoder().decode(o.raw.slice(a)))}{if(!i(e,""))throw t;let o=p(e,""),a=x(o);if(a+1!=o.str.length)throw`Expected string length ${a} but actual length was ${o.str.length-1}`;a>0&&(A=o.str.slice(1))}if(!i(e,"
"))throw t}{if(!i(e,""))throw t;X(e,"")}let f=0;{if(!i(e,""))throw t;let o=p(e,"");if(o.raw.length!=2*b)throw`Expected variable_types length ${b*2}, found ${o.raw.length}`;for(;o.ptr=1&&a<=2045)f+=a;else switch(a){case 32768:f+=8;break;case 65526:f+=8;break;case 65527:f+=4;break;case 65528:f+=4;break;case 65529:f+=2;break;case 65530:f+=1;break;default:throw`Unsupported field type ${a}`}}}{if(!i(e,""))throw t;let o=p(e,""),a=c>=118?129:33;if(o.raw.length!=a*b)throw`Expected variable_types length ${b*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=p(e,"");if(o.raw.length!=2*b+2)throw`Expected sortlist length ${b*2+2}, found ${o.raw.length}`}{if(!i(e,""))throw t;let o=p(e,""),a=c>=118?57:49;if(o.raw.length!=a*b)throw`Expected formats length ${b*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=c>=118?129:33,a=p(e,"")}{if(!i(e,""))throw t;let o=c>=118?321:81,a=p(e,"")}{if(!i(e,""))throw t;for(;e.str.slice(e.ptr,e.ptr+4)=="";){e.ptr+=4;let o=g(e,n);if(e.ptr+=o,!i(e,""))throw t}if(!i(e,""))throw t}let _=k.aoa_to_sheet([d],{dense:!0});var U=[];{if(!i(e,""))throw t;for(let o=0;o=1&&u<=2045){let w=new TextDecoder().decode(e.raw.slice(e.ptr,e.ptr+u));w=w.replace(/\x00[\s\S]*/,""),a[l]=w,e.ptr+=u}else switch(u){case 65526:a[l]=F(e,n);break;case 65527:a[l]=R(e,n);break;case 65528:a[l]=V(e,n);break;case 65529:a[l]=C(e,n);break;case 65530:a[l]=G(e);break;case 32768:a[l]="##SheetJStrL##",U.push([o+1,l,e.raw.slice(e.ptr,e.ptr+8)]),e.ptr+=8;break;default:throw`Unsupported field type ${u} for ${d[l]}`}}k.sheet_add_aoa(_,[a],{origin:-1,sheetStubs:!0})}if(!i(e,""))throw t}{if(!i(e,""))throw t;let o=[];for(;e.raw[e.ptr]==71;){if(!i(e,"GSO"))throw t;let a=g(e,n),l=0;if(c==117)l=g(e,n);else{let v=g(e,n),m=g(e,n);l=n?v+m*Math.pow(2,32):m+v*Math.pow(2,32),l>1e6&&console.error("More than 1 million observations -- data will be dropped")}let u=x(e),w=g(e,n);o[l]||(o[l]=[]);let y="";u==129?(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+w)),e.ptr+=w):(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+w)).replace(/\x00$/,""),e.ptr+=w),o[l][a]=y}if(!i(e,""))throw t;U.forEach(([a,l,u])=>{let w=W(u),y=0,v=0;switch(c){case 117:y=w.getUint32(0,n),v=w.getUint32(4,n);break;case 118:case 120:{y=w.getUint16(0,n);let m=w.getUint16(2,n),E=w.getUint32(4,n);v=n?m+E*65536:E+m*2**32}break;case 119:case 121:{let m=w.getUint16(0,n),E=u[2];y=n?m+(E<<16):E+(m<<8);let B=u[3],L=w.getUint32(4,n);v=n?B+L*256:L+B*2**32}}_["!data"][a][l].v=o[v][y]})}{if(!i(e,""))throw t;let o=p(e,"")}if(!i(e,"
"))throw t;let N=k.book_new();return k.book_append_sheet(N,_,"Sheet1"),N}function ee(r){let t=r[0];switch(t){case 102:case 112:throw`Unsupported DTA ${t} file`;case 103:case 104:case 105:case 108:case 110:case 111:case 113:case 114:case 115:break;default:throw new Error("Not a DTA file")}let s={ptr:1,raw:r,str:"",dv:W(r)},e=!0,c=0,n=0,b="",S="",$=[],D=[],M=[];{let d=x(s);switch(d){case 1:e=!1;break;case 2:e=!0;break;default:throw`DTA ${t} Unexpected byteorder ${d}`}let h=x(s);if(h!=1)throw`DTA ${t} Unexpected filetype ${h}`;s.ptr++,c=P(s,e),n=g(s,e),s.ptr+=t>=108?81:32,t>=105&&(s.ptr+=18)}{let d=0;for(d=0;d=110?33:9;for(d=0;d=114?49:t>=105?12:7;for(d=0;d=110?33:9)*c}if(s.ptr+=(t>=106?81:32)*c,t>=105)for(;s.ptr=111?g:P)(s,e);if(d==0&&h==0)break;s.ptr+=h}let A=k.aoa_to_sheet([D],{dense:!0});for(let d=0;d=111&&_>=1&&_<=244){let U=new TextDecoder().decode(s.raw.slice(s.ptr,s.ptr+_));U=U.replace(/\x00[\s\S]*/,""),h[f]=U,s.ptr+=_}else switch(_){case 251:case 98:h[f]=G(s);break;case 252:case 105:h[f]=C(s,e);break;case 253:case 108:h[f]=V(s,e);break;case 254:case 102:h[f]=R(s,e);break;case 255:case 100:h[f]=F(s,e);break;default:throw`Unsupported field type ${_} for ${D[f]}`}}k.sheet_add_aoa(A,[h],{origin:-1,sheetStubs:!0})}let T=k.book_new();return k.book_append_sheet(T,A,"Sheet1"),T}function te(r){if(r[0]>=102&&r[0]<=115)return ee(r);if(r[0]===60)return Z(r);throw new Error("Not a DTA file")}return H(re);})(); +//# sourceMappingURL=dta.min.js.map diff --git a/docz/static/dta/pres.dta b/docz/static/dta/pres.dta new file mode 100644 index 0000000000000000000000000000000000000000..7fafb0cc2f1948e616cd122f8d294ada76beadbf GIT binary patch literal 595 zcmXS7Vq{=qU}c~IFfdYZNljKTGB7k!Ffg$)GGO5O>zA0Diq|U7yp+@myehzws)k0z zgjFG_0BX=PNJkPFWkN&1DKjTW!8s>0uOvTD3n=EEnqQQj8m{0}TAZN`