forked from sheetjs/sheetjs
		
	updated demos [ci skip]
- frameworks: react, react-native, preact, next.js, weex, nuxt.js - deployments: nodejs server, duktape, chakra, electron, nw.js
This commit is contained in:
		
							parent
							
								
									ad47cb433c
								
							
						
					
					
						commit
						f03e32fc9a
					
				
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							@ -167,21 +167,25 @@ CDNjs automatically pulls the latest version and makes all versions available at
 | 
			
		||||
 | 
			
		||||
The `demos` directory includes sample projects for:
 | 
			
		||||
 | 
			
		||||
**JS Frameworks and APIs**
 | 
			
		||||
**Frameworks and APIs**
 | 
			
		||||
- [`angular 1.x`](demos/angular/)
 | 
			
		||||
- [`angular 2.x / 4.x`](demos/angular2/)
 | 
			
		||||
- [`meteor`](demos/meteor/)
 | 
			
		||||
- [`vue 2.x`](demos/vue/)
 | 
			
		||||
- [`react and react-native`](demos/react/)
 | 
			
		||||
- [`vue 2.x and weex`](demos/vue/)
 | 
			
		||||
- [`XMLHttpRequest and fetch`](demos/xhr/)
 | 
			
		||||
- [`nodejs server`](demos/server/)
 | 
			
		||||
 | 
			
		||||
**JS Bundlers and Tooling**
 | 
			
		||||
**Bundlers and Tooling**
 | 
			
		||||
- [`browserify`](demos/browserify/)
 | 
			
		||||
- [`requirejs`](demos/requirejs/)
 | 
			
		||||
- [`rollup`](demos/rollup/)
 | 
			
		||||
- [`systemjs`](demos/systemjs/)
 | 
			
		||||
- [`webpack 2.x`](demos/webpack/)
 | 
			
		||||
 | 
			
		||||
**JS Platforms and Integrations**
 | 
			
		||||
**Platforms and Integrations**
 | 
			
		||||
- [`electron application`](demos/electron/)
 | 
			
		||||
- [`nw.js application`](demos/nwjs/)
 | 
			
		||||
- [`Adobe ExtendScript`](demos/extendscript/)
 | 
			
		||||
- [`Headless Browsers`](demos/headless/)
 | 
			
		||||
- [`canvas-datagrid`](demos/datagrid/)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										22
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							@ -89,8 +89,14 @@ function wb_fmt() {
 | 
			
		||||
	opts.cellNF = true;
 | 
			
		||||
	if(program.output) sheetname = program.output;
 | 
			
		||||
}
 | 
			
		||||
workbook_formats.forEach(function(m) { if(program[m]) { wb_fmt(); } });
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) { wb_fmt(); } });
 | 
			
		||||
function isfmt(m) {
 | 
			
		||||
	if(!program.output) return false;
 | 
			
		||||
	var t = m.charAt(0) == "." ? m : "." + m;
 | 
			
		||||
	console.log(m);
 | 
			
		||||
	return program.output.slice(-m.length) == m;
 | 
			
		||||
}
 | 
			
		||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) { wb_fmt(); } });
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
 | 
			
		||||
if(seen) {
 | 
			
		||||
} else if(program.formulae) opts.cellFormula = true;
 | 
			
		||||
else opts.cellFormula = false;
 | 
			
		||||
@ -129,14 +135,14 @@ var wopts = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
 | 
			
		||||
if(program.compress) wopts.compression = true;
 | 
			
		||||
 | 
			
		||||
/* full workbook formats */
 | 
			
		||||
workbook_formats.forEach(function(m) { if(program[m]) {
 | 
			
		||||
		X.writeFile(wb, sheetname || ((filename || "") + "." + m), wopts);
 | 
			
		||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) {
 | 
			
		||||
		X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m), wopts);
 | 
			
		||||
		process.exit(0);
 | 
			
		||||
} });
 | 
			
		||||
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) {
 | 
			
		||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
 | 
			
		||||
		wopts.bookType = m[1];
 | 
			
		||||
		X.writeFile(wb, sheetname || ((filename || "") + "." + m[2]), wopts);
 | 
			
		||||
		X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m[2]), wopts);
 | 
			
		||||
		process.exit(0);
 | 
			
		||||
} });
 | 
			
		||||
 | 
			
		||||
@ -168,9 +174,9 @@ if(program.readOnly) process.exit(0);
 | 
			
		||||
	['prn', '.prn'],
 | 
			
		||||
	['txt', '.txt'],
 | 
			
		||||
	['dif', '.dif']
 | 
			
		||||
].forEach(function(m) { if(program[m[0]]) {
 | 
			
		||||
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
 | 
			
		||||
		wopts.bookType = m[0];
 | 
			
		||||
		X.writeFile(wb, sheetname || ((filename || "") + m[1]), wopts);
 | 
			
		||||
		X.writeFile(wb, program.output || sheetname || ((filename || "") + m[1]), wopts);
 | 
			
		||||
		process.exit(0);
 | 
			
		||||
} });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								demos/altjs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								demos/altjs/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,6 +1,8 @@
 | 
			
		||||
jvm-npm.js
 | 
			
		||||
sheetjs.*
 | 
			
		||||
duk*
 | 
			
		||||
*.class
 | 
			
		||||
*.jar
 | 
			
		||||
rhino
 | 
			
		||||
xlsx.swift.js
 | 
			
		||||
xlsx.*.js
 | 
			
		||||
payload.js
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,11 @@ base:
 | 
			
		||||
	if [ ! -e sheetjs.xlsx ]; then node ../../tests/write.js; fi
 | 
			
		||||
 | 
			
		||||
.PHONY: duktape
 | 
			
		||||
duktape: base ## duktape / skookum demo
 | 
			
		||||
	sjs skookum.js
 | 
			
		||||
duktape: base ## duktape demo
 | 
			
		||||
	bash ./duktape.sh
 | 
			
		||||
	gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
 | 
			
		||||
	if [ ! -e xlsx.duktape.js ]; then cp ../../dist/xlsx.full.min.js xlsx.duktape.js; fi
 | 
			
		||||
	./sheetjs.duk
 | 
			
		||||
 | 
			
		||||
.PHONY: nashorn
 | 
			
		||||
nashorn: base ## nashorn demo
 | 
			
		||||
@ -19,6 +22,12 @@ swift: base ## swift demo
 | 
			
		||||
	if [ ! -e xlsx.swift.js ]; then cp ../../dist/xlsx.full.min.js xlsx.swift.js; fi
 | 
			
		||||
	./SheetJSCore.swift
 | 
			
		||||
 | 
			
		||||
.PHONY: chakra
 | 
			
		||||
chakra: base ## Chakra demo
 | 
			
		||||
	node -pe "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('sheetjs.xlsx').toString('base64') + '\";')"
 | 
			
		||||
	cat global.js ../../dist/xlsx.full.min.js payload.js chakra.js > xlsx.chakra.js
 | 
			
		||||
	chakra ./xlsx.chakra.js
 | 
			
		||||
 | 
			
		||||
.PHONY: rhinojs ## rhino demo
 | 
			
		||||
rhinojs: base SheetJSRhino.class
 | 
			
		||||
	java -cp .:SheetJS.jar:rhino.jar SheetJSRhino sheetjs.xlsx
 | 
			
		||||
 | 
			
		||||
@ -50,14 +50,30 @@ context.setOptimizationLevel(-1);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## duktape and skookum
 | 
			
		||||
## 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 interop 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!  Duktape understands the source
 | 
			
		||||
code and can process binary strings out the box, but does not provide I/O or
 | 
			
		||||
other standard library features.
 | 
			
		||||
amalgamation makes integration extremely simple!  It supports `Buffer` natively:
 | 
			
		||||
 | 
			
		||||
To demonstrate compatibility with duktape, this demo uses the JS runtime from
 | 
			
		||||
