forked from sheetjs/sheetjs
update tests
This commit is contained in:
parent
6bea47aaef
commit
838ee58a49
@ -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++));
|
||||
|
@ -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)
|
||||
|
10
demos/altjs/.gitignore
vendored
10
demos/altjs/.gitignore
vendored
@ -1,10 +0,0 @@
|
||||
sheetjs.*
|
||||
SheetJSSwift
|
||||
duk*
|
||||
*.class
|
||||
*.jar
|
||||
rhino
|
||||
shim.min.js
|
||||
xlsx.*.js
|
||||
payload.js
|
||||
goja
|
@ -1,3 +0,0 @@
|
||||
disabled_rules:
|
||||
- trailing_semicolon
|
||||
- identifier_name
|
@ -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
|
@ -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)
|
||||
|
@ -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);
|
@ -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); }
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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]]));
|
@ -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(); }
|
||||
|
||||
}
|
@ -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); }
|
||||
}
|
@ -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, "<cmd>", 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, "<cmd>", 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};", "<cmd>", 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(); }
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,3 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var global = (function(){ return this; }).call(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")
|
||||
}
|
@ -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);
|
||||
}
|
@ -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');
|
@ -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();
|
@ -1,110 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
@ -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**: <https://marketplace.visualstudio.com/items?itemName=RandomFractalsInc.vscode-data-preview>
|
||||
|
||||
**Repository**: <https://github.com/RandomFractals/vscode-data-preview>
|
||||
|
||||
**Notes**: Demonstrates reading and writing files.
|
3
demos/webpack/.gitignore
vendored
3
demos/webpack/.gitignore
vendored
@ -1,3 +0,0 @@
|
||||
main.js
|
||||
main.min.js
|
||||
*.out.js
|
@ -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)
|
@ -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)
|
||||
|
@ -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);
|
||||
})();
|
@ -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}); }
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>SheetJS Live Demo</title>
|
||||
<style>
|
||||
#drop{
|
||||
border:2px dashed #bbb;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
padding:25px;
|
||||
text-align:center;
|
||||
font:20pt bold,"Vollkorn";color:#bbb
|
||||
}
|
||||
#b64data{
|
||||
width:100%;
|
||||
}
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
(Base64 text works back to IE6; drag and drop works back to IE10)
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
Output Format: <select name="format" onchange="setfmt()">
|
||||
<option value="csv" selected> CSV</option>
|
||||
<option value="json"> JSON</option>
|
||||
<option value="form"> FORMULAE</option>
|
||||
<option value="html"> HTML</option>
|
||||
</select><br />
|
||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
|
||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
|
||||
|
||||
<textarea id="b64data">... or paste a base64-encoding here</textarea>
|
||||
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
|
||||
<b>Advanced Demo Options:</b>
|
||||
Use Web Workers: (when available) <input type="checkbox" name="useworker" checked>
|
||||
</pre>
|
||||
<pre id="out"></pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<script src="core.out.js"></script>
|
||||
<script>
|
||||
var XW = {
|
||||
/* worker message */
|
||||
msg: 'xlsx',
|
||||
/* worker scripts */
|
||||
worker: './coreworker.js'
|
||||
};
|
||||
</script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -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;
|
@ -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}); }
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>SheetJS Live Demo</title>
|
||||
<style>
|
||||
#drop{
|
||||
border:2px dashed #bbb;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
padding:25px;
|
||||
text-align:center;
|
||||
font:20pt bold,"Vollkorn";color:#bbb
|
||||
}
|
||||
#b64data{
|
||||
width:100%;
|
||||
}
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
(Base64 text works back to IE6; drag and drop works back to IE10)
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
Output Format: <select name="format" onchange="setfmt()">
|
||||
<option value="csv" selected> CSV</option>
|
||||
<option value="json"> JSON</option>
|
||||
<option value="form"> FORMULAE</option>
|
||||
<option value="html"> HTML</option>
|
||||
</select><br />
|
||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
|
||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
|
||||
|
||||
<textarea id="b64data">... or paste a base64-encoding here</textarea>
|
||||
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
|
||||
<b>Advanced Demo Options:</b>
|
||||
Use Web Workers: (when available) <input type="checkbox" name="useworker" checked>
|
||||
</pre>
|
||||
<pre id="out"></pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<script src="full.out.js"></script>
|
||||
<script>
|
||||
var XW = {
|
||||
/* worker message */
|
||||
msg: 'xlsx',
|
||||
/* worker scripts */
|
||||
worker: './fullworker.js'
|
||||
};
|
||||
</script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -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;
|
@ -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}); }
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>SheetJS Live Demo</title>
|
||||
<style>
|
||||
#drop{
|
||||
border:2px dashed #bbb;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
padding:25px;
|
||||
text-align:center;
|
||||
font:20pt bold,"Vollkorn";color:#bbb
|
||||
}
|
||||
#b64data{
|
||||
width:100%;
|
||||
}
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
(Base64 text works back to IE6; drag and drop works back to IE10)
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
Output Format: <select name="format" onchange="setfmt()">
|
||||
<option value="csv" selected> CSV</option>
|
||||
<option value="json"> JSON</option>
|
||||
<option value="form"> FORMULAE</option>
|
||||
<option value="html"> HTML</option>
|
||||
</select><br />
|
||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
|
||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
|
||||
|
||||
<textarea id="b64data">... or paste a base64-encoding here</textarea>
|
||||
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
|
||||
<b>Advanced Demo Options:</b>
|
||||
Use Web Workers: (when available) <input type="checkbox" name="useworker" checked>
|
||||
</pre>
|
||||
<pre id="out"></pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<script src="main.min.js"></script>
|
||||
<script>
|
||||
var XW = {
|
||||
/* worker message */
|
||||
msg: 'xlsx',
|
||||
/* worker scripts */
|
||||
worker: './mainworker.js'
|
||||
};
|
||||
</script>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -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}); }
|
||||
};
|
@ -1,4 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var XLSX = require('../../');
|
||||
console.log("it works!");
|
||||
module.exports = XLSX;
|
@ -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
|
||||
]
|
@ -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
|
||||
}
|
||||
};
|
1
demos/webpack/xlsx.core.min.js
vendored
1
demos/webpack/xlsx.core.min.js
vendored
@ -1 +0,0 @@
|
||||
../../dist/xlsx.core.min.js
|
1
demos/webpack/xlsx.full.min.js
vendored
1
demos/webpack/xlsx.full.min.js
vendored
@ -1 +0,0 @@
|
||||
../../dist/xlsx.full.min.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++));
|
||||
|
@ -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++));
|
||||
|
33
test.js
33
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'});
|
||||
|
20
test.mjs
generated
20
test.mjs
generated
@ -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) {
|
||||
|
16
test.mts
16
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'});
|
||||
}); });
|
||||
|
16
test.ts
16
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'});
|
||||
}); });
|
||||
|
16
testnocp.ts
16
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'});
|
||||
}); });
|
||||
|
20
tests/core.js
generated
20
tests/core.js
generated
@ -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) {
|
||||
|
@ -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) {
|
||||
|
3
xlsx.js
generated
3
xlsx.js
generated
@ -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) {
|
||||
|
3
xlsx.mjs
generated
3
xlsx.mjs
generated
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user