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