[Skookum JS](https://github.com/saghul/sjs).  Built upon the duktape engine, it
 | 
			
		||||
adds a simple I/O interface to enable reading from files.
 | 
			
		||||
```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, {type:'buffer'});");
 | 
			
		||||
 | 
			
		||||
/* write a workbook object to a C char array */
 | 
			
		||||
duk_eval_string(ctx, "XLSX.write(workbook, {type:'buffer', bookType:'xlsx'})");
 | 
			
		||||
duk_size_t sz;
 | 
			
		||||
char *buf = (char *)duk_get_buffer_data(ctx, -1, sz);
 | 
			
		||||
duk_pop(ctx);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								demos/altjs/chakra.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								demos/altjs/chakra.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
/* 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]]));
 | 
			
		||||
							
								
								
									
										17
									
								
								demos/altjs/duktape.sh
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										17
									
								
								demos/altjs/duktape.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
DUKTAPE_VER=2.1.1
 | 
			
		||||
if [ ! -e duktape-$DUKTAPE_VER ]; then
 | 
			
		||||
	if [ ! -e duktape-$DUKTAPE_VER.tar ]; then
 | 
			
		||||
		if [ ! -e duktape-$DUKTAPE_VER.tar.xz ]; then
 | 
			
		||||
			curl -O http://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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								demos/altjs/global.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								demos/altjs/global.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var global = (function(){ return this; }).call(null);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										101
									
								
								demos/altjs/sheetjs.duk.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										101
									
								
								demos/altjs/sheetjs.duk.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,101 @@
 | 
			
		||||
/* 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, "xlsx.duktape.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, "sheetjs.xlsx", "buf");
 | 
			
		||||
	if(res != 0) FAIL("load sheetjs.xlsx")
 | 
			
		||||
 | 
			
		||||
	/* parse workbook */
 | 
			
		||||
	DOIT("wb = XLSX.read(buf, {type:'buffer'});");
 | 
			
		||||
	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 */
 | 
			
		||||
	DOIT("newbuf = XLSX.write(wb, {type:'buffer', bookType:'xlsx'})");
 | 
			
		||||
	res = save_file(ctx, "sheetjsw.xlsx", "newbuf");
 | 
			
		||||
	if(res != 0) FAIL("save sheetjsw.xlsx")
 | 
			
		||||
 | 
			
		||||
	/* cleanup */
 | 
			
		||||
	duk_destroy_heap(ctx);
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
#!/usr/bin/env sjs
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
 | 
			
		||||
var XLSX = require('../../xlsx.js');
 | 
			
		||||
 | 
			
		||||
var io = require('io');
 | 
			
		||||
var file = io.open("sheetjs.xlsx", "rb");
 | 
			
		||||
var strs = [], str = "";
 | 
			
		||||
while((str = file.read()).length > 0) strs.push(str);
 | 
			
		||||
var data = (Buffer.concat(strs.map(function(x) { return new Buffer(x); })));
 | 
			
		||||
 | 
			
		||||
var wb = XLSX.read(data, {type:"buffer"});
 | 
			
		||||
console.log(wb.Sheets[wb.SheetNames[0]]);
 | 
			
		||||
@ -6,9 +6,9 @@ The library can be imported directly from TS code with:
 | 
			
		||||
import * as XLSX from 'xlsx';
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This demo uses an array of arrays as the core data structure.  The component
 | 
			
		||||
template includes a file input element, a table that updates based on the data,
 | 
			
		||||
and a button to export the data.
 | 
			
		||||
This demo uses an array of arrays (type `Array<Array<any>>`) as the core state.
 | 
			
		||||
The component template includes a file input element, a table that updates with
 | 
			
		||||
the data, and a button to export the data.
 | 
			
		||||
 | 
			
		||||
## Switching between Angular versions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,8 +24,8 @@ function s2ab(s: string): ArrayBuffer {
 | 
			
		||||
	<table class="sjs-table">
 | 
			
		||||
		<tr *ngFor="let row of data">
 | 
			
		||||
			<td *ngFor="let val of row">
 | 
			
		||||
			{{val}}
 | 
			
		||||
		</td>
 | 
			
		||||
				{{val}}
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</table>
 | 
			
		||||
	<button (click)="export()">Export!</button>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										8
									
								
								demos/electron/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										8
									
								
								demos/electron/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init:
 | 
			
		||||
	mkdir -p node_modules
 | 
			
		||||
	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx ; fi; cd -
 | 
			
		||||
 | 
			
		||||
.PHONY: run
 | 
			
		||||
run:
 | 
			
		||||
	electron .
 | 
			
		||||
							
								
								
									
										19
									
								
								demos/electron/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										19
									
								
								demos/electron/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
# Electron
 | 
			
		||||
 | 
			
		||||
This library is compatible with Electron and should just work out of the box.
 | 
			
		||||
The demonstration uses Electron v1.7.5.  The library is added via `require` from
 | 
			
		||||
the render process.  It can also be required from the main process, as shown in
 | 
			
		||||
this demo to render a version string in the About dialog on OSX.
 | 
			
		||||
 | 
			
		||||
The standard HTML5 `FileReader` techniques from the browser apply to Electron.
 | 
			
		||||
This demo includes a drag-and-drop box as well as a file input box, mirroring
 | 
			
		||||
the [SheetJS Data Preview Live Demo](http://oss.sheetjs.com/js-xlsx/)
 | 
			
		||||
 | 
			
		||||
Since electron provides an `fs` implementation, `readFile` and `writeFile` can
 | 
			
		||||
be used in conjunction with the standard dialogs.  For example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var dialog = require('electron').remote.dialog;
 | 
			
		||||
var o = (dialog.showOpenDialog({ properties: ['openFile'] })||[''])[0];
 | 
			
		||||
var workbook = X.readFile(o);
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										37
									
								
								demos/electron/index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										37
									
								
								demos/electron/index.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
<!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 Electron 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
 | 
			
		||||
}
 | 
			
		||||
a { text-decoration: none }
 | 
			
		||||
</style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<pre>
 | 
			
		||||
<b><a href="http://sheetjs.com">SheetJS Electron Demo</a></b>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
<br />
 | 
			
		||||
<button id="readf">Click here to select a file from your computer</button><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
 | 
			
		||||
 | 
			
		||||
</pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="index.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										79
									
								
								demos/electron/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										79
									
								
								demos/electron/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
var X = require('xlsx');
 | 
			
		||||
var electron = require('electron').remote;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		wb.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(wb, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var _gaq = _gaq || [];
 | 
			
		||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 | 
			
		||||
	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 | 
			
		||||
	var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			data = new Uint8Array(data);
 | 
			
		||||
			process_wb(X.read(data, {type: 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
 | 
			
		||||
	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 readf = document.getElementById('readf');
 | 
			
		||||
	function handleF(e) {
 | 
			
		||||
		var o = electron.dialog.showOpenDialog({
 | 
			
		||||
			title: 'Select a file',
 | 
			
		||||
			filters: [{
 | 
			
		||||
				name: "Spreadsheets",
 | 
			
		||||
				extensions: "xls|xlsx|xlsm|xlsb|xml|xlw|xlc|csv|txt|dif|sylk|slk|prn|ods|fods|uos|dbf|wks|123|wq1|qpw|htm|html".split("|")
 | 
			
		||||
			}],
 | 
			
		||||
			properties: ['openFile']
 | 
			
		||||
		});
 | 
			
		||||
		if(o.length > 0) process_wb(X.readFile(o[0]));
 | 
			
		||||
	}
 | 
			
		||||
	readf.addEventListener('click', handleF, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var xlf = document.getElementById('xlf');
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
							
								
								
									
										19
									
								
								demos/electron/main.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										19
									
								
								demos/electron/main.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
/* from the electron quick-start */
 | 
			
		||||
var electron = require('electron');
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
var app = electron.app;
 | 
			
		||||
 | 
			
		||||
var win = null;
 | 
			
		||||
 | 
			
		||||
function createWindow() {
 | 
			
		||||
	if(win) return;
 | 
			
		||||
	win = new electron.BrowserWindow({width:800, height:600});
 | 
			
		||||
	win.loadURL("file://" + __dirname + "/index.html");
 | 
			
		||||
	win.webContents.openDevTools();
 | 
			
		||||
	win.on('closed', function() { win = null; });
 | 
			
		||||
}
 | 
			
		||||
if(app.setAboutPanelOptions) app.setAboutPanelOptions({ applicationName: 'sheetjs-electron', applicationVersion: "XLSX " + XLSX.version, copyright: "(C) 2017-present SheetJS LLC" });
 | 
			
		||||
app.on('open-file', function() { console.log(arguments); });
 | 
			
		||||
app.on('ready', createWindow);
 | 
			
		||||
app.on('activate', createWindow);
 | 
			
		||||
app.on('window-all-closed', function() { if(process.platform !== 'darwin') app.quit(); });
 | 
			
		||||
							
								
								
									
										10
									
								
								demos/electron/package.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										10
									
								
								demos/electron/package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
	"name": "sheetjs-electron",
 | 
			
		||||
	"author": "sheetjs",
 | 
			
		||||
	"version": "0.0.0",
 | 
			
		||||
	"main": "main.js",
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
		"electron": "~1.7.x",
 | 
			
		||||
		"xlsx": "*"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								demos/nwjs/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										7
									
								
								demos/nwjs/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init:
 | 
			
		||||
	if [ ! -e xlsx.full.min.js ]; then ln -s ../../dist/xlsx.full.min.js . ; fi
 | 
			
		||||
 | 
			
		||||
.PHONY: run
 | 
			
		||||
run:
 | 
			
		||||
	nw .
 | 
			
		||||
							
								
								
									
										10
									
								
								demos/nwjs/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										10
									
								
								demos/nwjs/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
# NW.js
 | 
			
		||||
 | 
			
		||||
This library is compatible with NW.js and should just work out of the box.
 | 
			
		||||
The demonstration uses NW.js 0.24 with the dist script.
 | 
			
		||||
 | 
			
		||||
The standard HTML5 `FileReader` techniques from the browser apply to NW.js.
 | 
			
		||||
This demo includes a drag-and-drop box as well as a file input box, mirroring
 | 
			
		||||
the [SheetJS Data Preview Live Demo](http://oss.sheetjs.com/js-xlsx/)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								demos/nwjs/index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										37
									
								
								demos/nwjs/index.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
<!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 NW.js 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
 | 
			
		||||
}
 | 
			
		||||
a { text-decoration: none }
 | 
			
		||||
</style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<pre>
 | 
			
		||||
<b><a href="http://sheetjs.com">SheetJS NW.js Demo</a></b>
 | 
			
		||||
 | 
			
		||||
<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>
 | 
			
		||||
<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
 | 
			
		||||
 | 
			
		||||
</pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
<script src="index.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										62
									
								
								demos/nwjs/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										62
									
								
								demos/nwjs/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		wb.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(wb, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var _gaq = _gaq || [];
 | 
			
		||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 | 
			
		||||
	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 | 
			
		||||
	var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			data = new Uint8Array(data);
 | 
			
		||||
			process_wb(X.read(data, {type: 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
 | 
			
		||||
	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');
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
							
								
								
									
										10
									
								
								demos/nwjs/package.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										10
									
								
								demos/nwjs/package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
{
 | 
			
		||||
	"name": "sheetjs-nwjs",
 | 
			
		||||
	"author": "sheetjs",
 | 
			
		||||
	"version": "0.0.0",
 | 
			
		||||
	"main": "index.html",
 | 
			
		||||
	"dependencies": {
 | 
			
		||||
		"nw": "~0.24.4",
 | 
			
		||||
		"xlsx": "*"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/nwjs/xlsx.full.min.js
									
									
									
									
										vendored
									
									
										Symbolic link
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/nwjs/xlsx.full.min.js
									
									
									
									
										vendored
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../../dist/xlsx.full.min.js
 | 
			
		||||
							
								
								
									
										2
									
								
								demos/react/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/react/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
SheetJS
 | 
			
		||||
.next
 | 
			
		||||
							
								
								
									
										22
									
								
								demos/react/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										22
									
								
								demos/react/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
.PHONY: react
 | 
			
		||||
react: ## Simple server for react and clones
 | 
			
		||||
	python -mSimpleHTTPServer
 | 
			
		||||
 | 
			
		||||
.PHONY: next
 | 
			
		||||
next: ## next.js demo
 | 
			
		||||
	# next doesn't support jsx extension
 | 
			
		||||
	mkdir -p pages
 | 
			
		||||
	cp sheetjs.jsx pages/sheetjs.js
 | 
			
		||||
	next
 | 
			
		||||
 | 
			
		||||
.PHONY: native
 | 
			
		||||
native: ## Build react-native project
 | 
			
		||||
	bash ./native.sh
 | 
			
		||||
 | 
			
		||||
.PHONY: ios
 | 
			
		||||
ios: native ## react-native ios sim
 | 
			
		||||
	cd SheetJS; react-native run-ios; cd -
 | 
			
		||||
 | 
			
		||||
.PHONY: android
 | 
			
		||||
android: native ## react-native android sim
 | 
			
		||||
	cd SheetJS; react-native run-android; cd -
 | 
			
		||||
							
								
								
									
										68
									
								
								demos/react/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										68
									
								
								demos/react/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
			
		||||
# React
 | 
			
		||||
 | 
			
		||||
The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped
 | 
			
		||||
into web pages with script tags e.g.
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The library can also be imported directly from JSX code with:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import * as XLSX from 'xlsx';
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This demo shows a simple JSX component transpiled in the browser using the babel
 | 
			
		||||
standalone library.  Since there is no standard React table model, this demo
 | 
			
		||||
settles on the array of arrays approach.
 | 
			
		||||
 | 
			
		||||
Other scripts in this demo show:
 | 
			
		||||
- server-rendered React component (with `next.js`)
 | 
			
		||||
- `preact` using the react compatibility library
 | 
			
		||||
- `react-native` deployment for iOS and android
 | 
			
		||||
 | 
			
		||||
## Internal State
 | 
			
		||||
 | 
			
		||||
The simplest state representation is an array of arrays.  To avoid having the
 | 
			
		||||
table component depend on the library, the column labels are precomputed.  The
 | 
			
		||||
state in this demo is shaped like the following object:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{
 | 
			
		||||
  cols: [
 | 
			
		||||
    { name: "A", key: 0 },
 | 
			
		||||
    { name: "B", key: 1 },
 | 
			
		||||
    { name: "C", key: 2 },
 | 
			
		||||
  ],
 | 
			
		||||
  data: [
 | 
			
		||||
    [ "id",    "name", "value" ],
 | 
			
		||||
    [    1, "sheetjs",    7262 ]
 | 
			
		||||
    [    2, "js-xlsx",    6969 ]
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The appropriate state model is application-specific.
 | 
			
		||||
 | 
			
		||||
## React Native
 | 
			
		||||
 | 
			
		||||
<img src="screen.png" width="400px"/>
 | 
			
		||||
 | 
			
		||||
Reproducing the full project is straightforward:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
react-native init SheetJS
 | 
			
		||||
cd SheetJS
 | 
			
		||||
npm i -S xlsx react react-native react-native-table-component react-native-fs
 | 
			
		||||
cp ../react-native.js index.ios.js
 | 
			
		||||
cp ../react-native.js index.android.js
 | 
			
		||||
react-native link
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This uses `react-native-fs` to read and write files on devices.  The app will
 | 
			
		||||
prompt before reading and after writing data.  The printed location will be:
 | 
			
		||||
 | 
			
		||||
- android: path in the device filesystem
 | 
			
		||||
- iOS simulator: local path to file
 | 
			
		||||
- iOS device: a path accessible from iTunes App Documents view
 | 
			
		||||
							
								
								
									
										40
									
								
								demos/react/index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										40
									
								
								demos/react/index.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
 | 
			
		||||
<!-- vim: set ts=2: -->
 | 
			
		||||
<html lang="en" style="height: 100%">
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 | 
			
		||||
<title>SheetJS React Demo</title>
 | 
			
		||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
 | 
			
		||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js"></script>
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js"></script>
 | 
			
		||||
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 | 
			
		||||
<script src="https://unpkg.com/file-saver/FileSaver.js"></script>
 | 
			
		||||
<style>body, #app { height: 100%; };</style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
<h1><a href="http://sheetjs.com">SheetJS React Demo</a></h1>
 | 
			
		||||
<br />
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a><br />
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a><br /><br />
 | 
			
		||||
</div>
 | 
			
		||||
<div id="app" class="container-fluid"></div>
 | 
			
		||||
<script type="text/babel" src="sheetjs.jsx"></script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
	var _gaq = _gaq || [];
 | 
			
		||||
	_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
	_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
	(function() {
 | 
			
		||||
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 | 
			
		||||
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 | 
			
		||||
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 | 
			
		||||
	})();
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/babel">
 | 
			
		||||
	ReactDOM.render( <SheetJSApp />, document.getElementById('app') );
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										17
									
								
								demos/react/native.sh
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										17
									
								
								demos/react/native.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
if [ ! -e SheetJS ]; then
 | 
			
		||||
	react-native init SheetJS
 | 
			
		||||
	cd SheetJS
 | 
			
		||||
	npm i -S xlsx react react-native react-native-table-component react-native-fs
 | 
			
		||||
	cd -
 | 
			
		||||
fi
 | 
			
		||||
if [ ! -e SheetJS/logo.png ]; then
 | 
			
		||||
	curl -O http://oss.sheetjs.com/assets/img/logo.png
 | 
			
		||||
	mv logo.png SheetJS/logo.png
 | 
			
		||||
fi
 | 
			
		||||
cp react-native.js SheetJS/index.ios.js
 | 
			
		||||
cp react-native.js SheetJS/index.android.js
 | 
			
		||||
cd SheetJS;
 | 
			
		||||
react-native link
 | 
			
		||||
cd -;
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/react/pages/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/react/pages/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
sheetjs.js
 | 
			
		||||
							
								
								
									
										26
									
								
								demos/react/pages/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								demos/react/pages/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
import Head from 'next/head'
 | 
			
		||||
import SheetJSApp from './sheetjs.js'
 | 
			
		||||
export default () => (
 | 
			
		||||
<div>
 | 
			
		||||
	<Head>
 | 
			
		||||
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 | 
			
		||||
		<title>SheetJS React Demo</title>
 | 
			
		||||
		<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
 | 
			
		||||
		<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
 | 
			
		||||
		<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js"></script>
 | 
			
		||||
		<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js"></script>
 | 
			
		||||
		<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 | 
			
		||||
		<script src="https://unpkg.com/file-saver/FileSaver.js"></script>
 | 
			
		||||
		<style jsx>{`
 | 
			
		||||
			body, #app { height: 100%; };
 | 
			
		||||
		`}</style>
 | 
			
		||||
	</Head>
 | 
			
		||||
	<div class="container-fluid">
 | 
			
		||||
		<h1><a href="http://sheetjs.com">SheetJS React Demo</a></h1>
 | 
			
		||||
		<br />
 | 
			
		||||
		<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a><br />
 | 
			
		||||
		<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a><br /><br />
 | 
			
		||||
	</div>
 | 
			
		||||
	<SheetJSApp />
 | 
			
		||||
</div>
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										42
									
								
								demos/react/preact.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										42
									
								
								demos/react/preact.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
 | 
			
		||||
<!-- vim: set ts=2: -->
 | 
			
		||||
<html lang="en" style="height: 100%">
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 | 
			
		||||
<title>SheetJS React Demo</title>
 | 
			
		||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
 | 
			
		||||
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
 | 
			
		||||
<script src="//unpkg.com/preact"></script>
 | 
			
		||||
<script src="//unpkg.com/proptypes"></script>
 | 
			
		||||
<script src="//unpkg.com/preact-compat"></script>
 | 
			
		||||
<script>var React = preactCompat, ReactDOM = preactCompat;</script>
 | 
			
		||||
<script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
 | 
			
		||||
<script src="https://unpkg.com/file-saver/FileSaver.js"></script>
 | 
			
		||||
<style>body, #app { height: 100%; };</style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div class="container-fluid">
 | 
			
		||||
<h1><a href="http://sheetjs.com">SheetJS React Demo</a></h1>
 | 
			
		||||
<br />
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a><br />
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a><br /><br />
 | 
			
		||||
</div>
 | 
			
		||||
<div id="app" class="container-fluid"></div>
 | 
			
		||||
<script type="text/babel" src="sheetjs.jsx"></script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
	var _gaq = _gaq || [];
 | 
			
		||||
	_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
	_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
	(function() {
 | 
			
		||||
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 | 
			
		||||
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 | 
			
		||||
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 | 
			
		||||
	})();
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/babel">
 | 
			
		||||
	ReactDOM.render( <SheetJSApp />, document.getElementById('app') );
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										76
									
								
								demos/react/react-native.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										76
									
								
								demos/react/react-native.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,76 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
 | 
			
		||||
import * as XLSX from 'xlsx';
 | 
			
		||||
 | 
			
		||||
import React, { Component } from 'react';
 | 
			
		||||
import { AppRegistry, StyleSheet, Text, View, Button, Alert, Image } from 'react-native';
 | 
			
		||||
import { Table, Row, Rows } from 'react-native-table-component';
 | 
			
		||||
import { writeFile, readFile, DocumentDirectoryPath } from 'react-native-fs'
 | 
			
		||||
 | 
			
		||||
const DDP = DocumentDirectoryPath + "/";
 | 
			
		||||
 | 
			
		||||
const make_cols = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, (x,i) => XLSX.utils.encode_col(i));
 | 
			
		||||
 | 
			
		||||
export default class SheetJS extends Component {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		super(props);
 | 
			
		||||
		this.state = {
 | 
			
		||||
			data: [[1,2,3],[4,5,6]],
 | 
			
		||||
			cols: make_cols("A1:C2")
 | 
			
		||||
		};
 | 
			
		||||
		this.importFile = this.importFile.bind(this);
 | 
			
		||||
		this.exportFile = this.exportFile.bind(this);
 | 
			
		||||
	};
 | 
			
		||||
	importFile() {
 | 
			
		||||
		Alert.alert("Rename file to sheetjs.xlsx", "Copy to " + DDP, [
 | 
			
		||||
			{text: 'Cancel', onPress: () => {}, style: 'cancel' },
 | 
			
		||||
			{text: 'Import', onPress: () => {
 | 
			
		||||
				readFile(DDP + "sheetjs.xlsx", 'ascii').then((res) => {
 | 
			
		||||
					const wb = XLSX.read(res, {type:'binary'});
 | 
			
		||||
					const wsname = wb.SheetNames[0];
 | 
			
		||||
					const ws = wb.Sheets[wsname];
 | 
			
		||||
					const data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
					this.setState({ data: data, cols: make_cols(ws['!ref']) });
 | 
			
		||||
				}).catch((err) => { Alert.alert("importFile Error", "Error " + err.message); });
 | 
			
		||||
			}}
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
	exportFile() {
 | 
			
		||||
		const ws = XLSX.utils.aoa_to_sheet(this.state.data);
 | 
			
		||||
		const wb = XLSX.utils.book_new();
 | 
			
		||||
		XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
		const wbout = XLSX.write(wb, {type:"binary", bookType:"xlsx"});
 | 
			
		||||
		const file = DDP + "sheetjsw.xlsx";
 | 
			
		||||
		writeFile(file, wbout, 'ascii').then((res) =>{
 | 
			
		||||
				Alert.alert("exportFile success", "Exported to " + file);
 | 
			
		||||
		}).catch((err) => { Alert.alert("exportFile Error", "Error " + err.message); });
 | 
			
		||||
	};
 | 
			
		||||
	render() { return (
 | 
			
		||||
<View style={styles.container}>
 | 
			
		||||
	<Image style={{width: 128, height: 128}} source={require('./logo.png')} />
 | 
			
		||||
	<Text style={styles.welcome}>SheetJS React Native Demo</Text>
 | 
			
		||||
	<Text style={styles.instructions}>Import Data</Text>
 | 
			
		||||
	<Button onPress={this.importFile} title="Import data from a spreadsheet" color="#841584" />
 | 
			
		||||
	<Text style={styles.instructions}>Export Data</Text>
 | 
			
		||||
	<Button disabled={!this.state.data.length} onPress={this.exportFile} title="Export data to XLSX" color="#841584" />
 | 
			
		||||
 | 
			
		||||
	<Text style={styles.instructions}>Current Data</Text>
 | 
			
		||||
	<Table style={styles.table}>
 | 
			
		||||
		<Row data={this.state.cols} style={styles.thead} textStyle={styles.text}/>
 | 
			
		||||
		<Rows data={this.state.data} style={styles.tr} textStyle={styles.text}/>
 | 
			
		||||
	</Table>
 | 
			
		||||
</View>
 | 
			
		||||
	); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const styles = StyleSheet.create({
 | 
			
		||||
	container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF' },
 | 
			
		||||
	welcome: { fontSize: 20, textAlign: 'center', margin: 10 },
 | 
			
		||||
	instructions: { textAlign: 'center', color: '#333333', marginBottom: 5 },
 | 
			
		||||
	thead: { height: 40, backgroundColor: '#f1f8ff' },
 | 
			
		||||
	tr: { height: 30 },
 | 
			
		||||
	text: { marginLeft: 5 },
 | 
			
		||||
	table: { width: "100%" }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
AppRegistry.registerComponent('SheetJS', () => SheetJS);
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								demos/react/screen.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								demos/react/screen.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 68 KiB  | 
							
								
								
									
										139
									
								
								demos/react/sheetjs.jsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										139
									
								
								demos/react/sheetjs.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
const SheetJSFT = [
 | 
			
		||||
	"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm"
 | 
			
		||||
].map(function(x) { return "." + x; }).join(",");
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Simple HTML5 file drag-and-drop wrapper
 | 
			
		||||
  usage: <DragDropFile handleFile={handleFile}>...</DragDropFile>
 | 
			
		||||
    handleFile(file:File):void;
 | 
			
		||||
*/
 | 
			
		||||
class DragDropFile extends React.Component {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		super(props);
 | 
			
		||||
		this.onDrop = this.onDrop.bind(this);
 | 
			
		||||
	};
 | 
			
		||||
	suppress(evt) { evt.stopPropagation(); evt.preventDefault(); };
 | 
			
		||||
	onDrop(evt) { evt.stopPropagation(); evt.preventDefault();
 | 
			
		||||
		const files = evt.dataTransfer.files;
 | 
			
		||||
		if(files && files[0]) this.props.handleFile(files[0]);
 | 
			
		||||
	};
 | 
			
		||||
	render() { return (
 | 
			
		||||
<div onDrop={this.onDrop} onDragEnter={this.suppress} onDragOver={this.suppress}>
 | 
			
		||||
	{this.props.children}
 | 
			
		||||
</div>
 | 
			
		||||
	); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Simple HTML5 file input wrapper
 | 
			
		||||
  usage: <DataInput handleFile={callback} />
 | 
			
		||||
    handleFile(file:File):void;
 | 
			
		||||
*/
 | 
			
		||||
class DataInput extends React.Component {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		super(props);
 | 
			
		||||
		this.handleChange = this.handleChange.bind(this);
 | 
			
		||||
	};
 | 
			
		||||
	handleChange(e) {
 | 
			
		||||
		const files = e.target.files;
 | 
			
		||||
		if(files && files[0]) this.props.handleFile(files[0]);
 | 
			
		||||
	};
 | 
			
		||||
	render() { return (
 | 
			
		||||
<form className="form-inline">
 | 
			
		||||
	<div className="form-group">
 | 
			
		||||
		<label htmlFor="file">Spreadsheet</label>
 | 
			
		||||
		<input type="file" className="form-control" id="file" accept={SheetJSFT} onChange={this.handleChange} />
 | 
			
		||||
	</div>
 | 
			
		||||
</form>
 | 
			
		||||
	); };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* generate an array of column objects */
 | 
			
		||||
const make_cols = refstr => Array(XLSX.utils.decode_range(refstr).e.c + 1).fill(0).map((x,i) => ({name:XLSX.utils.encode_col(i), key:i}));
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  Simple HTML Table
 | 
			
		||||
  usage: <OutTable data={data} cols={cols} />
 | 
			
		||||
    data:Array<Array<any> >;
 | 
			
		||||
    cols:Array<{name:string, key:number|string}>;
 | 
			
		||||
*/
 | 
			
		||||
class OutTable extends React.Component {
 | 
			
		||||
	constructor(props) { super(props); };
 | 
			
		||||
	render() { return (
 | 
			
		||||
<div className="table-responsive">
 | 
			
		||||
	<table className="table table-striped">
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>{this.props.cols.map((c) => <th>{c.name}</th>)}</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tbody>
 | 
			
		||||
			{this.props.data.map(r => <tr>
 | 
			
		||||
				{this.props.cols.map(c => <td key={c.key}>{ r[c.key] }</td>)}
 | 
			
		||||
			</tr>)}
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>
 | 
			
		||||
	); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* see Browser download file example in docs */
 | 
			
		||||
function s2ab(s) {
 | 
			
		||||
  const buf = new ArrayBuffer(s.length);
 | 
			
		||||
  const view = new Uint8Array(buf);
 | 
			
		||||
  for (let i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SheetJSApp extends React.Component {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		super(props);
 | 
			
		||||
		this.state = {
 | 
			
		||||
			data: [], /* Array of Arrays e.g. [["a","b"],[1,2]] */
 | 
			
		||||
			cols: []  /* Array of column objects e.g. { name: "C", key: 2 } */
 | 
			
		||||
		};
 | 
			
		||||
		this.handleFile = this.handleFile.bind(this);
 | 
			
		||||
		this.exportFile = this.exportFile.bind(this);
 | 
			
		||||
	};
 | 
			
		||||
	handleFile(file/*:File*/) {
 | 
			
		||||
		/* Boilerplate to set up FileReader */
 | 
			
		||||
		const reader = new FileReader();
 | 
			
		||||
		reader.onload = (e) => {
 | 
			
		||||
			/* Parse data */
 | 
			
		||||
			const bstr = e.target.result;
 | 
			
		||||
			const wb = XLSX.read(bstr, {type:'binary'});
 | 
			
		||||
			/* Get first worksheet */
 | 
			
		||||
			const wsname = wb.SheetNames[0];
 | 
			
		||||
			const ws = wb.Sheets[wsname];
 | 
			
		||||
			/* Convert array of arrays */
 | 
			
		||||
			const data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
			/* Update state */
 | 
			
		||||
			this.setState({ data: data, cols: make_cols(ws['!ref']) });
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsBinaryString(file);
 | 
			
		||||
	};
 | 
			
		||||
	exportFile() {
 | 
			
		||||
		/* convert state to workbook */
 | 
			
		||||
		const ws = XLSX.utils.aoa_to_sheet(this.state.data);
 | 
			
		||||
		const wb = XLSX.utils.book_new();
 | 
			
		||||
		XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
		/* generate XLSX file */
 | 
			
		||||
		const wbout = XLSX.write(wb, {type:"binary", bookType:"xlsx"});
 | 
			
		||||
		/* send to client */
 | 
			
		||||
		saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "sheetjs.xlsx");
 | 
			
		||||
	};
 | 
			
		||||
	render() { return (
 | 
			
		||||
<DragDropFile handleFile={this.handleFile}>
 | 
			
		||||
	<div className="row"><div className="col-xs-12">
 | 
			
		||||
		<DataInput handleFile={this.handleFile} />
 | 
			
		||||
	</div></div>
 | 
			
		||||
	<div className="row"><div className="col-xs-12">
 | 
			
		||||
		<button disabled={!this.state.data.length} className="btn btn-success" onClick={this.exportFile}>Export</button>
 | 
			
		||||
	</div></div>
 | 
			
		||||
	<div className="row"><div className="col-xs-12">
 | 
			
		||||
		<OutTable data={this.state.data} cols={this.state.cols} />
 | 
			
		||||
	</div></div>
 | 
			
		||||
</DragDropFile>
 | 
			
		||||
); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if(typeof module !== 'undefined') module.exports = SheetJSApp
 | 
			
		||||
							
								
								
									
										21
									
								
								demos/server/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								demos/server/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init:
 | 
			
		||||
	if [ ! -e sheetjs.xlsx ]; then ln -s ../../sheetjs.xlsx; fi
 | 
			
		||||
	mkdir -p node_modules
 | 
			
		||||
	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd -
 | 
			
		||||
 | 
			
		||||
.PHONY: request
 | 
			
		||||
request: init ## request demo
 | 
			
		||||
	node _request.js
 | 
			
		||||
 | 
			
		||||
.PHONY: express
 | 
			
		||||
express: init ## express demo
 | 
			
		||||
	node express.js
 | 
			
		||||
 | 
			
		||||
.PHONY: micro
 | 
			
		||||
micro: init ## micro demo
 | 
			
		||||
	micro -p 7262 micro.js
 | 
			
		||||
 | 
			
		||||
.PHONY: koa
 | 
			
		||||
koa: init ## koa demo
 | 
			
		||||
	node koa.js
 | 
			
		||||
							
								
								
									
										96
									
								
								demos/server/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										96
									
								
								demos/server/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
			
		||||
# NodeJS Server Deployments
 | 
			
		||||
 | 
			
		||||
This library is 100% pure JS.  This is great for compatibility but tends to lock
 | 
			
		||||
up long-running processes.  In the web browser, Web Workers are used to offload
 | 
			
		||||
work from the main browser thread.  In NodeJS, there are other strategies.  This
 | 
			
		||||
demo shows a few different strategies applied to different server frameworks.
 | 
			
		||||
 | 
			
		||||
NOTE: these examples merely demonstrate the core concepts and do not include
 | 
			
		||||
appropriate error checking or other production-level features.
 | 
			
		||||
 | 
			
		||||
### Node Buffer
 | 
			
		||||
 | 
			
		||||
The `read` and `write` functions can handle `Buffer` data with `type:"buffer"`.
 | 
			
		||||
For example, the `request` library returns data in a buffer:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var XLSX = require('xlsx'), request = require('request');
 | 
			
		||||
request(url, {encoding: null}, function(err, res, data) {
 | 
			
		||||
	if(err || res.statusCode !== 200) return;
 | 
			
		||||
 | 
			
		||||
	/* data is a node Buffer that can be passed to XLSX.read */
 | 
			
		||||
	var workbook = XLSX.read(data, {type:'buffer'});
 | 
			
		||||
 | 
			
		||||
	/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Example servers
 | 
			
		||||
 | 
			
		||||
Each example server is expected to hold an array-of-arrays in memory.  They are
 | 
			
		||||
expected to handle:
 | 
			
		||||
 | 
			
		||||
- `POST /         ` accepts an encoded `file` and updates the internal storage
 | 
			
		||||
- `GET  /?t=<type>` returns the internal storage in the specified type
 | 
			
		||||
- `POST /?f=<name>` reads the local file and updates the internal storage
 | 
			
		||||
- `GET  /?f=<name>` writes the file to the specified name
 | 
			
		||||
 | 
			
		||||
Testing with cURL is straightforward:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# upload test.xls and update data
 | 
			
		||||
curl -X POST -F "data=@test.xls" http://localhost:7262/
 | 
			
		||||
# download data in SYLK format
 | 
			
		||||
curl -X GET http://localhost:7262/?t=slk
 | 
			
		||||
# read sheetjs.xlsx from the server directory
 | 
			
		||||
curl -X POST http://localhost:7262/?f=sheetjs.xlsx
 | 
			
		||||
# write sheetjs.xlsb in the XLSB format
 | 
			
		||||
curl -X GET http://localhost:7262/?f=sheetjs.xlsb
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Main-process logic with express
 | 
			
		||||
 | 
			
		||||
The most straightforward approach is to handle the data directly in HTTP event
 | 
			
		||||
handlers.  The `buffer` type for `XLSX.read` and `XLSX.write` work with `http`
 | 
			
		||||
module and with express directly.  The following snippet generates a workbook
 | 
			
		||||
based on an array of arrays and sends it to the client:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
function send_aoa_to_client(req, res, data, bookType) {
 | 
			
		||||
	/* generate workbook */
 | 
			
		||||
	var ws = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
	var wb = XLSX.utils.book_new();
 | 
			
		||||
	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
 | 
			
		||||
	/* generate buffer */
 | 
			
		||||
	var buf = XLSX.write(wb, {type:'buffer', bookType:bookType || "xlsx"});
 | 
			
		||||
 | 
			
		||||
	/* send to client */
 | 
			
		||||
	res.status(200).send(buf);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## fork with koa
 | 
			
		||||
 | 
			
		||||
`child_process.fork` provides a light-weight and customizable way to offload
 | 
			
		||||
work from the main server process.  This demo passes commands to a custom child
 | 
			
		||||
process and the child passes back buffers of data.
 | 
			
		||||
 | 
			
		||||
The main server script is `koa.js` and the worker script is `koasub.js`.  State
 | 
			
		||||
is maintained in the worker script.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## xlsx script with micro
 | 
			
		||||
 | 
			
		||||
The node module ships with the `xlsx` bin script.  For global installs, symlinks
 | 
			
		||||
are configured to enable running `xlsx` from anywhere.  For local installs, the
 | 
			
		||||
appropriate symlink is set up in `node_modules/.bin/`.
 | 
			
		||||
 | 
			
		||||
The `--arrays` option directs `xlsx` to generate an array of arrays that can be
 | 
			
		||||
parsed by the server.  To generate files, the `json2csv` module exports the JS
 | 
			
		||||
array of arrays to a CSV, the server writes the file, and the `xlsx` command is
 | 
			
		||||
used to generate files of different formats.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								demos/server/_cors.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								demos/server/_cors.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var cors = function(req, res) { res.header('Access-Control-Allow-Origin', '*'); };
 | 
			
		||||
cors.mw = function(req, res, next) { cors(req, res); next(); };
 | 
			
		||||
module.exports = cors;
 | 
			
		||||
							
								
								
									
										7
									
								
								demos/server/_logit.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										7
									
								
								demos/server/_logit.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var sprintf = require('printj').sprintf;
 | 
			
		||||
var logit = function(req, res) {
 | 
			
		||||
	console.log(sprintf("%s %s %d", req.method, req.url, res.statusCode));
 | 
			
		||||
};
 | 
			
		||||
logit.mw = function(req, res, next) { logit(req, res); next(); }
 | 
			
		||||
module.exports = logit;
 | 
			
		||||
							
								
								
									
										9
									
								
								demos/server/_request.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								demos/server/_request.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('xlsx'), request = require('request');
 | 
			
		||||
var url = 'http://www.freddiemac.com/pmms/2017/historicalweeklydata.xls'
 | 
			
		||||
request(url, {encoding: null}, function(err, res, data) {
 | 
			
		||||
	if(err || res.statusCode !== 200) return;
 | 
			
		||||
	var wb = XLSX.read(data, {type:'buffer'});
 | 
			
		||||
	var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
	console.log(XLSX.utils.sheet_to_csv(ws, {blankrows:false}));
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										65
									
								
								demos/server/express.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										65
									
								
								demos/server/express.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
 | 
			
		||||
var fs = require('fs'), path = require('path'), URL = require('url');
 | 
			
		||||
var express = require('express'), app = express();
 | 
			
		||||
var sprintf = require('printj').sprintf;
 | 
			
		||||
var logit = require('./_logit');
 | 
			
		||||
var cors = require('./_cors');
 | 
			
		||||
var data = "a,b,c\n1,2,3".split("\n").map(function(x) { return x.split(","); });
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
 | 
			
		||||
/* helper to generate the workbook object */
 | 
			
		||||
function make_book() {
 | 
			
		||||
	var ws = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
	var wb = XLSX.utils.book_new();
 | 
			
		||||
	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
	return wb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_data(req, res, type) {
 | 
			
		||||
	var wb = make_book();
 | 
			
		||||
	/* send buffer back */
 | 
			
		||||
	res.status(200).send(XLSX.write(wb, {type:'buffer', bookType:type}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_file(req, res, file) {
 | 
			
		||||
	var wb = make_book();
 | 
			
		||||
	/* write using XLSX.writeFile */
 | 
			
		||||
	XLSX.writeFile(wb, file);
 | 
			
		||||
	res.status(200).send("wrote to " + file + "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function load_data(file) {
 | 
			
		||||
	var wb = XLSX.readFile(file);
 | 
			
		||||
	/* generate array of arrays */
 | 
			
		||||
	data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {header:1});
 | 
			
		||||
	console.log(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_data(req, res) {
 | 
			
		||||
	var keys = Object.keys(req.files), k = keys[0];
 | 
			
		||||
	load_data(req.files[k].path);
 | 
			
		||||
	res.status(200).send("ok\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_file(req, res, file) {
 | 
			
		||||
	load_data(file);
 | 
			
		||||
	res.status(200).send("ok\n");
 | 
			
		||||
}
 | 
			
		||||
app.use(logit.mw);
 | 
			
		||||
app.use(cors.mw);
 | 
			
		||||
app.use(require('express-formidable')());
 | 
			
		||||
app.get('/', function(req, res, next) {
 | 
			
		||||
	var url = URL.parse(req.url, true);
 | 
			
		||||
	if(url.query.t) return get_data(req, res, url.query.t);
 | 
			
		||||
	else if(url.query.f) return get_file(req, res, url.query.f);
 | 
			
		||||
	res.status(403).end("Forbidden");
 | 
			
		||||
});
 | 
			
		||||
app.post('/', function(req, res, next) {
 | 
			
		||||
	var url = URL.parse(req.url, true);
 | 
			
		||||
	if(url.query.f) return post_file(req, res, url.query.f);
 | 
			
		||||
	return post_data(req, res);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
var port = +process.argv[2] || +process.env.PORT || 7262;
 | 
			
		||||
app.listen(port, function() { console.log('Serving HTTP on port ' + port); });
 | 
			
		||||
							
								
								
									
										41
									
								
								demos/server/hapi.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										41
									
								
								demos/server/hapi.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var Hapi = require('hapi'), server = new Hapi.Server();
 | 
			
		||||
var logit = require('./_logit');
 | 
			
		||||
var Worker = require('webworker-threads').Worker;
 | 
			
		||||
var data = "a,b,c\n1,2,3".split("\n").map(x => x.split(","));
 | 
			
		||||
 | 
			
		||||
function get_data(req, res, type) {
 | 
			
		||||
	var work = new Worker(function(){
 | 
			
		||||
		var XLSX = require('xlsx');
 | 
			
		||||
		this.onmessage = function(e) {
 | 
			
		||||
			console.log("get data " + e.data);
 | 
			
		||||
			var ws = XLSX.utils.aoa_to_sheet(e.data[1]);
 | 
			
		||||
			var wb = XLSX.utils.book_new();
 | 
			
		||||
			XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
			console.log("prepared wb");
 | 
			
		||||
			postMessage(XLSX.write(wb, {type:'binary', bookType:type}));
 | 
			
		||||
			console.log("sent data");
 | 
			
		||||
		};
 | 
			
		||||
	});
 | 
			
		||||
	work.onmessage = function(e) { console.log(e); res(e); };
 | 
			
		||||
	work.postMessage([type, data]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var port = 7262;
 | 
			
		||||
server.connection({ host:'localhost', port: port});
 | 
			
		||||
 | 
			
		||||
server.route({ method: 'GET', path: '/', handler: function(req, res) {
 | 
			
		||||
	logit(req.raw.req, req.raw.res);
 | 
			
		||||
	if(req.query.t) return get_data(req, res, req.query.t);
 | 
			
		||||
	else if(req.query.f) return get_file(req, res, req.query.f);
 | 
			
		||||
	return res('Forbidden').code(403);
 | 
			
		||||
}});
 | 
			
		||||
server.route({ method: 'POST', path: '/', handler: function(req, res) {
 | 
			
		||||
	logit(req.raw.req, req.raw.res);
 | 
			
		||||
	if(req.query.f) return post_file(req, res, req.query.f);
 | 
			
		||||
	return post_data(req, res);
 | 
			
		||||
}});
 | 
			
		||||
server.start(function(err) {
 | 
			
		||||
	if(err) throw err;
 | 
			
		||||
	console.log('Serving HTTP on port ' + port);
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										79
									
								
								demos/server/koa.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										79
									
								
								demos/server/koa.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
 | 
			
		||||
const Koa = require('koa'), app = new Koa();
 | 
			
		||||
const { sprintf } = require('printj');
 | 
			
		||||
const { IncomingForm } = require('formidable');
 | 
			
		||||
const { fork } = require('child_process');
 | 
			
		||||
const logit = require('./_logit');
 | 
			
		||||
const subprocess = fork('koasub.js');
 | 
			
		||||
 | 
			
		||||
const get_data = async (ctx, type) => {
 | 
			
		||||
	await new Promise((resolve, reject) => {
 | 
			
		||||
		const cb = (data) => {
 | 
			
		||||
			ctx.response.body = Buffer(data);
 | 
			
		||||
			subprocess.removeListener('message', cb);
 | 
			
		||||
			resolve();
 | 
			
		||||
		};
 | 
			
		||||
		subprocess.on('message', cb);
 | 
			
		||||
		subprocess.send(['get data', type]);
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const get_file = async (ctx, file) => {
 | 
			
		||||
	await new Promise((resolve, reject) => {
 | 
			
		||||
		const cb = (data) => {
 | 
			
		||||
			ctx.response.body = Buffer(data);
 | 
			
		||||
			subprocess.removeListener('message', cb);
 | 
			
		||||
			resolve();
 | 
			
		||||
		};
 | 
			
		||||
		subprocess.on('message', cb);
 | 
			
		||||
		subprocess.send(['get file', file]);
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const load_data = async (ctx, file) => {
 | 
			
		||||
	await new Promise((resolve, reject) => {
 | 
			
		||||
		const cb = (data) => {
 | 
			
		||||
			ctx.response.body = "ok\n";
 | 
			
		||||
			subprocess.removeListener('message', cb);
 | 
			
		||||
			resolve();
 | 
			
		||||
		};
 | 
			
		||||
		subprocess.on('message', cb);
 | 
			
		||||
		subprocess.send(['load data', file]);
 | 
			
		||||
	});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const post_data = async (ctx) => {
 | 
			
		||||
	const keys = Object.keys(ctx.request._files), k = keys[0];
 | 
			
		||||
	await load_data(ctx, ctx.request._files[k].path);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
app.use(async (ctx, next) => { logit(ctx.req, ctx.res); await next(); });
 | 
			
		||||
app.use(async (ctx, next) => {
 | 
			
		||||
	const form = new IncomingForm();
 | 
			
		||||
	await new Promise((resolve, reject) => {
 | 
			
		||||
		form.parse(ctx.req, (err, fields, files) => {
 | 
			
		||||
			if(err) return reject(err);
 | 
			
		||||
			ctx.request._fields = fields;
 | 
			
		||||
			ctx.request._files = files;
 | 
			
		||||
			resolve();
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
	await next();
 | 
			
		||||
});
 | 
			
		||||
app.use(async (ctx, next) => {
 | 
			
		||||
	if(ctx.request.method !== 'GET') await next();
 | 
			
		||||
	else if(ctx.request.path !== '/') await next();
 | 
			
		||||
	else if(ctx.request.query.t) await get_data(ctx, ctx.request.query.t);
 | 
			
		||||
	else if(ctx.request.query.f) await get_file(ctx, ctx.request.query.f);
 | 
			
		||||
	else ctx.throw(403, "Forbidden");
 | 
			
		||||
});
 | 
			
		||||
app.use(async (ctx, next) => {
 | 
			
		||||
	if(ctx.request.method !== 'POST') await next();
 | 
			
		||||
	else if(ctx.request.path !== '/') await next();
 | 
			
		||||
	else if(ctx.request.query.f) await load_data(ctx, ctx.request.query.f);
 | 
			
		||||
	else await post_data(ctx);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const port = +process.argv[2] || +process.env.PORT || 7262;
 | 
			
		||||
app.listen(port, () => { console.log('Serving HTTP on port ' + port); });
 | 
			
		||||
							
								
								
									
										39
									
								
								demos/server/koasub.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										39
									
								
								demos/server/koasub.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
const XLSX = require('xlsx');
 | 
			
		||||
let data = "a,b,c\n1,2,3".split("\n").map(x => x.split(","));
 | 
			
		||||
process.on('message', ([m, data] = _) => {
 | 
			
		||||
	switch(m) {
 | 
			
		||||
		case 'load data': load_data(data); break;
 | 
			
		||||
		case 'get data': get_data(data); break;
 | 
			
		||||
		case 'get file': get_file(data); break;
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function load_data(file) {
 | 
			
		||||
	var wb = XLSX.readFile(file);
 | 
			
		||||
	/* generate array of arrays */
 | 
			
		||||
	data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {header:1});
 | 
			
		||||
	console.log(data);
 | 
			
		||||
	process.send("done");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* helper to generate the workbook object */
 | 
			
		||||
function make_book() {
 | 
			
		||||
	var ws = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
	var wb = XLSX.utils.book_new();
 | 
			
		||||
	XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
	return wb;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_data(type) {
 | 
			
		||||
	var wb = make_book();
 | 
			
		||||
	/* send buffer back */
 | 
			
		||||
	process.send(XLSX.write(wb, {type:'buffer', bookType:type}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_file(file) {
 | 
			
		||||
	var wb = make_book();
 | 
			
		||||
	/* write using XLSX.writeFile */
 | 
			
		||||
	XLSX.writeFile(wb, file);
 | 
			
		||||
	process.send("wrote to " + file + "\n");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								demos/server/micro.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										85
									
								
								demos/server/micro.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,85 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
var URL = require('url');
 | 
			
		||||
var child_process = require('child_process');
 | 
			
		||||
var micro = require('micro'), formidable = require('formidable');
 | 
			
		||||
var logit = require('./_logit'), cors = require('./_cors');
 | 
			
		||||
var json2csv = require('json2csv');
 | 
			
		||||
var data = "a,b,c\n1,2,3".split("\n").map(function(x) { return x.split(","); });
 | 
			
		||||
var xlsx = '../../bin/xlsx.njs';
 | 
			
		||||
 | 
			
		||||
function get_data(req, res, type) {
 | 
			
		||||
	var file = "_tmp." + type;
 | 
			
		||||
 | 
			
		||||
	/* prepare CSV */
 | 
			
		||||
	var csv = json2csv({data:data, hasCSVColumnTitle:false});
 | 
			
		||||
 | 
			
		||||
	/* write it to a temp file */
 | 
			
		||||
	fs.writeFile('tmp.csv', csv, function(err1) {
 | 
			
		||||
 | 
			
		||||
		/* call xlsx to read the csv and write to another temp file */
 | 
			
		||||
		child_process.exec(xlsx+' tmp.csv -o '+ file, function(err, stdout, stderr){
 | 
			
		||||
			cors(req, res);
 | 
			
		||||
			/* read the new file and send it to the client */
 | 
			
		||||
			micro.send(res, 200, fs.readFileSync(file));
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_file(req, res, file) {
 | 
			
		||||
	var csv = json2csv({data:data, hasCSVColumnTitle:false});
 | 
			
		||||
	fs.writeFile('tmp.csv', csv, function(err1) {
 | 
			
		||||
		/* write to specified file */
 | 
			
		||||
		child_process.exec(xlsx+' tmp.csv -o '+file, function(err, stdout, stderr) {
 | 
			
		||||
			cors(req, res);
 | 
			
		||||
			micro.send(res, 200, "wrote to " + file + "\n");
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_data(req, res) {
 | 
			
		||||
	var form = new formidable.IncomingForm();
 | 
			
		||||
	form.on('file', function(field, file) {
 | 
			
		||||
		/* file.path is the location of the file in the system */
 | 
			
		||||
		child_process.exec(xlsx+' --arrays ' + file.path, post_cb(req, res));
 | 
			
		||||
	});
 | 
			
		||||
	form.parse(req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_file(req, res, file) {
 | 
			
		||||
	child_process.exec(xlsx+' --arrays ' + file, post_cb(req, res));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_cb(req, res) {
 | 
			
		||||
	return function(err, stdout, stderr) {
 | 
			
		||||
		cors(req, res);
 | 
			
		||||
		/* xlsx --arrays writes JSON to stdout, so parse and assign to data var */
 | 
			
		||||
		data = JSON.parse(stdout);
 | 
			
		||||
		console.log(data);
 | 
			
		||||
		return micro.send(res, 200, "ok\n");
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get(req, res) {
 | 
			
		||||
	var url = URL.parse(req.url, true);
 | 
			
		||||
	if(url.pathname.length > 1) micro.send(res, 404, "File not found");
 | 
			
		||||
	else if(url.query.t) get_data(req, res, url.query.t);
 | 
			
		||||
	else if(url.query.f) get_file(req, res, url.query.f);
 | 
			
		||||
	else micro.send(res, 403, "Forbidden\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post(req, res) {
 | 
			
		||||
	var url = URL.parse(req.url, true);
 | 
			
		||||
	if(url.pathname.length > 1) micro.send(res, 404, "File not found");
 | 
			
		||||
	else if(url.query.f) post_file(req, res, url.query.f);
 | 
			
		||||
	else post_data(req, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = function(req, res) {
 | 
			
		||||
	logit(req, res);
 | 
			
		||||
	switch(req.method) {
 | 
			
		||||
		case 'GET': return get(req, res);
 | 
			
		||||
		case 'POST': return post(req, res);
 | 
			
		||||
	}
 | 
			
		||||
	return micro.send(res, 501, "Unsupported method " + req.method + "\n");
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										2
									
								
								demos/vue/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/vue/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
SheetJS
 | 
			
		||||
.nuxt
 | 
			
		||||
							
								
								
									
										17
									
								
								demos/vue/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										17
									
								
								demos/vue/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
.PHONY: vue
 | 
			
		||||
vue: ## Simple server for vue
 | 
			
		||||
	python -mSimpleHTTPServer
 | 
			
		||||
 | 
			
		||||
.PHONY: nuxt
 | 
			
		||||
nuxt: ## nuxt.js demo
 | 
			
		||||
	mkdir -p node_modules
 | 
			
		||||
	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd ..
 | 
			
		||||
	nuxt
 | 
			
		||||
 | 
			
		||||
.PHONY: weex
 | 
			
		||||
weex: ## Build weex project
 | 
			
		||||
	bash ./weex.sh
 | 
			
		||||
 | 
			
		||||
.PHONY: ios
 | 
			
		||||
ios: weex ## weex ios sim
 | 
			
		||||
	cd SheetJS; weexpack run ios; cd -
 | 
			
		||||
@ -13,8 +13,59 @@ as you would with any other browser-friendly library.
 | 
			
		||||
This demo directly generates HTML using `sheet_to_html` and adds an element to
 | 
			
		||||
a pregenerated template.  It also has a button for exporting as XLSX.
 | 
			
		||||
 | 
			
		||||
Other scripts in this demo show:
 | 
			
		||||
- server-rendered VueJS component (with `nuxt.js`)
 | 
			
		||||
- `weex` deployment for iOS
 | 
			
		||||
 | 
			
		||||
## Single File Components
 | 
			
		||||
 | 
			
		||||
For Single File Components, a simple `import XLSX from 'xlsx'` should suffice.
 | 
			
		||||
The webpack demo includes a sample `webpack.config.js`.
 | 
			
		||||
 | 
			
		||||
## WeeX
 | 
			
		||||
 | 
			
		||||
WeeX is a framework for building real mobile apps, akin to React Native.  The
 | 
			
		||||
ecosystem is not quite as mature as React Native, missing basic features like
 | 
			
		||||
document access.  As a result, this demo uses the `stream.fetch` API to upload
 | 
			
		||||
Base64-encoded documents to <https://hastebin.com> and download a precomputed
 | 
			
		||||
[Base64-encoded workbook](http://sheetjs.com/sheetjs.xlsx.b64).
 | 
			
		||||
 | 
			
		||||
Using NodeJS it is straightforward to convert to/from base64:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* convert sheetjs.xlsx -> sheetjs.xlsx.b64 */
 | 
			
		||||
var buf = fs.readFileSync("sheetjs.xlsx");
 | 
			
		||||
fs.writeFileSync("sheetjs.xlsx.b64", buf.toString("base64"));
 | 
			
		||||
 | 
			
		||||
/* convert sheetjs.xls.b64 -> sheetjs.xls */
 | 
			
		||||
var str = fs.readFileSync("sheetjs.xls.b64").toString();
 | 
			
		||||
fs.writeFileSync("sheetjs.xls", new Buffer(str, "base64"));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Nuxt and State
 | 
			
		||||
 | 
			
		||||
The `nuxt.js` demo uses the same state approach as the React next.js demo:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{
 | 
			
		||||
  cols: [
 | 
			
		||||
    { name: "A", key: 0 },
 | 
			
		||||
    { name: "B", key: 1 },
 | 
			
		||||
    { name: "C", key: 2 },
 | 
			
		||||
  ],
 | 
			
		||||
  data: [
 | 
			
		||||
    [ "id",    "name", "value" ],
 | 
			
		||||
    [    1, "sheetjs",    7262 ]
 | 
			
		||||
    [    2, "js-xlsx",    6969 ]
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Due to webpack configuration issues on client/server bundles, the library should
 | 
			
		||||
be explicitly included in the layout HTML (as script tag) and in the component:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const _XLSX = require('xlsx');
 | 
			
		||||
const X = typeof XLSX !== 'undefined' ? XLSX : _XLSX;
 | 
			
		||||
/* use the variable X rather than XLSX in the component */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
 | 
			
		||||
<!-- vim: set ts=2: -->
 | 
			
		||||
<html ng-app="app">
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
	<title>SheetJS + VueJS2</title>
 | 
			
		||||
	<!-- Vue 2 -->
 | 
			
		||||
@ -38,6 +38,17 @@ This demo shows a sample Vue component "html-preview" that:
 | 
			
		||||
 | 
			
		||||
<a href="https://obamawhitehouse.archives.gov/sites/default/files/omb/budget/fy2014/assets/receipts.xls">Sample Spreadsheet</a>
 | 
			
		||||
</pre>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
	var _gaq = _gaq || [];
 | 
			
		||||
	_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
	_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
	(function() {
 | 
			
		||||
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
 | 
			
		||||
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
 | 
			
		||||
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
 | 
			
		||||
	})();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<div id="app">
 | 
			
		||||
	<html-preview></html-preview>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										66
									
								
								demos/vue/native.vue
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										66
									
								
								demos/vue/native.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com -->
 | 
			
		||||
<template>
 | 
			
		||||
	<div class="container">
 | 
			
		||||
		<image :src="logoUrl" class="logo"></image>
 | 
			
		||||
		<text class="welcome">SheetJS WeeX Demo {{version}}</text>
 | 
			
		||||
		<text class="instructions">Import Data</text>
 | 
			
		||||
		<text :style="{ color: '#841584' }" @click="importFile">Download spreadsheet</text>
 | 
			
		||||
		<text class="instructions">Export Data</text>
 | 
			
		||||
		<text :style="{ color: data.length ? '#841584' : '#CDCDCD', disabled: !data.length }" @click="exportFile">Upload XLSX</text>
 | 
			
		||||
		<text style="instructions">Current Data</text>
 | 
			
		||||
		<scroller class="scroller">
 | 
			
		||||
			<div class="row" v-for="(row, ridx) in data">
 | 
			
		||||
				<text>ROW {{ridx + 1}}</text>
 | 
			
		||||
				<text v-for="(cell, cidx) in row">CELL {{get_label(ridx, cidx)}}:{{cell}}</text>
 | 
			
		||||
			</div>
 | 
			
		||||
		</scroller>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.container { height: 100%; flex: 1; justify-content: center; align-items: center; background-color: '#F5FCFF'; }
 | 
			
		||||
.logo { width: 256px; height: 256px; }
 | 
			
		||||
.welcome { font-size: 40; text-align: 'center'; margin: 10; }
 | 
			
		||||
.instructions { padding-top: 20px; color:#888; font-size: 24px;}
 | 
			
		||||
.scroller { height: 500px; border-width: 3px; width: 700px; }
 | 
			
		||||
.loading { justify-content: center; }
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
const modal = weex.requireModule('modal');
 | 
			
		||||
const stream = weex.requireModule('stream');
 | 
			
		||||
export default {
 | 
			
		||||
	data: {
 | 
			
		||||
		data: [[1,2,3],[4,5,6]],
 | 
			
		||||
		logoUrl: 'http://oss.sheetjs.com/assets/img/logo.png',
 | 
			
		||||
		version: XLSX.version,
 | 
			
		||||
		fileUrl: 'http://sheetjs.com/sheetjs.xlsx.b64',
 | 
			
		||||
		binUrl: 'https://hastebin.com/documents'
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		importFile: function (e) {
 | 
			
		||||
			modal.toast({ message: 'getting ' + this.fileUrl, duration: 1 });
 | 
			
		||||
			var self = this;
 | 
			
		||||
			stream.fetch({method:'GET', type:'text', url:this.fileUrl}, function(res){
 | 
			
		||||
				const wb = XLSX.read(res.data, {type:'base64'});
 | 
			
		||||
				const ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
				self.data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		exportFile: function (e) {
 | 
			
		||||
			var self = this;
 | 
			
		||||
			const ws = XLSX.utils.aoa_to_sheet(this.data);
 | 
			
		||||
			const wb = XLSX.utils.book_new();
 | 
			
		||||
			XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
			const wbout = XLSX.write(wb, {type:"base64", bookType:"xlsx"});
 | 
			
		||||
			const body = wbout;
 | 
			
		||||
			stream.fetch({method:'POST', type:'json', url:this.binUrl, body:body}, function(res) {
 | 
			
		||||
				modal.toast({ message: 'KEY: ' + res.data.key, duration: 10 });
 | 
			
		||||
				self.version = res.data.key;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		get_label: function(r, c) { return XLSX.utils.encode_cell({r:r, c:c})}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/vue/package.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/vue/package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
{}
 | 
			
		||||
							
								
								
									
										102
									
								
								demos/vue/pages/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										102
									
								
								demos/vue/pages/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,102 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
<template>
 | 
			
		||||
<div @drop="_drop" @dragenter="_suppress" @dragover="_suppress">
 | 
			
		||||
	<div class="row"><div class="col-xs-12">
 | 
			
		||||
		<form class="form-inline">
 | 
			
		||||
			<div class="form-group">
 | 
			
		||||
				<label for="file">Spreadsheet</label>
 | 
			
		||||
				<input type="file" class="form-control" id="file" :accept="SheetJSFT" @change="_change" />
 | 
			
		||||
			</div>
 | 
			
		||||
		</form>
 | 
			
		||||
	</div></div>
 | 
			
		||||
	<div class="row"><div class="col-xs-12">
 | 
			
		||||
		<button :disabled="data.length ? false : true" class="btn btn-success" @click="_export">Export</button>
 | 
			
		||||
	</div></div>
 | 
			
		||||
	<div class="row"><div class="col-xs-12">
 | 
			
		||||
		<div class="table-responsive">
 | 
			
		||||
			<table class="table table-striped">
 | 
			
		||||
				<thead><tr>
 | 
			
		||||
					<th v-for="c in cols">{{c.name}}</th>
 | 
			
		||||
				</tr></thead>
 | 
			
		||||
				<tbody><tr v-for="r in data">
 | 
			
		||||
					<td v-for="c in cols"> {{ r[c.key] }}</td>
 | 
			
		||||
				</tr></tbody>
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div></div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
const _XLSX = require('xlsx');
 | 
			
		||||
const X = typeof XLSX !== 'undefined' ? XLSX : _XLSX;
 | 
			
		||||
const make_cols = refstr => Array(X.utils.decode_range(refstr).e.c + 1).fill(0).map((x,i) => ({name:X.utils.encode_col(i), key:i}));
 | 
			
		||||
 | 
			
		||||
/* see Browser download file example in docs */
 | 
			
		||||
function s2ab(s) {
 | 
			
		||||
  const buf = new ArrayBuffer(s.length);
 | 
			
		||||
  const view = new Uint8Array(buf);
 | 
			
		||||
  for (let i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const _SheetJSFT = [
 | 
			
		||||
	"xlsx", "xlsb", "xlsm", "xls", "xml", "csv", "txt", "ods", "fods", "uos", "sylk", "dif", "dbf", "prn", "qpw", "123", "wb*", "wq*", "html", "htm"
 | 
			
		||||
].map(function(x) { return "." + x; }).join(",");
 | 
			
		||||
export default {
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			data: ["SheetJS".split(""), "1234567".split("")],
 | 
			
		||||
			cols: [
 | 
			
		||||
				{name:"A", key:0},
 | 
			
		||||
				{name:"B", key:1},
 | 
			
		||||
				{name:"C", key:2},
 | 
			
		||||
				{name:"D", key:3},
 | 
			
		||||
				{name:"E", key:4},
 | 
			
		||||
				{name:"F", key:5},
 | 
			
		||||
				{name:"G", key:6},
 | 
			
		||||
			],
 | 
			
		||||
			SheetJSFT: _SheetJSFT
 | 
			
		||||
	}; },
 | 
			
		||||
	methods: {
 | 
			
		||||
		_suppress(evt) { evt.stopPropagation(); evt.preventDefault(); },
 | 
			
		||||
		_drop(evt) {
 | 
			
		||||
			evt.stopPropagation(); evt.preventDefault();
 | 
			
		||||
			const files = evt.dataTransfer.files;
 | 
			
		||||
			if(files && files[0]) this._file(files[0]);
 | 
			
		||||
		},
 | 
			
		||||
		_change(evt) {
 | 
			
		||||
			const files = evt.target.files;
 | 
			
		||||
			if(files && files[0]) this._file(files[0]);
 | 
			
		||||
		},
 | 
			
		||||
		_export(evt) {
 | 
			
		||||
			/* convert state to workbook */
 | 
			
		||||
			const ws = X.utils.aoa_to_sheet(this.data);
 | 
			
		||||
			const wb = X.utils.book_new();
 | 
			
		||||
			X.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
			/* generate X file */
 | 
			
		||||
			const wbout = X.write(wb, {type:"binary", bookType:"xlsx"});
 | 
			
		||||
			/* send to client */
 | 
			
		||||
			saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "sheetjs.xlsx");
 | 
			
		||||
		},
 | 
			
		||||
		_file(file) {
 | 
			
		||||
			/* Boilerplate to set up FileReader */
 | 
			
		||||
			const reader = new FileReader();
 | 
			
		||||
			reader.onload = (e) => {
 | 
			
		||||
				/* Parse data */
 | 
			
		||||
				const bstr = e.target.result;
 | 
			
		||||
				const wb = X.read(bstr, {type:'binary'});
 | 
			
		||||
				/* Get first worksheet */
 | 
			
		||||
				const wsname = wb.SheetNames[0];
 | 
			
		||||
				const ws = wb.Sheets[wsname];
 | 
			
		||||
				/* Convert array of arrays */
 | 
			
		||||
				const data = X.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
				/* Update state */
 | 
			
		||||
				this.data = data;
 | 
			
		||||
				this.cols = make_cols(ws['!ref']);
 | 
			
		||||
			};
 | 
			
		||||
			reader.readAsBinaryString(file);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/vue/static/xlsx.full.min.js
									
									
									
									
										vendored
									
									
										Symbolic link
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/vue/static/xlsx.full.min.js
									
									
									
									
										vendored
									
									
										Symbolic link
									
								
							@ -0,0 +1 @@
 | 
			
		||||
../xlsx.full.min.js
 | 
			
		||||
							
								
								
									
										16
									
								
								demos/vue/weex.sh
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										16
									
								
								demos/vue/weex.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
if [ ! -e SheetJS ]; then
 | 
			
		||||
	weexpack create SheetJS
 | 
			
		||||
	cd SheetJS
 | 
			
		||||
	npm install
 | 
			
		||||
	weexpack platform add ios
 | 
			
		||||
	sed -i 's/ATSDK-Weex/ATSDK/g' platforms/ios/Podfile
 | 
			
		||||
	cd -
 | 
			
		||||
	# weexpack run ios
 | 
			
		||||
fi
 | 
			
		||||
cp native.vue SheetJS/src/index.vue
 | 
			
		||||
if [ ! -e SheetJS/web/bootstrap.min.css ]; then
 | 
			
		||||
	curl -O https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
 | 
			
		||||
	mv bootstrap.min.css SheetJS/web/
 | 
			
		||||
fi
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# XMLHttpRequest and Friends
 | 
			
		||||
# XMLHttpRequest and fetch
 | 
			
		||||
 | 
			
		||||
`XMLHttpRequest` and `fetch` browser APIs enable binary data transfer between
 | 
			
		||||
web browser clients and web servers.  Since this library works in web browsers,
 | 
			
		||||
@ -14,21 +14,88 @@ name specified in `file`.
 | 
			
		||||
 | 
			
		||||
To start the demo, run `npm start` and navigate to <http://localhost:7262/>
 | 
			
		||||
 | 
			
		||||
## XMLHttpRequest (xhr.html)
 | 
			
		||||
## XMLHttpRequest
 | 
			
		||||
 | 
			
		||||
For downloading data, the `arraybuffer` response type generates an `ArrayBuffer`
 | 
			
		||||
that can be viewed as an `Uint8Array` and fed to `XLSX.read` using `array` type.
 | 
			
		||||
that can be viewed as an `Uint8Array` and fed to `XLSX.read` using `array` type:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* set up an async GET request */
 | 
			
		||||
var req = new XMLHttpRequest();
 | 
			
		||||
req.open("GET", url, true);
 | 
			
		||||
req.responseType = "arraybuffer";
 | 
			
		||||
 | 
			
		||||
req.onload = function(e) {
 | 
			
		||||
	/* parse the data when it is received */
 | 
			
		||||
	var data = new Uint8Array(oReq.response);
 | 
			
		||||
	var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
	/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
};
 | 
			
		||||
req.send();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For uploading data, this demo populates a `FormData` object with string data
 | 
			
		||||
generated with the `base64` output type.
 | 
			
		||||
generated with the `base64` output type:
 | 
			
		||||
 | 
			
		||||
## axios (axios.html) and superagent (superagent.html)
 | 
			
		||||
```js
 | 
			
		||||
/* generate XLSX as base64 string */
 | 
			
		||||
var b64 = XLSX.write(workbook, {bookType:'xlsx', type:'base64'});
 | 
			
		||||
 | 
			
		||||
The codes are structurally similar to the XMLHttpRequest example.  `axios` uses
 | 
			
		||||
a Promise-based API while `superagent` opts for a more traditional chain.
 | 
			
		||||
/* build FormData with the generated file */
 | 
			
		||||
var fd = new FormData();
 | 
			
		||||
fd.append('data', b64);
 | 
			
		||||
 | 
			
		||||
## fetch (fetch.html)
 | 
			
		||||
/* send data */
 | 
			
		||||
var req = new XMLHttpRequest();
 | 
			
		||||
req.open("POST", "/upload", true);
 | 
			
		||||
req.send(formdata);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
axios and superagent patterns are similar to the XMLHttpRequest pattern but
 | 
			
		||||
involve much less boilerplate:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* set up an async GET request with axios */
 | 
			
		||||
axios(url, {responseType:'arraybuffer'}).then(function(res) {
 | 
			
		||||
	/* parse the data when it is received */
 | 
			
		||||
	var data = new Uint8Array(res.data);
 | 
			
		||||
	var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
 | 
			
		||||
	/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/* set up an async GET request with superagent */
 | 
			
		||||
superagent.get(url).responseType('arraybuffer').end(function(err, res) {
 | 
			
		||||
	/* parse the data when it is received */
 | 
			
		||||
	var data = new Uint8Array(res.body);
 | 
			
		||||
	var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
 | 
			
		||||
	/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## fetch
 | 
			
		||||
 | 
			
		||||
For downloading data, `response.blob()` resolves to a `Blob` object that can be
 | 
			
		||||
converted to `ArrayBuffer` using a `FileReader`.
 | 
			
		||||
converted to `ArrayBuffer` using a `FileReader`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
fetch(url).then(function(res) {
 | 
			
		||||
	/* get the data as a Blob */
 | 
			
		||||
	if(!res.ok) throw new Error("fetch failed");
 | 
			
		||||
	return res.blob();
 | 
			
		||||
}).then(function(blob) {
 | 
			
		||||
	/* configure a FileReader to process the blob */
 | 
			
		||||
	var reader = new FileReader();
 | 
			
		||||
	reader.addEventListener("loadend", function() {
 | 
			
		||||
		/* parse the data when it is received */
 | 
			
		||||
		var data = new Uint8Array(this.result);
 | 
			
		||||
		var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
 | 
			
		||||
		/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
	});
 | 
			
		||||
	reader.readAsArrayBuffer(blob);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,23 +4,14 @@
 | 
			
		||||
var fs = require('fs'), path = require('path');
 | 
			
		||||
var express = require('express'), app = express();
 | 
			
		||||
var sprintf = require('printj').sprintf;
 | 
			
		||||
var logit = require('../server/_logit');
 | 
			
		||||
var cors = require('../server/_cors');
 | 
			
		||||
 | 
			
		||||
var port = +process.argv[2] || +process.env.PORT || 7262;
 | 
			
		||||
var basepath = process.cwd();
 | 
			
		||||
 | 
			
		||||
function doit(cb) {
 | 
			
		||||
	return function(req, res, next) {
 | 
			
		||||
		cb(req, res);
 | 
			
		||||
		next();
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
app.use(doit(function(req, res) {
 | 
			
		||||
	console.log(sprintf("%s %s %d", req.method, req.url, res.statusCode));
 | 
			
		||||
}));
 | 
			
		||||
app.use(doit(function(req, res) {
 | 
			
		||||
	res.header('Access-Control-Allow-Origin', '*');
 | 
			
		||||
}));
 | 
			
		||||
app.use(logit.mw);
 | 
			
		||||
app.use(cors.mw);
 | 
			
		||||
app.use(require('express-formidable')());
 | 
			
		||||
app.post('/upload', function(req, res) {
 | 
			
		||||
	fs.writeFile(req.fields.file, req.fields.data, 'base64', function(err, r) {
 | 
			
		||||
 | 
			
		||||
@ -25,21 +25,25 @@ CDNjs automatically pulls the latest version and makes all versions available at
 | 
			
		||||
 | 
			
		||||
The `demos` directory includes sample projects for:
 | 
			
		||||
 | 
			
		||||
**JS Frameworks and APIs**
 | 
			
		||||
**Frameworks and APIs**
 | 
			
		||||
- [`angular 1.x`](demos/angular/)
 | 
			
		||||
- [`angular 2.x / 4.x`](demos/angular2/)
 | 
			
		||||
- [`meteor`](demos/meteor/)
 | 
			
		||||
- [`vue 2.x`](demos/vue/)
 | 
			
		||||
- [`react and react-native`](demos/react/)
 | 
			
		||||
- [`vue 2.x and weex`](demos/vue/)
 | 
			
		||||
- [`XMLHttpRequest and fetch`](demos/xhr/)
 | 
			
		||||
- [`nodejs server`](demos/server/)
 | 
			
		||||
 | 
			
		||||
**JS Bundlers and Tooling**
 | 
			
		||||
**Bundlers and Tooling**
 | 
			
		||||
- [`browserify`](demos/browserify/)
 | 
			
		||||
- [`requirejs`](demos/requirejs/)
 | 
			
		||||
- [`rollup`](demos/rollup/)
 | 
			
		||||
- [`systemjs`](demos/systemjs/)
 | 
			
		||||
- [`webpack 2.x`](demos/webpack/)
 | 
			
		||||
 | 
			
		||||
**JS Platforms and Integrations**
 | 
			
		||||
**Platforms and Integrations**
 | 
			
		||||
- [`electron application`](demos/electron/)
 | 
			
		||||
- [`nw.js application`](demos/nwjs/)
 | 
			
		||||
- [`Adobe ExtendScript`](demos/extendscript/)
 | 
			
		||||
- [`Headless Browsers`](demos/headless/)
 | 
			
		||||
- [`canvas-datagrid`](demos/datagrid/)
 | 
			
		||||
 | 
			
		||||
@ -161,21 +161,25 @@ CDNjs automatically pulls the latest version and makes all versions available at
 | 
			
		||||
 | 
			
		||||
The `demos` directory includes sample projects for:
 | 
			
		||||
 | 
			
		||||
**JS Frameworks and APIs**
 | 
			
		||||
**Frameworks and APIs**
 | 
			
		||||
- [`angular 1.x`](demos/angular/)
 | 
			
		||||
- [`angular 2.x / 4.x`](demos/angular2/)
 | 
			
		||||
- [`meteor`](demos/meteor/)
 | 
			
		||||
- [`vue 2.x`](demos/vue/)
 | 
			
		||||
- [`react and react-native`](demos/react/)
 | 
			
		||||
- [`vue 2.x and weex`](demos/vue/)
 | 
			
		||||
- [`XMLHttpRequest and fetch`](demos/xhr/)
 | 
			
		||||
- [`nodejs server`](demos/server/)
 | 
			
		||||
 | 
			
		||||
**JS Bundlers and Tooling**
 | 
			
		||||
**Bundlers and Tooling**
 | 
			
		||||
- [`browserify`](demos/browserify/)
 | 
			
		||||
- [`requirejs`](demos/requirejs/)
 | 
			
		||||
- [`rollup`](demos/rollup/)
 | 
			
		||||
- [`systemjs`](demos/systemjs/)
 | 
			
		||||
- [`webpack 2.x`](demos/webpack/)
 | 
			
		||||
 | 
			
		||||
**JS Platforms and Integrations**
 | 
			
		||||
**Platforms and Integrations**
 | 
			
		||||
- [`electron application`](demos/electron/)
 | 
			
		||||
- [`nw.js application`](demos/nwjs/)
 | 
			
		||||
- [`Adobe ExtendScript`](demos/extendscript/)
 | 
			
		||||
- [`Headless Browsers`](demos/headless/)
 | 
			
		||||
- [`canvas-datagrid`](demos/datagrid/)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user