diff --git a/bits/04_base64.js b/bits/04_base64.js index 0164e3f..637bee2 100644 --- a/bits/04_base64.js +++ b/bits/04_base64.js @@ -48,9 +48,7 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64,/, '') - .replace(/[^\w\+\/\=]/g, ""); - + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, ""); for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); diff --git a/demos/README.md b/demos/README.md index c700643..1243a17 100644 --- a/demos/README.md +++ b/demos/README.md @@ -51,7 +51,7 @@ can be installed with Bash on Windows or with `cygwin`. - [`SalesForce Lightning Web Components`](https://docs.sheetjs.com/docs/getting-started/demos/salesforce) - [`Excel JavaScript API`](https://docs.sheetjs.com/docs/getting-started/demos/excel) - [`Headless Automation`](https://docs.sheetjs.com/docs/getting-started/demos/headless) -- [`Swift JSC and Other JavaScript Engines`](altjs/) +- [`Swift JSC and Other JavaScript Engines`](https://docs.sheetjs.com/docs/getting-started/demos/engines) - [`"serverless" functions`](function/) - [`Databases and Structured Data Stores`](https://docs.sheetjs.com/docs/getting-started/demos/database) - [`NoSQL, K/V, and Unstructured Data Stores`](https://docs.sheetjs.com/docs/getting-started/demos/nosql) @@ -68,9 +68,7 @@ can be installed with Bash on Windows or with `cygwin`. - [`swc`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#swc) - [`systemjs`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#systemjs) - [`vite`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#vite) -- [`webpack 2.x`](webpack/) +- [`webpack`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#webpack) - [`wmr`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#wmr) -Other examples are included in the [showcase](demos/showcase/). - [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx) diff --git a/demos/altjs/.gitignore b/demos/altjs/.gitignore deleted file mode 100644 index 6626d47..0000000 --- a/demos/altjs/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -sheetjs.* -SheetJSSwift -duk* -*.class -*.jar -rhino -shim.min.js -xlsx.*.js -payload.js -goja diff --git a/demos/altjs/.swiftlint.yml b/demos/altjs/.swiftlint.yml deleted file mode 100644 index 11856f9..0000000 --- a/demos/altjs/.swiftlint.yml +++ /dev/null @@ -1,3 +0,0 @@ -disabled_rules: - - trailing_semicolon - - identifier_name diff --git a/demos/altjs/Makefile b/demos/altjs/Makefile deleted file mode 100644 index 7fc69e0..0000000 --- a/demos/altjs/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -.PHONY: all -all: duktape nashorn rhinojs swift goja - -.PHONY: base -base: - if [ ! -e sheetjs.xlsx ]; then node ../../tests/write.js; fi - if [ ! -e xlsx.full.min.js ]; then cp ../../dist/xlsx.full.min.js .; fi - if [ ! -e shim.min.js ]; then cp ../../dist/shim.min.js .; fi - -.PHONY: duk -duk: base - bash ./duktape.sh - gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm - -.PHONY: duktape -duktape: duk ## duktape demo - for ext in xlsx xlsb biff8.xls xml.xls; do ./sheetjs.duk sheetjs.$$ext; done - -.PHONY: nashorn -nashorn: base ## nashorn demo - jjs nashorn.js - -.PHONY: swift -swift: base ## swift demo - swiftc SheetJSCore.swift main.swift -o SheetJSSwift - ./SheetJSSwift - -.PHONY: goja -goja: base ## goja demo - go build goja.go - for ext in xlsx xlsb biff8.xls xml.xls; do ./goja sheetjs.$$ext; done - -.PHONY: chakra -chakra: base ## Chakra demo - node -pe "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('sheetjs.xlsx').toString('base64') + '\";')" - cat global.js xlsx.full.min.js payload.js chakra.js > xlsx.chakra.js - chakra ./xlsx.chakra.js - -.PHONY: rhinojs ## rhino demo -rhinojs: base SheetJSRhino.class - for ext in xlsx xlsb biff8.xls xml.xls; do java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.$$ext; done - -RHDEPS=$(filter-out SheetJSRhino.class,$(patsubst %.java,%.class,$(wildcard com/sheetjs/*.java))) -$(RHDEPS): %.class: %.java rhino.jar - javac -cp .:SheetJS.jar:rhino.jar $*.java - -SheetJSRhino.class: $(RHDEPS) - jar -cf SheetJS.jar $^ xlsx.full.min.js - javac -cp .:SheetJS.jar:rhino.jar SheetJSRhino.java - -rhino.jar: - if [ ! -e rhino ]; then git clone --depth=1 https://github.com/mozilla/rhino; fi - #if [ ! -e rhino/build/rhino*/js.jar ]; then cd rhino; ant jar; fi - #cp rhino/build/rhino*/js.jar rhino.jar - if [ ! -e rhino/buildGradle/libs/rhino-[0-1]*.jar ]; then cd rhino; ./gradlew jar; fi - cp rhino/buildGradle/libs/rhino-[0-9]*.jar rhino.jar - -.PHONY: clean -clean: - rm SheetJS.jar *.class com/sheetjs/*.class diff --git a/demos/altjs/README.md b/demos/altjs/README.md index 55de233..0ba063a 100644 --- a/demos/altjs/README.md +++ b/demos/altjs/README.md @@ -1,186 +1,7 @@ # Other JS Engines and Deployments -There are many JS engines and deployments outside of web browsers. NodeJS is the -most popular deployment, but there are many others for special use cases. Some -optimize for low overhead and others optimize for ease of embedding within other -applications. Since it was designed for ES3 engines, the library can be used in -those settings! This demo tries to demonstrate a few alternative deployments. +[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/engines) +includes more detailed instructions and more JS engines. -Some engines provide no default global object. To create a global reference: - -```js -var global = (function(){ return this; }).call(null); -``` - - -## Swift + JavaScriptCore - -iOS and OSX ship with the JavaScriptCore framework for running JS scripts from -Swift and Objective-C. Hybrid function invocation is tricky, but explicit data -passing is straightforward. The demo shows a standalone example for OSX. For -playgrounds, the library should be copied to shared playground data directory -(usually `~/Documents/Shared Playground Data`): - -```swift -/* This only works in a playground, see SheetJSCore.swift for standalone use */ -import JavaScriptCore; -import PlaygroundSupport; - -/* build path variable for the library */ -let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory; -let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js"); - -/* prepare JS context */ -var context: JSContext! = JSContext(); -var src = "var global = (function(){ return this; }).call(null);"; -context.evaluateScript(src); - -/* load library */ -var lib = try? String(contentsOf: lib_path); -context.evaluateScript(lib); -let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); - -/* to verify the library was loaded, get the version string */ -let XLSXversion: JSValue! = XLSX.objectForKeyedSubscript("version") -var version = XLSXversion.toString(); -``` - -Binary strings can be passed back and forth using `String.Encoding.isoLatin1`: - -```swift -/* parse sheetjs.xls */ -let file_path = shared_dir.appendingPathComponent("sheetjs.xls"); -let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1); -context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)); -src = "var wb = XLSX.read(payload, {type:'binary'});"; -context.evaluateScript(src); - -/* write to sheetjsw.xlsx */ -let out_path = shared_dir.appendingPathComponent("sheetjsw.xlsx"); -src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})"; -context.evaluateScript(src); -let outvalue: JSValue! = context.objectForKeyedSubscript("out"); -var out: String! = outvalue.toString(); -try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1); -``` - - -## Nashorn - -Nashorn ships with Java 8. It includes a command-line tool `jjs` for running JS -scripts. It is somewhat limited but does offer access to the full Java runtime. - -The `load` function in `jjs` can load the minified source directly: - -```js -var global = (function(){ return this; }).call(null); -load('xlsx.full.min.js'); -``` - -The Java `nio` API provides the `Files.readAllBytes` method to read a file into -a byte array. To use in `XLSX.read`, the demo copies the bytes into a plain JS -array and calls `XLSX.read` with type `"array"`. - - -## Rhino - -[Rhino](http://www.mozilla.org/rhino) is an ES3+ engine written in Java. The -`SheetJSRhino` class and `com.sheetjs` package show a complete JAR deployment, -including the full XLSX source. - -Due to code generation errors, optimization must be turned off: - -```java -Context context = Context.enter(); -context.setOptimizationLevel(-1); -``` - - -## ChakraCore - -ChakraCore is an embeddable JS engine written in C++. The library and binary -distributions include a command-line tool `chakra` for running JS scripts. - -The simplest way to interact with the engine is to pass Base64 strings. The make -target builds a very simple payload with the data. - - -## Duktape - -[Duktape](http://duktape.org/) is an embeddable JS engine written in C. The -amalgamation makes integration extremely simple! It supports `Buffer` natively -but should be sliced before processing: - -```C -/* parse a C char array as a workbook object */ -duk_push_external_buffer(ctx); -duk_config_buffer(ctx, -1, buf, len); -duk_put_global_string(ctx, "buf"); -duk_eval_string_noresult("workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});"); - -/* write a workbook object to a C char array */ -duk_eval_string(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})"); -duk_size_t sz; -char *buf = (char *)duk_get_buffer_data(ctx, -1, sz); -duk_pop(ctx); -``` - - -## QuickJS - -QuickJS is an embeddable JS engine written in C. It provides a separate set of -functions for interacting with the filesystem and the global object. It can run -the browser dist build. - -The `global` object is available as `std.global`. To make it visible to the -loader, create a reference to itself: - -```js -std.global.global = std.global; -std.loadScript("xlsx.full.min.js"); -``` - -The filesystem interaction mirrors POSIX, including separate allocations: - -```js -/* read file */ -var rh = std.open(filename, "rb"); rh.seek(0, std.SEEK_END); -var sz = rh.tell(); rh.seek(); -var ab = new ArrayBuffer(sz); rh.read(ab, 0, sz); rh.close(); -var wb = XLSX.read(ab, {type: 'array'}); - -/* write file */ -var ab = XLSX.write(wb, {type: 'array'}); -var wh = std.open("sheetjs.qjs.xlsx", "wb"); -wh.write(out, 0, ab.byteLength); wh.close(); -``` - - -## Goja - -Goja is a pure Go implementation of ECMAScript 5. `[]byte` should be converted -to a binary string in the engine: - -```go -/* read file */ -data, _ := ioutil.ReadFile("sheetjs.xlsx") - -/* load into engine */ -vm.Set("buf", data) - -/* convert to binary string */ -_, _ = vm.RunString("var bstr = ''; for(var i = 0; i < buf.length; ++i) bstr += String.fromCharCode(buf[i]);") - -/* parse */ -wb, _ = vm.RunString("wb = XLSX.read(bstr, {type:'binary', cellNF:true});") -``` - -On the write side, `"base64"` strings can be decoded in Go: - -```go -b64str, _ := vm.RunString("XLSX.write(wb, {type:'base64', bookType:'xlsx'})") -buf, _ := base64.StdEncoding.DecodeString(b64str.String()) -_ = ioutil.WriteFile("sheetjs.xlsx", buf, 0644) -``` [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx) diff --git a/demos/altjs/SJSPlayground.swift b/demos/altjs/SJSPlayground.swift deleted file mode 100644 index e95cde5..0000000 --- a/demos/altjs/SJSPlayground.swift +++ /dev/null @@ -1,37 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* This only works in a playground, see SheetJSCore.swift for standalone use */ -import JavaScriptCore; -import PlaygroundSupport; - -/* build path variable for the library */ -let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory; -let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js"); - -/* prepare JS context */ -var context: JSContext! = JSContext(); -var src = "var global = (function(){ return this; }).call(null);"; -context.evaluateScript(src); - -/* load library */ -var lib = try? String(contentsOf: lib_path); -context.evaluateScript(lib); -let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); - -/* to verify the library was loaded, get the version string */ -let XLSXversion: JSValue! = XLSX.objectForKeyedSubscript("version") -var version = XLSXversion.toString(); - -/* parse sheetjs.xls */ -let file_path = shared_dir.appendingPathComponent("sheetjs.xls"); -let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1); -context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!); -src = "var wb = XLSX.read(payload, {type:'binary'});"; -context.evaluateScript(src); - -/* write to sheetjsw.xlsx */ -let out_path = shared_dir.appendingPathComponent("sheetjsw.xlsx"); -src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})"; -context.evaluateScript(src); -let outvalue: JSValue! = context.objectForKeyedSubscript("out"); -var out: String! = outvalue.toString(); -try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1); diff --git a/demos/altjs/SheetJSCore.swift b/demos/altjs/SheetJSCore.swift deleted file mode 100755 index 4f56647..0000000 --- a/demos/altjs/SheetJSCore.swift +++ /dev/null @@ -1,96 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -import JavaScriptCore; - -enum SJSError: Error { - case badJSContext; - case badJSWorkbook; - case badJSWorksheet; -}; - -class SJSWorksheet { - var context: JSContext!; - var wb: JSValue; var ws: JSValue; - var idx: Int32; - - func toCSV() throws -> String { - let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); - let utils: JSValue! = XLSX.objectForKeyedSubscript("utils"); - let sheet_to_csv: JSValue! = utils.objectForKeyedSubscript("sheet_to_csv"); - return sheet_to_csv.call(withArguments: [ws]).toString(); - } - - init(ctx: JSContext, workbook: JSValue, worksheet: JSValue, idx: Int32) throws { - self.context = ctx; self.wb = workbook; self.ws = worksheet; self.idx = idx; - } -} - -class SJSWorkbook { - var context: JSContext!; - var wb: JSValue; var SheetNames: JSValue; var Sheets: JSValue; - - func getSheetAtIndex(idx: Int32) throws -> SJSWorksheet { - let SheetName: String = SheetNames.atIndex(Int(idx)).toString(); - let ws: JSValue! = Sheets.objectForKeyedSubscript(SheetName); - return try SJSWorksheet(ctx: context, workbook: wb, worksheet: ws, idx: idx); - } - - func writeBStr(bookType: String = "xlsx") throws -> String { - let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX"); - context.evaluateScript(String(format: "var writeopts = {type:'binary', bookType:'%@'}", bookType)); - let writeopts: JSValue = context.objectForKeyedSubscript("writeopts"); - let writefunc: JSValue = XLSX.objectForKeyedSubscript("write"); - return writefunc.call(withArguments: [wb, writeopts]).toString(); - } - - init(ctx: JSContext, wb: JSValue) throws { - self.context = ctx; - self.wb = wb; - self.SheetNames = wb.objectForKeyedSubscript("SheetNames"); - self.Sheets = wb.objectForKeyedSubscript("Sheets"); - } -} - -class SheetJSCore { - var context: JSContext!; - var XLSX: JSValue!; - - func init_context() throws -> JSContext { - var context: JSContext! - do { - context = JSContext(); - context.exceptionHandler = { _, X in if let e = X { print(e.toString()!); }; }; - context.evaluateScript("var global = (function(){ return this; }).call(null);"); - context.evaluateScript("if(typeof wbs == 'undefined') wbs = [];"); - let src = try String(contentsOfFile: "xlsx.full.min.js"); - context.evaluateScript(src); - if context != nil { return context!; } - } catch { print(error.localizedDescription); } - throw SJSError.badJSContext; - } - - func version() throws -> String { - if let version = XLSX.objectForKeyedSubscript("version") { return version.toString(); } - throw SJSError.badJSContext; - } - - func readFile(file: String) throws -> SJSWorkbook { - let data: String! = try String(contentsOfFile: file, encoding: String.Encoding.isoLatin1); - return try readBStr(data: data); - } - - func readBStr(data: String) throws -> SJSWorkbook { - context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)); - context.evaluateScript("var wb = XLSX.read(payload, {type:'binary'});"); - let wb: JSValue! = context.objectForKeyedSubscript("wb"); - if wb == nil { throw SJSError.badJSWorkbook; } - return try SJSWorkbook(ctx: context, wb: wb); - } - - init() throws { - do { - self.context = try init_context(); - self.XLSX = self.context.objectForKeyedSubscript("XLSX"); - if self.XLSX == nil { throw SJSError.badJSContext; } - } catch { print(error.localizedDescription); } - } -} diff --git a/demos/altjs/SheetJSRhino.java b/demos/altjs/SheetJSRhino.java deleted file mode 100644 index 75bf980..0000000 --- a/demos/altjs/SheetJSRhino.java +++ /dev/null @@ -1,31 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -import com.sheetjs.SheetJS; -import com.sheetjs.SheetJSFile; -import com.sheetjs.SheetJSSheet; - -public class SheetJSRhino { - public static void main(String args[]) throws Exception { - try { - SheetJS sjs = new SheetJS(); - - /* open file */ - SheetJSFile xl = sjs.read_file(args[0]); - - /* get sheetnames */ - String[] sheetnames = xl.get_sheet_names(); - System.err.println(sheetnames[0]); - - /* convert to CSV */ - SheetJSSheet sheet = xl.get_sheet(0); - String csv = sheet.get_csv(); - - System.out.println(csv); - - } catch(Exception e) { - throw e; - } finally { - SheetJS.close(); - } - } -} diff --git a/demos/altjs/chakra.js b/demos/altjs/chakra.js deleted file mode 100644 index 7f9f8c1..0000000 --- a/demos/altjs/chakra.js +++ /dev/null @@ -1,3 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var wb = XLSX.read(payload, {type:'base64'}); -console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])); diff --git a/demos/altjs/com/sheetjs/JSHelper.java b/demos/altjs/com/sheetjs/JSHelper.java deleted file mode 100644 index c8dcec0..0000000 --- a/demos/altjs/com/sheetjs/JSHelper.java +++ /dev/null @@ -1,51 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -package com.sheetjs; - -import java.lang.Integer; -import java.lang.StringBuilder; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.NativeArray; -import org.mozilla.javascript.NativeObject; -import org.mozilla.javascript.Scriptable; - -public class JSHelper { - static String read_file(String file) throws IOException { - byte[] b = Files.readAllBytes(Paths.get(file)); - System.out.println(b.length); - StringBuilder sb = new StringBuilder(); - for(int i = 0; i < b.length; ++i) sb.append(Character.toString((char)(b[i] < 0 ? b[i] + 256 : b[i]))); - return sb.toString(); - } - - static Object get_object(String path, Object base) throws ObjectNotFoundException { - int idx = path.indexOf("."); - Scriptable b = (Scriptable)base; - if(idx == -1) return b.get(path, b); - Object o = b.get(path.substring(0,idx), b); - if(o == Scriptable.NOT_FOUND) throw new ObjectNotFoundException("not found: |" + path.substring(0,idx) + "|" + Integer.toString(idx)); - return get_object(path.substring(idx+1), (NativeObject)o); - } - - static Object[] get_array(String path, Object base) throws ObjectNotFoundException { - NativeArray arr = (NativeArray)get_object(path, base); - Object[] out = new Object[(int)arr.getLength()]; - int idx; - for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr); - return out; - } - - static String[] get_string_array(String path, Object base) throws ObjectNotFoundException { - NativeArray arr = (NativeArray)get_object(path, base); - String[] out = new String[(int)arr.getLength()]; - int idx; - for(Object o : arr.getIds()) out[idx = (Integer)o] = arr.get(idx, arr).toString(); - return out; - } - - public static void close() { Context.exit(); } - -} diff --git a/demos/altjs/com/sheetjs/ObjectNotFoundException.java b/demos/altjs/com/sheetjs/ObjectNotFoundException.java deleted file mode 100644 index 1116922..0000000 --- a/demos/altjs/com/sheetjs/ObjectNotFoundException.java +++ /dev/null @@ -1,10 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -package com.sheetjs; - -import java.lang.Exception; - -public class ObjectNotFoundException extends Exception { - public ObjectNotFoundException() {} - public ObjectNotFoundException(String message) { super(message); } -} diff --git a/demos/altjs/com/sheetjs/SheetJS.java b/demos/altjs/com/sheetjs/SheetJS.java deleted file mode 100644 index 01def4b..0000000 --- a/demos/altjs/com/sheetjs/SheetJS.java +++ /dev/null @@ -1,58 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -package com.sheetjs; - -import java.lang.Integer; -import java.util.Scanner; -import java.io.IOException; -import java.io.File; -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Function; -import org.mozilla.javascript.NativeObject; -import org.mozilla.javascript.Scriptable; - -public class SheetJS { - public Scriptable scope; - public Context cx; - public NativeObject nXLSX; - - public SheetJS() throws Exception { - this.cx = Context.enter(); - this.scope = this.cx.initStandardObjects(); - - /* boilerplate */ - cx.setOptimizationLevel(-1); - String s = "var global = (function(){ return this; }).call(null);"; - cx.evaluateString(scope, s, "", 1, null); - - /* eval library */ - s = new Scanner(SheetJS.class.getResourceAsStream("/xlsx.full.min.js")).useDelimiter("\\Z").next(); - //s = new Scanner(new File("xlsx.full.min.js")).useDelimiter("\\Z").next(); - cx.evaluateString(scope, s, "", 1, null); - - /* grab XLSX variable */ - Object XLSX = scope.get("XLSX", scope); - if(XLSX == Scriptable.NOT_FOUND) throw new Exception("XLSX not found"); - this.nXLSX = (NativeObject)XLSX; - } - - public SheetJSFile read_file(String filename) throws IOException, ObjectNotFoundException { - /* open file */ - String d = JSHelper.read_file(filename); - - /* options argument */ - NativeObject q = (NativeObject)this.cx.evaluateString(this.scope, "q = {'type':'binary', 'WTF':1};", "", 2, null); - - /* set up function arguments */ - Object args[] = {d, q}; - - /* call read -> wb workbook */ - Function readfunc = (Function)JSHelper.get_object("XLSX.read",this.scope); - NativeObject wb = (NativeObject)readfunc.call(this.cx, this.scope, this.nXLSX, args); - - return new SheetJSFile(wb, this); - } - - public static void close() { JSHelper.close(); } -} - diff --git a/demos/altjs/com/sheetjs/SheetJSFile.java b/demos/altjs/com/sheetjs/SheetJSFile.java deleted file mode 100644 index dcc0e08..0000000 --- a/demos/altjs/com/sheetjs/SheetJSFile.java +++ /dev/null @@ -1,24 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -package com.sheetjs; - -import org.mozilla.javascript.NativeObject; -import org.mozilla.javascript.Function; - -public class SheetJSFile { - public NativeObject wb; - public SheetJS sheetjs; - public SheetJSFile() {} - public SheetJSFile(NativeObject wb, SheetJS sheetjs) { this.wb = wb; this.sheetjs = sheetjs; } - public String[] get_sheet_names() { - try { - return JSHelper.get_string_array("SheetNames", this.wb); - } catch(ObjectNotFoundException e) { - return null; - } - } - public SheetJSSheet get_sheet(int idx) throws ObjectNotFoundException { - return new SheetJSSheet(this, idx); - } -} - diff --git a/demos/altjs/com/sheetjs/SheetJSSheet.java b/demos/altjs/com/sheetjs/SheetJSSheet.java deleted file mode 100644 index a99ab03..0000000 --- a/demos/altjs/com/sheetjs/SheetJSSheet.java +++ /dev/null @@ -1,29 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* vim: set ts=2: */ -package com.sheetjs; - -import org.mozilla.javascript.Function; -import org.mozilla.javascript.NativeObject; - -public class SheetJSSheet { - public NativeObject ws; - public SheetJSFile wb; - public SheetJSSheet(SheetJSFile wb, int idx) throws ObjectNotFoundException { - this.wb = wb; - this.ws = (NativeObject)JSHelper.get_object("Sheets." + wb.get_sheet_names()[idx],wb.wb); - } - public String get_range() throws ObjectNotFoundException { - return JSHelper.get_object("!ref",this.ws).toString(); - } - public String get_string_value(String address) throws ObjectNotFoundException { - return JSHelper.get_object(address + ".v",this.ws).toString(); - } - - public String get_csv() throws ObjectNotFoundException { - Function csvify = (Function)JSHelper.get_object("XLSX.utils.sheet_to_csv",this.wb.sheetjs.scope); - Object csvArgs[] = {this.ws}; - Object csv = csvify.call(this.wb.sheetjs.cx, this.wb.sheetjs.scope, this.wb.sheetjs.scope, csvArgs); - return csv.toString(); - } -} - diff --git a/demos/altjs/duktape.sh b/demos/altjs/duktape.sh deleted file mode 100755 index d0b5f81..0000000 --- a/demos/altjs/duktape.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -DUKTAPE_VER=2.6.0 -if [ ! -e duktape-$DUKTAPE_VER ]; then - if [ ! -e duktape-$DUKTAPE_VER.tar ]; then - if [ ! -e duktape-$DUKTAPE_VER.tar.xz ]; then - curl -O https://duktape.org/duktape-$DUKTAPE_VER.tar.xz - fi - xz -d duktape-$DUKTAPE_VER.tar.xz - fi - tar -xf duktape-$DUKTAPE_VER.tar -fi - -for f in duktape.{c,h} duk_config.h; do - cp duktape-$DUKTAPE_VER/src/$f . -done - diff --git a/demos/altjs/global.js b/demos/altjs/global.js deleted file mode 100644 index 00bae5d..0000000 --- a/demos/altjs/global.js +++ /dev/null @@ -1,3 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var global = (function(){ return this; }).call(null); - diff --git a/demos/altjs/goja.go b/demos/altjs/goja.go deleted file mode 100644 index 6b29202..0000000 --- a/demos/altjs/goja.go +++ /dev/null @@ -1,71 +0,0 @@ -package main - -import ( - b64 "encoding/base64" - "fmt" - "os" - "io/ioutil" - "github.com/dop251/goja" -) - -func safe_run_file(vm *goja.Runtime, file string) { - data, err := ioutil.ReadFile(file) - if err != nil { panic(err) } - src := string(data) - _, err = vm.RunString(src) - if err != nil { panic(err) } -} - -func eval_string(vm *goja.Runtime, cmd string) goja.Value { - v, err := vm.RunString(cmd) - if err != nil { panic(err) } - return v -} - -func write_type(vm *goja.Runtime, t string) { - /* due to some wonkiness with array passing, use base64 */ - b64str := eval_string(vm, "XLSX.write(wb, {type:'base64', bookType:'" + t + "'})") - buf, err := b64.StdEncoding.DecodeString(b64str.String()); - if err != nil { panic(err) } - err = ioutil.WriteFile("sheetjsg." + t, buf, 0644) - if err != nil { panic(err) } -} - -func main() { - vm := goja.New() - - /* initialize */ - eval_string(vm, "if(typeof global == 'undefined') global = (function(){ return this; }).call(null);") - - /* load library */ - safe_run_file(vm, "shim.min.js") - safe_run_file(vm, "xlsx.full.min.js") - - /* get version string */ - v := eval_string(vm, "XLSX.version") - fmt.Printf("SheetJS library version %s\n", v) - - /* read file */ - data, err := ioutil.ReadFile(os.Args[1]) - if err != nil { panic(err) } - vm.Set("buf", data) - fmt.Printf("Loaded file %s\n", os.Args[1]) - - /* parse workbook */ - eval_string(vm, "var bstr = ''; for(var i = 0; i < buf.length; ++i) bstr += String.fromCharCode(buf[i]);") - eval_string(vm, "wb = XLSX.read(bstr, {type:'binary', cellNF:true});") - eval_string(vm, "ws = wb.Sheets[wb.SheetNames[0]]") - - /* print CSV */ - csv := eval_string(vm, "XLSX.utils.sheet_to_csv(ws)") - fmt.Printf("%s\n", csv) - - /* change cell A1 to 3 */ - eval_string(vm, "ws['A1'].v = 3; delete ws['A1'].w;") - - /* write file */ - //write_type(vm, "xlsb") - //write_type(vm, "xlsx") - write_type(vm, "xls") - write_type(vm, "csv") -} diff --git a/demos/altjs/main.swift b/demos/altjs/main.swift deleted file mode 100755 index 24b278a..0000000 --- a/demos/altjs/main.swift +++ /dev/null @@ -1,21 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ - -let sheetjs = try SheetJSCore(); - -try print(sheetjs.version()); - -let filenames: [[String]] = [ - ["xlsx", "xlsx"], - ["xlsb", "xlsb"], - ["biff8.xls", "xls"], - ["xml.xls", "xlml"] -]; - -for fn in filenames { - let wb: SJSWorkbook = try sheetjs.readFile(file: "sheetjs." + fn[0]); - let ws: SJSWorksheet = try wb.getSheetAtIndex(idx: 0); - let csv: String = try ws.toCSV(); - print(csv); - let wbout: String = try wb.writeBStr(bookType: fn[1]); - try wbout.write(toFile: "sheetjsswift." + fn[0], atomically: false, encoding: String.Encoding.isoLatin1); -} diff --git a/demos/altjs/nashorn.js b/demos/altjs/nashorn.js deleted file mode 100644 index a17fa13..0000000 --- a/demos/altjs/nashorn.js +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env jjs -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ - -/* load module */ -var global = (function(){ return this; }).call(null); -load('xlsx.full.min.js'); - -/* helper to convert byte array to plain JS array */ -function b2a(b) { - var out = new Array(b.length); - for(var i = 0; i < out.length; i++) out[i] = (b[i] < 0 ? b[i] + 256 : b[i]); - return out; -} - -function process_file(path) { - java.lang.System.out.println(path); - - /* read file */ - var path = java.nio.file.Paths.get(path); - var bytes = java.nio.file.Files.readAllBytes(path); - var u8a = b2a(bytes); - - /* read data */ - var wb = XLSX.read(u8a, {type:"array"}); - - /* get first worksheet as an array of arrays */ - var ws = wb.Sheets[wb.SheetNames[0]]; - var js = XLSX.utils.sheet_to_json(ws, {header:1}); - - /* print out every line */ - js.forEach(function(l) { java.lang.System.out.println(JSON.stringify(l)); }); -} - -process_file('sheetjs.xlsx'); -process_file('sheetjs.xlsb'); -process_file('sheetjs.biff8.xls'); diff --git a/demos/altjs/qjs.js b/demos/altjs/qjs.js deleted file mode 100755 index 0e8ca6d..0000000 --- a/demos/altjs/qjs.js +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env qjs -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/* load XLSX */ -std.global.global = std.global; -std.loadScript("xlsx.full.min.js"); - -/* read contents of file */ -var rh = std.open("sheetjs.xlsx", "rb"); -rh.seek(0, std.SEEK_END); -var sz = rh.tell(); -var ab = new ArrayBuffer(sz); -rh.seek(); -rh.read(ab, 0, sz); -rh.close(); - -/* parse file */ -var wb = XLSX.read(ab, {type: 'array'}); - -/* write array */ -var out = XLSX.write(wb, {type: 'array'}); - -/* write contents to file */ -var wh = std.open("sheetjs.qjs.xlsx", "wb"); -wh.write(out, 0, out.byteLength); -wh.close(); diff --git a/demos/altjs/sheetjs.duk.c b/demos/altjs/sheetjs.duk.c deleted file mode 100644 index 23f6c5d..0000000 --- a/demos/altjs/sheetjs.duk.c +++ /dev/null @@ -1,110 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -#include -#include -#include -#include "duktape.h" - -#define FAIL_LOAD { \ - duk_push_undefined(ctx); \ - perror("Error in load_file"); \ - return 1; \ -} - -static char *read_file(const char *filename, size_t *sz) { - FILE *f = fopen(filename, "rb"); - if(!f) return NULL; - long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); } - char *buf = (char *)malloc(fsize * sizeof(char)); - *sz = fread((void *) buf, 1, fsize, f); - fclose(f); - return buf; -} - -static duk_int_t eval_file(duk_context *ctx, const char *filename) { - size_t len; char *buf = read_file(filename, &len); - if(!buf) FAIL_LOAD - - duk_push_lstring(ctx, (const char *)buf, (duk_size_t)len); - duk_int_t retval = duk_peval(ctx); - duk_pop(ctx); - return retval; -} - -static duk_int_t load_file(duk_context *ctx, const char *filename, const char *var) { - size_t len; char *buf = read_file(filename, &len); - if(!buf) FAIL_LOAD - - duk_push_external_buffer(ctx); - duk_config_buffer(ctx, -1, buf, len); - duk_put_global_string(ctx, var); - return 0; -} - -static duk_int_t save_file(duk_context *ctx, const char *filename, const char *var) { - duk_get_global_string(ctx, var); - duk_size_t sz; - char *buf = (char *)duk_get_buffer_data(ctx, -1, &sz); - - if(!buf) return 1; - FILE *f = fopen(filename, "wb"); fwrite(buf, 1, sz, f); fclose(f); - return 0; -} - -#define FAIL(cmd) { \ - printf("error in %s: %s\n", cmd, duk_safe_to_string(ctx, -1)); \ - duk_destroy_heap(ctx); \ - return res; \ -} - -#define DOIT(cmd) duk_eval_string_noresult(ctx, cmd); -int main(int argc, char *argv[]) { - duk_int_t res = 0; - - /* initialize */ - duk_context *ctx = duk_create_heap_default(); - /* duktape does not expose a standard "global" by default */ - DOIT("var global = (function(){ return this; }).call(null);"); - - /* load library */ - res = eval_file(ctx, "shim.min.js"); - if(res != 0) FAIL("shim load") - res = eval_file(ctx, "xlsx.full.min.js"); - if(res != 0) FAIL("library load") - - /* get version string */ - duk_eval_string(ctx, "XLSX.version"); - printf("SheetJS library version %s\n", duk_get_string(ctx, -1)); - duk_pop(ctx); - - /* read file */ - res = load_file(ctx, argv[1], "buf"); - if(res != 0) FAIL("file load") - printf("Loaded file %s\n", argv[1]); - - /* parse workbook */ - DOIT("wb = XLSX.read(buf, {type:'buffer', cellNF:true});"); - DOIT("ws = wb.Sheets[wb.SheetNames[0]]"); - - /* print CSV */ - duk_eval_string(ctx, "XLSX.utils.sheet_to_csv(ws)"); - printf("%s\n", duk_get_string(ctx, -1)); - duk_pop(ctx); - - /* change cell A1 to 3 */ - DOIT("ws['A1'].v = 3; delete ws['A1'].w;"); - - /* write file */ -#define WRITE_TYPE(BOOKTYPE) \ - DOIT("newbuf = (XLSX.write(wb, {type:'array', bookType:'" BOOKTYPE "'}));");\ - res = save_file(ctx, "sheetjsw." BOOKTYPE, "newbuf");\ - if(res != 0) FAIL("save sheetjsw." BOOKTYPE) - - WRITE_TYPE("xlsb") - WRITE_TYPE("xlsx") - WRITE_TYPE("xls") - WRITE_TYPE("csv") - - /* cleanup */ - duk_destroy_heap(ctx); - return res; -} diff --git a/demos/showcase/README.md b/demos/showcase/README.md deleted file mode 100644 index a42bf93..0000000 --- a/demos/showcase/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Showcase - -Many use cases are too complex to summarize in a short demo. The listed open -source projects use SheetJS libraries in clever deployments. - -### vscode-data-preview - -**Deployment**: Visual Studio Code Extension - -**Website**: - -**Repository**: - -**Notes**: Demonstrates reading and writing files. diff --git a/demos/webpack/.gitignore b/demos/webpack/.gitignore deleted file mode 100644 index 9278674..0000000 --- a/demos/webpack/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -main.js -main.min.js -*.out.js diff --git a/demos/webpack/Makefile b/demos/webpack/Makefile deleted file mode 100644 index 90946ca..0000000 --- a/demos/webpack/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -TOOL=webpack -WPOPTS=--display-modules --display-reasons --profile --mode=development -.PHONY: all -all: main.min.js core.out.js full.out.js app.out.js - -main.min.js: main.out.js - uglifyjs $< > $@ - -.PHONY: main.out.js core.out.js full.out.js -main.out.js core.out.js full.out.js: %.out.js: %.js - webpack $< --output-filename $@ $(WPOPTS) - -.PHONY: app.out.js -app.out.js: webpack.app.js app.js appworker.js - webpack --config $< $(WPOPTS) diff --git a/demos/webpack/README.md b/demos/webpack/README.md index eab47a8..b99ce27 100644 --- a/demos/webpack/README.md +++ b/demos/webpack/README.md @@ -1,110 +1,6 @@ # Webpack -This library is built with some dynamic logic to determine if it is invoked in a -script tag or in nodejs. Webpack does not understand those feature tests, so by -default it will do some strange things. - -## Basic Usage - -`webpack.app.js` demonstrates bundling an entire app script in a bundle. For -basic projects requiring the module from the npm package, it is sufficient to -suppress the node shims: - -```js -/* webpack config for app.out.js */ -{ - /* entry point app.js */ - entry: './app.js', - - /* write to app.out.js */ - output: { path:__dirname, filename: './app.out.js' }, - - /* suppress node shims */ - node: { - process: false, - Buffer: false - } -} -``` - -## Suppressing the Node shims - -The library properly guards against accidental leakage of node features in the -browser but webpack disregards those. The config should explicitly suppress: - -```js - node: { - process: false, - Buffer: false - } -``` - -## Omitting optional dependencies - -The `codepage` is needed in certain special cases, including files generated by -non-US-English versions of Excel, but may not be needed. To reduce build size, -the module can be omitted by aliasing the dependency: - -```js - resolve: { - alias: { "./dist/cpexcel.js": "" } - }, -``` - -Alternatively, bundling the `xlsx.core.min.js` script always omits dependencies. - -## Bower and minified versions - -Webpack may show a message like "This seems to be a pre-built javascript file" -when processing minified files (like the default Bower script). The message is -harmless. To suppress the message, set `module.noParse` in the webpack config: - -```js - module: { - noParse: [ - /xlsx.core.min.js/, - /xlsx.full.min.js/ - ] - } -``` - -## Other Demos - -This demo also attempts to demonstrate bundling of the library as well as the -core and full distribution versions. `app.js` is the common app code (it will -not be bundled). The individual bundles merely wrap and reflect `XLSX`. The -app code uses the bundles with script tag inclusion in the main HTML files. The -worker scripts use the bundles with `importScripts` references. - -| required script | HTML page | entry | worker script | -|----------------:|------------:|----------:|----------------:| -| main `xlsx` lib | `main.html` | `main.js` | `mainworker.js` | -| `xlsx.core.min` | `core.html` | `core.js` | `coreworker.js` | -| `xlsx.full.min` | `full.html` | `full.js` | `fullworker.js` | - -The entry points in the demo merely require and re-export the library: - -```js -/* main.js */ -var XLSX = require('../../'); -console.log("it works!"); -module.exports = XLSX; -``` - -The main advantage of reflecting the library is deduplication: the library code -is only downloaded once. The basic example builds a separate worker script and -eventually ships the library twice. - -### Reflecting the XLSX variable - -This library will not assign to `module.exports` if it is run in the browser. To -convince webpack, the demo webpack config sets `output`: - -```js - output: { - libraryTarget: 'var', - library: 'XLSX' - } -``` +[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#webpack) +reflects the new default behavior to use the ESM build. [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx) diff --git a/demos/webpack/app.js b/demos/webpack/app.js deleted file mode 100644 index 9eef9bf..0000000 --- a/demos/webpack/app.js +++ /dev/null @@ -1,147 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -/*jshint browser:true */ -/*global XLSX */ -var X = typeof require !== "undefined" && require('../../') || XLSX; - -var global_wb; - -var process_wb = (function() { - var OUT = document.getElementById('out'); - var HTMLOUT = document.getElementById('htmlout'); - - var get_format = (function() { - var radios = document.getElementsByName( "format" ); - return function() { - for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value; - }; - })(); - - var to_json = function to_json(workbook) { - var result = {}; - workbook.SheetNames.forEach(function(sheetName) { - var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]); - if(roa.length) result[sheetName] = roa; - }); - return JSON.stringify(result, 2, 2); - }; - - var to_csv = function to_csv(workbook) { - var result = []; - workbook.SheetNames.forEach(function(sheetName) { - var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]); - if(csv.length){ - result.push("SHEET: " + sheetName); - result.push(""); - result.push(csv); - } - }); - return result.join("\n"); - }; - - var to_fmla = function to_fmla(workbook) { - var result = []; - workbook.SheetNames.forEach(function(sheetName) { - var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]); - if(formulae.length){ - result.push("SHEET: " + sheetName); - result.push(""); - result.push(formulae.join("\n")); - } - }); - return result.join("\n"); - }; - - var to_html = function to_html(workbook) { - HTMLOUT.innerHTML = ""; - workbook.SheetNames.forEach(function(sheetName) { - var htmlstr = X.write(workbook, {sheet:sheetName, type:'string', bookType:'html'}); - HTMLOUT.innerHTML += htmlstr; - }); - return ""; - }; - - return function process_wb(wb) { - global_wb = wb; - var output = ""; - switch(get_format()) { - case "form": output = to_fmla(wb); break; - case "html": output = to_html(wb); break; - case "json": output = to_json(wb); break; - default: output = to_csv(wb); - } - if(OUT.innerText === undefined) OUT.textContent = output; - else OUT.innerText = output; - if(typeof console !== 'undefined') console.log("output", new Date()); - }; -})(); - -var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); }; - -var b64it = window.b64it = (function() { - var tarea = document.getElementById('b64data'); - return function b64it() { - if(typeof console !== 'undefined') console.log("onload", new Date()); - var wb = X.read(tarea.value, {type:'base64', WTF:false}); - process_wb(wb); - }; -})(); - -var do_file = (function() { - var use_worker = typeof Worker !== 'undefined'; - var domwork = document.getElementsByName("useworker")[0]; - if(!use_worker) domwork.disabled = !(domwork.checked = false); - - var xw = function xw(data, cb) { - var worker = new Worker(XW.worker); - worker.onmessage = function(e) { - switch(e.data.t) { - case 'ready': break; - case 'e': console.error(e.data.d); break; - case XW.msg: cb(JSON.parse(e.data.d)); break; - } - }; - worker.postMessage({d:data,b:'array'}); - }; - - return function do_file(files) { - use_worker = domwork.checked; - var f = files[0]; - var reader = new FileReader(); - reader.onload = function(e) { - if(typeof console !== 'undefined') console.log("onload", new Date(), use_worker); - var data = e.target.result; - data = new Uint8Array(data); - if(use_worker) xw(data, process_wb); - else process_wb(X.read(data, {type: 'array'})); - }; - reader.readAsArrayBuffer(f); - }; -})(); - -(function() { - var drop = document.getElementById('drop'); - if(!drop.addEventListener) return; - - function handleDrop(e) { - e.stopPropagation(); - e.preventDefault(); - do_file(e.dataTransfer.files); - } - - function handleDragover(e) { - e.stopPropagation(); - e.preventDefault(); - e.dataTransfer.dropEffect = 'copy'; - } - - drop.addEventListener('dragenter', handleDragover, false); - drop.addEventListener('dragover', handleDragover, false); - drop.addEventListener('drop', handleDrop, false); -})(); - -(function() { - var xlf = document.getElementById('xlf'); - if(!xlf.addEventListener) return; - function handleFile(e) { do_file(e.target.files); } - xlf.addEventListener('change', handleFile, false); -})(); diff --git a/demos/webpack/appworker.js b/demos/webpack/appworker.js deleted file mode 100644 index 17cac10..0000000 --- a/demos/webpack/appworker.js +++ /dev/null @@ -1,11 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var XLSX = require('../../'); -postMessage({t:"ready"}); - -onmessage = function (evt) { - var v; - try { - v = XLSX.read(evt.data.d, {type: evt.data.b}); -postMessage({t:"xlsx", d:JSON.stringify(v)}); - } catch(e) { postMessage({t:"e",d:e.stack||e}); } -}; diff --git a/demos/webpack/core.html b/demos/webpack/core.html deleted file mode 100644 index 6456899..0000000 --- a/demos/webpack/core.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - -SheetJS Live Demo - - - -
-SheetJS Data Preview Live Demo
-(Base64 text works back to IE6; drag and drop works back to IE10)
-
-Source Code Repo
-Issues?  Something look weird?  Click here and report an issue
-Output Format: 
-
Drop a spreadsheet file here to see sheet data
- ... or click here to select a file - - -
-Advanced Demo Options: -Use Web Workers: (when available) -
-

-
-
- - - - - diff --git a/demos/webpack/core.js b/demos/webpack/core.js deleted file mode 100644 index 39042f7..0000000 --- a/demos/webpack/core.js +++ /dev/null @@ -1,4 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var XLSX = require('./xlsx.core.min'); -console.log("it works!"); -module.exports = XLSX; diff --git a/demos/webpack/coreworker.js b/demos/webpack/coreworker.js deleted file mode 100644 index b17e861..0000000 --- a/demos/webpack/coreworker.js +++ /dev/null @@ -1,11 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -importScripts('core.out.js'); -postMessage({t:"ready"}); - -onmessage = function (evt) { - var v; - try { - v = XLSX.read(evt.data.d, {type: evt.data.b}); -postMessage({t:"xlsx", d:JSON.stringify(v)}); - } catch(e) { postMessage({t:"e",d:e.stack||e}); } -}; diff --git a/demos/webpack/full.html b/demos/webpack/full.html deleted file mode 100644 index 96ea066..0000000 --- a/demos/webpack/full.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - -SheetJS Live Demo - - - -
-SheetJS Data Preview Live Demo
-(Base64 text works back to IE6; drag and drop works back to IE10)
-
-Source Code Repo
-Issues?  Something look weird?  Click here and report an issue
-Output Format: 
-
Drop a spreadsheet file here to see sheet data
- ... or click here to select a file - - -
-Advanced Demo Options: -Use Web Workers: (when available) -
-

-
-
- - - - - diff --git a/demos/webpack/full.js b/demos/webpack/full.js deleted file mode 100644 index 142687f..0000000 --- a/demos/webpack/full.js +++ /dev/null @@ -1,4 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var XLSX = require('./xlsx.full.min'); -console.log("it works!"); -module.exports = XLSX; diff --git a/demos/webpack/fullworker.js b/demos/webpack/fullworker.js deleted file mode 100644 index 52cf9b9..0000000 --- a/demos/webpack/fullworker.js +++ /dev/null @@ -1,11 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -importScripts('full.out.js'); -postMessage({t:"ready"}); - -onmessage = function (evt) { - var v; - try { - v = XLSX.read(evt.data.d, {type: evt.data.b}); -postMessage({t:"xlsx", d:JSON.stringify(v)}); - } catch(e) { postMessage({t:"e",d:e.stack||e}); } -}; diff --git a/demos/webpack/main.html b/demos/webpack/main.html deleted file mode 100644 index 5baade7..0000000 --- a/demos/webpack/main.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - -SheetJS Live Demo - - - -
-SheetJS Data Preview Live Demo
-(Base64 text works back to IE6; drag and drop works back to IE10)
-
-Source Code Repo
-Issues?  Something look weird?  Click here and report an issue
-Output Format: 
-
Drop a spreadsheet file here to see sheet data
- ... or click here to select a file - - -
-Advanced Demo Options: -Use Web Workers: (when available) -
-

-
-
- - - - - diff --git a/demos/webpack/mainworker.js b/demos/webpack/mainworker.js deleted file mode 100644 index 2749ad5..0000000 --- a/demos/webpack/mainworker.js +++ /dev/null @@ -1,11 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -importScripts('main.min.js'); -postMessage({t:"ready"}); - -onmessage = function (evt) { - var v; - try { - v = XLSX.read(evt.data.d, {type: evt.data.b}); -postMessage({t:"xlsx", d:JSON.stringify(v)}); - } catch(e) { postMessage({t:"e",d:e.stack||e}); } -}; diff --git a/demos/webpack/src/index.js b/demos/webpack/src/index.js deleted file mode 100644 index 57c9cf5..0000000 --- a/demos/webpack/src/index.js +++ /dev/null @@ -1,4 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var XLSX = require('../../'); -console.log("it works!"); -module.exports = XLSX; diff --git a/demos/webpack/webpack.app.js b/demos/webpack/webpack.app.js deleted file mode 100644 index d45b8c5..0000000 --- a/demos/webpack/webpack.app.js +++ /dev/null @@ -1,25 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -var commonops = { - /* suppress node shims */ - node: { - process: false, - Buffer: false - } -} - -/* app.out.js */ -var app_config = Object.assign({ - entry: './app.js', - output: { path:__dirname, filename: './app.out.js' } -}, commonops); - -/* appworker.out.js */ -var appworker_config = Object.assign({ - entry: './appworker.js', - output: { path:__dirname, filename: './appworker.out.js' } -}, commonops); - -module.exports = [ - app_config, - appworker_config -] diff --git a/demos/webpack/webpack.config.js b/demos/webpack/webpack.config.js deleted file mode 100644 index 5a4fe0e..0000000 --- a/demos/webpack/webpack.config.js +++ /dev/null @@ -1,27 +0,0 @@ -/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -module.exports = { - /* ensure that the XLSX variable is exported */ - output: { - path: __dirname, - libraryTarget: 'var', - library: 'XLSX' - }, - /* module.noParse needed for bower */ - module: { - noParse: [ - /xlsx.core.min.js/, - /xlsx.full.min.js/ - ] - }, - /* Uncomment the next block to suppress codepage */ - /* - resolve: { - alias: { "./dist/cpexcel.js": "" } - }, - */ - /* suppress node shims */ - node: { - process: false, - Buffer: false - } -}; diff --git a/demos/webpack/xlsx.core.min.js b/demos/webpack/xlsx.core.min.js deleted file mode 120000 index 383ccb8..0000000 --- a/demos/webpack/xlsx.core.min.js +++ /dev/null @@ -1 +0,0 @@ -../../dist/xlsx.core.min.js \ No newline at end of file diff --git a/demos/webpack/xlsx.full.min.js b/demos/webpack/xlsx.full.min.js deleted file mode 120000 index dbca48d..0000000 --- a/demos/webpack/xlsx.full.min.js +++ /dev/null @@ -1 +0,0 @@ -../../dist/xlsx.full.min.js \ No newline at end of file diff --git a/modules/04_base64.js b/modules/04_base64.js index fdd658a..637bee2 100644 --- a/modules/04_base64.js +++ b/modules/04_base64.js @@ -48,9 +48,7 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/^data:.+\/.+;base64\,/,'') - .replace(/[^\w\+\/\=]/g, "") - + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, ""); for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); diff --git a/modules/04_base64.ts b/modules/04_base64.ts index adbd40a..10bfc37 100644 --- a/modules/04_base64.ts +++ b/modules/04_base64.ts @@ -40,7 +40,7 @@ function Base64_encode_pass(input: string): string { function Base64_decode(input: string): string { var o = ""; var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0; - input = input.replace(/^data:.+\/.+;base64\,/,'') + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/,'') .replace(/[^\w\+\/\=]/g, "") for(var i = 0; i < input.length;) { e1 = Base64_map.indexOf(input.charAt(i++)); diff --git a/test.js b/test.js index f7d9cd5..e62ff2e 100644 --- a/test.js +++ b/test.js @@ -688,30 +688,21 @@ describe('input formats', function() { it('should read base64 strings', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); - it('handles base64 within data URI scheme (gh-2762)', function() { - // Arrange - var fileInBase64 = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; - var fileInBase64WithDataURIScheme = 'data:text/csv;base64,TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; - // Act - var workBookFromRawBase64 = X.read(fileInBase64, { type: 'base64' }); - var workBookFromBase64WithinDataURI = X.read(fileInBase64WithDataURIScheme, { type: 'base64' }); + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel - // Assert - assert.deepStrictEqual(workBookFromRawBase64, workBookFromBase64WithinDataURI); - }); - it('handles base64 where data URI has no media type (gh-2762)', function() { - // Arrange - var fileInBase64 = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; - var fileInBase64WithDataURIScheme = 'data:;base64,TmFtZXMNCkhhZmV6DQpTYW0NCg=='; - - // Act - var workBookFromRawBase64 = X.read(fileInBase64, { type: 'base64' }); - var workBookFromBase64WithinDataURI = X.read(fileInBase64WithDataURIScheme, { type: 'base64' }); - - // Assert - assert.deepStrictEqual(workBookFromRawBase64, workBookFromBase64WithinDataURI); + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); }); if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); diff --git a/test.mjs b/test.mjs index 1e7e914..8b2a2dc 100644 --- a/test.mjs +++ b/test.mjs @@ -685,6 +685,22 @@ describe('input formats', function() { it('should read base64 strings', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + it('handles base64 within data URI scheme (gh-2762)', function() { + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel + + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); + }); if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); @@ -1384,7 +1400,7 @@ describe('parse features', function() { }); describe('data types formats', function() {[ - ['xlsx', paths.dtfxlsx], + ['xlsx', paths.dtfxlsx] ].forEach(function(m) { it(m[0], function() { var wb = X.read(fs.readFileSync(m[1]), {type: TYPE, cellDates: true}); var ws = wb.Sheets[wb.SheetNames[0]]; @@ -2187,7 +2203,7 @@ describe('CSV', function() { var aoa = [ ["3a", "3 a", "3 a-1"], ["3b", "3 b", "3 b-1"], - ["3p", "3 P", "3 p-1"], + ["3p", "3 P", "3 p-1"] ] var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1; for(var R = 0; R < 3; ++R) { diff --git a/test.mts b/test.mts index 1f25456..f57df05 100644 --- a/test.mts +++ b/test.mts @@ -702,6 +702,22 @@ describe('input formats', function() { it('should read base64 strings', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + it('handles base64 within data URI scheme (gh-2762)', function() { + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel + + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); + }); if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); diff --git a/test.ts b/test.ts index 0d8de53..b050ab4 100644 --- a/test.ts +++ b/test.ts @@ -702,6 +702,22 @@ Deno.test('input formats', async function(t) { await t.step('should read base64 strings', async function(t) { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + await t.step('handles base64 within data URI scheme (gh-2762)', async function(t) { + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel + + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); + }); if(typeof Uint8Array !== 'undefined') await t.step('should read array', async function(t) { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); diff --git a/testnocp.ts b/testnocp.ts index f8b155d..43c706a 100644 --- a/testnocp.ts +++ b/testnocp.ts @@ -701,6 +701,22 @@ Deno.test('input formats', async function(t) { await t.step('should read base64 strings', async function(t) { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + await t.step('handles base64 within data URI scheme (gh-2762)', async function(t) { + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel + + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); + }); if(typeof Uint8Array !== 'undefined') await t.step('should read array', async function(t) { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); diff --git a/tests/core.js b/tests/core.js index c697cc8..e432438 100644 --- a/tests/core.js +++ b/tests/core.js @@ -688,6 +688,22 @@ describe('input formats', function() { it('should read base64 strings', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'base64'), {type: 'base64'}); }); }); + it('handles base64 within data URI scheme (gh-2762)', function() { + var data = 'TmFtZXMNCkhhZmV6DQpTYW0NCg=='; + + var wb0 = X.read(data, { type: 'base64' }); // raw base64 string + var wb1 = X.read('data:;base64,' + data, { type: 'base64' }); // data URI, no media type + var wb2 = X.read('data:text/csv;base64,' + data, { type: 'base64' }); // data URI, CSV type + var wb3 = X.read('data:application/vnd.ms-excel;base64,' + data, { type: 'base64' }); // data URI, Excel + + [wb0, wb1, wb2, wb3].forEach(function(wb) { + var ws = wb.Sheets.Sheet1; + assert.equal(ws["!ref"], "A1:A3"); + assert.equal(get_cell(ws, "A1").v, "Names"); + assert.equal(get_cell(ws, "A2").v, "Hafez"); + assert.equal(get_cell(ws, "A3").v, "Sam"); + }); + }); if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) { X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'}); }); }); @@ -1393,7 +1409,7 @@ describe('parse features', function() { }); describe('data types formats', function() {[ - ['xlsx', paths.dtfxlsx], + ['xlsx', paths.dtfxlsx] ].forEach(function(m) { it(m[0], function() { var wb = X.read(fs.readFileSync(m[1]), {type: TYPE, cellDates: true}); var ws = wb.Sheets[wb.SheetNames[0]]; @@ -2200,7 +2216,7 @@ describe('CSV', function() { var aoa = [ ["3a", "3 a", "3 a-1"], ["3b", "3 b", "3 b-1"], - ["3p", "3 P", "3 p-1"], + ["3p", "3 P", "3 p-1"] ] var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1; for(var R = 0; R < 3; ++R) { diff --git a/xlsx.flow.js b/xlsx.flow.js index 9f9aef5..20b30d1 100644 --- a/xlsx.flow.js +++ b/xlsx.flow.js @@ -133,7 +133,7 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, ""); for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); @@ -19310,6 +19310,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { if(RecordType === 0 && last_RT === 0x000a /* EOF */) break; var length = (blob.l === blob.length ? 0 : blob.read_shift(2)); var R = XLSRecordEnum[RecordType]; + if(file_depth == 0 && [0x0009, 0x0209, 0x0409, 0x0809].indexOf(RecordType) == -1 /* BOF */) break; //console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length); //if(!R) console.log(blob.slice(blob.l, blob.l + length)); if(R && R.f) { diff --git a/xlsx.js b/xlsx.js index d277b1f..ea3ae67 100644 --- a/xlsx.js +++ b/xlsx.js @@ -132,7 +132,7 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, ""); for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); @@ -19204,6 +19204,7 @@ function parse_workbook(blob, options) { if(RecordType === 0 && last_RT === 0x000a /* EOF */) break; var length = (blob.l === blob.length ? 0 : blob.read_shift(2)); var R = XLSRecordEnum[RecordType]; + if(file_depth == 0 && [0x0009, 0x0209, 0x0409, 0x0809].indexOf(RecordType) == -1 /* BOF */) break; //console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length); //if(!R) console.log(blob.slice(blob.l, blob.l + length)); if(R && R.f) { diff --git a/xlsx.mjs b/xlsx.mjs index 80894bd..51b5adb 100644 --- a/xlsx.mjs +++ b/xlsx.mjs @@ -132,7 +132,7 @@ function Base64_encode_pass(input) { function Base64_decode(input) { var o = ""; var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0; - input = input.replace(/[^\w\+\/\=]/g, ""); + input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, ""); for (var i = 0; i < input.length; ) { e1 = Base64_map.indexOf(input.charAt(i++)); e2 = Base64_map.indexOf(input.charAt(i++)); @@ -19305,6 +19305,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { if(RecordType === 0 && last_RT === 0x000a /* EOF */) break; var length = (blob.l === blob.length ? 0 : blob.read_shift(2)); var R = XLSRecordEnum[RecordType]; + if(file_depth == 0 && [0x0009, 0x0209, 0x0409, 0x0809].indexOf(RecordType) == -1 /* BOF */) break; //console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length); //if(!R) console.log(blob.slice(blob.l, blob.l + length)); if(R && R.f) {