forked from sheetjs/sheetjs
		
	demo refresh [ci skip]
This commit is contained in:
		
							parent
							
								
									d02650055d
								
							
						
					
					
						commit
						1a8f97269e
					
				
							
								
								
									
										109
									
								
								.spelling
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										109
									
								
								.spelling
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
# xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com
 | 
			
		||||
SheetJS
 | 
			
		||||
js-xlsx
 | 
			
		||||
xls
 | 
			
		||||
xlsb
 | 
			
		||||
xlsx
 | 
			
		||||
 | 
			
		||||
# Excel-related terms
 | 
			
		||||
A1-style
 | 
			
		||||
AutoFilter
 | 
			
		||||
ECMA-376
 | 
			
		||||
FoxPro
 | 
			
		||||
Multiplan
 | 
			
		||||
OData
 | 
			
		||||
OpenDocument
 | 
			
		||||
OpenFormula
 | 
			
		||||
PivotTable
 | 
			
		||||
Quattro
 | 
			
		||||
SpreadsheetML
 | 
			
		||||
Unhide
 | 
			
		||||
Visicalc
 | 
			
		||||
chartsheet
 | 
			
		||||
chartsheets
 | 
			
		||||
dBASE
 | 
			
		||||
tooltip
 | 
			
		||||
tooltips
 | 
			
		||||
 | 
			
		||||
# Third-party
 | 
			
		||||
Browserify
 | 
			
		||||
CDNjs
 | 
			
		||||
CommonJS
 | 
			
		||||
ExtendScript
 | 
			
		||||
FileSaver
 | 
			
		||||
JavaScriptCore
 | 
			
		||||
NPM
 | 
			
		||||
Nuxt.js
 | 
			
		||||
RequireJS
 | 
			
		||||
Rollup
 | 
			
		||||
SystemJS
 | 
			
		||||
VueJS
 | 
			
		||||
iOS
 | 
			
		||||
nodejs
 | 
			
		||||
npm
 | 
			
		||||
unpkg
 | 
			
		||||
webpack
 | 
			
		||||
weex
 | 
			
		||||
 | 
			
		||||
# Other terms
 | 
			
		||||
APIs
 | 
			
		||||
Base64
 | 
			
		||||
Booleans
 | 
			
		||||
JS
 | 
			
		||||
README
 | 
			
		||||
UTF-16
 | 
			
		||||
XHR
 | 
			
		||||
XMLHttpRequest
 | 
			
		||||
bundlers
 | 
			
		||||
cleanroom
 | 
			
		||||
config
 | 
			
		||||
customizable
 | 
			
		||||
datagrid
 | 
			
		||||
deduplication
 | 
			
		||||
embeddable
 | 
			
		||||
filesystem
 | 
			
		||||
javascript
 | 
			
		||||
metadata
 | 
			
		||||
natively
 | 
			
		||||
prepend
 | 
			
		||||
prepended
 | 
			
		||||
repo
 | 
			
		||||
runtime
 | 
			
		||||
submodule
 | 
			
		||||
transpiled
 | 
			
		||||
 | 
			
		||||
 - demos/altjs/README.md
 | 
			
		||||
ChakraCore
 | 
			
		||||
Duktape
 | 
			
		||||
Nashorn
 | 
			
		||||
 | 
			
		||||
 - demos/angular/README.md
 | 
			
		||||
angular-ui-grid
 | 
			
		||||
ui-grid
 | 
			
		||||
 
 | 
			
		||||
 - demos/angular2/README.md
 | 
			
		||||
angular-cli
 | 
			
		||||
 | 
			
		||||
 - demos/extendscript/README.md
 | 
			
		||||
Photoshop
 | 
			
		||||
minifier
 | 
			
		||||
 | 
			
		||||
 - demos/headless/README.md
 | 
			
		||||
PhantomJS
 | 
			
		||||
SlimerJS
 | 
			
		||||
wkhtmltopdf
 | 
			
		||||
 | 
			
		||||
 - demos/nwjs/README.md
 | 
			
		||||
NW.js
 | 
			
		||||
 | 
			
		||||
 - demos/react/README.md
 | 
			
		||||
Next.js
 | 
			
		||||
Preact
 | 
			
		||||
 | 
			
		||||
 - demos/server/README.md
 | 
			
		||||
hapi
 | 
			
		||||
 | 
			
		||||
 - demos/xhr/README.md
 | 
			
		||||
axios
 | 
			
		||||
superagent
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							@ -209,6 +209,13 @@ book: readme graph ## Update summary for documentation
 | 
			
		||||
	markdown-toc README.md | sed 's/(#/(README.md#/g'>> misc/docs/SUMMARY.md
 | 
			
		||||
	<README.md grep -vE "(details|summary)>" > misc/docs/README.md
 | 
			
		||||
 | 
			
		||||
DEMOMDS=$(sort $(wildcard demos/*/README.md))
 | 
			
		||||
MDLINT=$(DEMODS) $(READEPS) demos/README.md
 | 
			
		||||
.PHONY: mdlint
 | 
			
		||||
mdlint: $(MDLINT) ## Check markdown documents
 | 
			
		||||
	alex $^
 | 
			
		||||
	mdspell -a -n -x -r --en-us $^
 | 
			
		||||
 | 
			
		||||
.PHONY: help
 | 
			
		||||
help:
 | 
			
		||||
	@grep -hE '(^[a-zA-Z_-][ a-zA-Z_-]*:.*?|^#[#*])' $(MAKEFILE_LIST) | bash misc/help.sh
 | 
			
		||||
 | 
			
		||||
@ -8,5 +8,37 @@ works extremely well in common use cases: script tag insertion and node require.
 | 
			
		||||
Systems like webpack try to be clever by performing simple static analysis to
 | 
			
		||||
pull in code.  However, they do not support dynamic type tests, breaking
 | 
			
		||||
compatibility with traditional scripts.  Configuration is required.  The demos
 | 
			
		||||
cover basic configuration steps for various systems and should work as laid out.
 | 
			
		||||
cover basic configuration steps for various systems and should "just work".
 | 
			
		||||
 | 
			
		||||
Mobile app and other larger demos do not include the full build structure. The
 | 
			
		||||
demos have `Makefile` scripts that show how to reproduce the full projects.  The
 | 
			
		||||
scripts have been tested against iOS and OSX.  For Windows platforms, GNU make
 | 
			
		||||
can be installed with Bash on Windows or with `cygwin`.
 | 
			
		||||
 | 
			
		||||
### Included Demos
 | 
			
		||||
 | 
			
		||||
**Frameworks and APIs**
 | 
			
		||||
- [`angular 1.x`](angular/)
 | 
			
		||||
- [`angular 2.x / 4.x`](angular2/)
 | 
			
		||||
- [`meteor`](meteor/)
 | 
			
		||||
- [`react and react-native`](react/)
 | 
			
		||||
- [`vue 2.x and weex`](vue/)
 | 
			
		||||
- [`XMLHttpRequest and fetch`](xhr/)
 | 
			
		||||
- [`nodejs server`](server/)
 | 
			
		||||
 | 
			
		||||
**Bundlers and Tooling**
 | 
			
		||||
- [`browserify`](browserify/)
 | 
			
		||||
- [`requirejs`](requirejs/)
 | 
			
		||||
- [`rollup`](rollup/)
 | 
			
		||||
- [`systemjs`](systemjs/)
 | 
			
		||||
- [`webpack 2.x`](webpack/)
 | 
			
		||||
 | 
			
		||||
**Platforms and Integrations**
 | 
			
		||||
- [`electron application`](electron/)
 | 
			
		||||
- [`nw.js application`](nwjs/)
 | 
			
		||||
- [`Adobe ExtendScript`](extendscript/)
 | 
			
		||||
- [`Headless Browsers`](headless/)
 | 
			
		||||
- [`canvas-datagrid`](datagrid/)
 | 
			
		||||
- [`Swift JSC and other engines`](altjs/)
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,52 @@ var global = (function(){ return this; }).call(null);
 | 
			
		||||
 | 
			
		||||
iOS and OSX ship with the JavaScriptCore framework, enabling easy JS access from
 | 
			
		||||
Swift and Objective-C.  Hybrid function invocation is tricky, but explicit data
 | 
			
		||||
passing is straightforward.
 | 
			
		||||
passing is straightforward.  The demo shows a standalone example for OSX.  For
 | 
			
		||||
playgrounds, the library should be copied to shared playground data directory
 | 
			
		||||
(usually `~/Documents/Shared Playground Data`):
 | 
			
		||||
 | 
			
		||||
Binary strings can be passed back and forth using `String.Encoding.ascii`.
 | 
			
		||||
```swift
 | 
			
		||||
/* This only works in a playground, see SheetJSCore.swift for standalone use */
 | 
			
		||||
import JavaScriptCore;
 | 
			
		||||
import PlaygroundSupport;
 | 
			
		||||
 | 
			
		||||
/* build path variable for the library */
 | 
			
		||||
let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory;
 | 
			
		||||
let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js");
 | 
			
		||||
 | 
			
		||||
/* prepare JS context */
 | 
			
		||||
var context:JSContext! = JSContext();
 | 
			
		||||
var src = "var global = (function(){ return this; }).call(null);";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
 | 
			
		||||
/* load library */
 | 
			
		||||
var lib = try? String(contentsOf: lib_path);
 | 
			
		||||
context.evaluateScript(lib);
 | 
			
		||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
 | 
			
		||||
 | 
			
		||||
/* to verify the library was loaded, get the version string */
 | 
			
		||||
let XLSXversion: JSValue! = XLSX.objectForKeyedSubscript("version")
 | 
			
		||||
var version  = XLSXversion.toString();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Binary strings can be passed back and forth using `String.Encoding.isoLatin1`:
 | 
			
		||||
 | 
			
		||||
```swift
 | 
			
		||||
/* parse sheetjs.xls */
 | 
			
		||||
let file_path = shared_dir.appendingPathComponent("sheetjs.xls");
 | 
			
		||||
let data:String! = try String(contentsOf: file_path, encoding:String.Encoding.isoLatin1);
 | 
			
		||||
context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!);
 | 
			
		||||
src = "var wb = XLSX.read(payload, {type:'binary'});";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
 | 
			
		||||
/* write to sheetjs.xlsx  */
 | 
			
		||||
let out_path = shared_dir.appendingPathComponent("sheetjs.xlsx");
 | 
			
		||||
src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
let outvalue: JSValue! = context.objectForKeyedSubscript("out");
 | 
			
		||||
var out:String! = outvalue.toString();
 | 
			
		||||
try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Nashorn
 | 
			
		||||
@ -42,7 +85,7 @@ array and calls `XLSX.read` with type `"array"`.
 | 
			
		||||
`SheetJSRhino` class and `com.sheetjs` package show a complete JAR deployment,
 | 
			
		||||
including the full XLSX source.
 | 
			
		||||
 | 
			
		||||
Due to code generation errors, optimization must be disabled:
 | 
			
		||||
Due to code generation errors, optimization must be turned off:
 | 
			
		||||
 | 
			
		||||
```java
 | 
			
		||||
Context context = Context.enter();
 | 
			
		||||
@ -55,7 +98,7 @@ context.setOptimizationLevel(-1);
 | 
			
		||||
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
 | 
			
		||||
The simplest way to interact with the engine is to pass Base64 strings. The make
 | 
			
		||||
target builds a very simple payload with the data.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -77,3 +120,5 @@ duk_size_t sz;
 | 
			
		||||
char *buf = (char *)duk_get_buffer_data(ctx, -1, sz);
 | 
			
		||||
duk_pop(ctx);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								demos/altjs/SJSPlayground.swift
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										37
									
								
								demos/altjs/SJSPlayground.swift
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
/* This only works in a playground, see SheetJSCore.swift for standalone use */
 | 
			
		||||
import JavaScriptCore;
 | 
			
		||||
import PlaygroundSupport;
 | 
			
		||||
 | 
			
		||||
/* build path variable for the library */
 | 
			
		||||
let shared_dir = PlaygroundSupport.playgroundSharedDataDirectory;
 | 
			
		||||
let lib_path = shared_dir.appendingPathComponent("xlsx.full.min.js");
 | 
			
		||||
 | 
			
		||||
/* prepare JS context */
 | 
			
		||||
var context:JSContext! = JSContext();
 | 
			
		||||
var src = "var global = (function(){ return this; }).call(null);";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
 | 
			
		||||
/* load library */
 | 
			
		||||
var lib = try? String(contentsOf: lib_path);
 | 
			
		||||
context.evaluateScript(lib);
 | 
			
		||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
 | 
			
		||||
 | 
			
		||||
/* to verify the library was loaded, get the version string */
 | 
			
		||||
let XLSXversion: JSValue! = XLSX.objectForKeyedSubscript("version")
 | 
			
		||||
var version  = XLSXversion.toString();
 | 
			
		||||
 | 
			
		||||
/* parse sheetjs.xls */
 | 
			
		||||
let file_path = shared_dir.appendingPathComponent("sheetjs.xls");
 | 
			
		||||
let data:String! = try String(contentsOf: file_path, encoding:String.Encoding.isoLatin1);
 | 
			
		||||
context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!);
 | 
			
		||||
src = "var wb = XLSX.read(payload, {type:'binary'});";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
 | 
			
		||||
/* write to sheetjs.xlsx  */
 | 
			
		||||
let out_path = shared_dir.appendingPathComponent("sheetjs.xlsx");
 | 
			
		||||
src = "var out = XLSX.write(wb, {type:'binary', bookType:'xlsx'})";
 | 
			
		||||
context.evaluateScript(src);
 | 
			
		||||
let outvalue: JSValue! = context.objectForKeyedSubscript("out");
 | 
			
		||||
var out:String! = outvalue.toString();
 | 
			
		||||
try? out.write(to: out_path, atomically: false, encoding: String.Encoding.isoLatin1);
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#!/usr/bin/env xcrun swift
 | 
			
		||||
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
import JavaScriptCore;
 | 
			
		||||
 | 
			
		||||
class SheetJS {
 | 
			
		||||
@ -30,7 +30,7 @@ class SheetJS {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	func readFileToCSV(file: String) throws -> String {
 | 
			
		||||
		let data:String! = try String(contentsOfFile: file, encoding:String.Encoding.ascii);
 | 
			
		||||
		let data:String! = try String(contentsOfFile: file, encoding:String.Encoding.isoLatin1);
 | 
			
		||||
		self.context.setObject(data, forKeyedSubscript:"payload" as (NSCopying & NSObjectProtocol)!);
 | 
			
		||||
 | 
			
		||||
		let src = [
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# Angular 1
 | 
			
		||||
 | 
			
		||||
The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped
 | 
			
		||||
into web pages with script tags e.g.
 | 
			
		||||
into web pages with script tags:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
@ -12,21 +12,94 @@ as you would with any other browser-friendly library.  To make this meaningful,
 | 
			
		||||
we chose to show an integration with a common angular table component.
 | 
			
		||||
 | 
			
		||||
This demo uses angular-ui-grid to display a data table.  The ui-grid does not
 | 
			
		||||
provide any way to hook into the import button, so the demo includes a simple
 | 
			
		||||
provide any way to modify the import button, so the demo includes a simple
 | 
			
		||||
directive for a HTML File Input control.  It also includes a sample service for
 | 
			
		||||
export which adds an item to the export menu.
 | 
			
		||||
 | 
			
		||||
## Import Directive
 | 
			
		||||
 | 
			
		||||
`SheetJSImportDirective` follows the prescription from the README for File input
 | 
			
		||||
controls using `readAsBinaryString`, converting to a suitable representation
 | 
			
		||||
and updating the scope.
 | 
			
		||||
A general import directive is fairly straightforward:
 | 
			
		||||
 | 
			
		||||
- Define the `importSheetJs` directive in the app:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
app.directive("importSheetJs", [SheetJSImportDirective]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Add the attribute `import-sheet-js=""` to the file input element:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<input type="file" import-sheet-js="" multiple="false"  />
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Define the directive:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var SheetJSImportDirective = function() {
 | 
			
		||||
  return {
 | 
			
		||||
    scope: { },
 | 
			
		||||
    link: function ($scope, $elm, $attrs) {
 | 
			
		||||
      $elm.on('change', function (changeEvent) {
 | 
			
		||||
        var reader = new FileReader();
 | 
			
		||||
 | 
			
		||||
        reader.onload = function (e) {
 | 
			
		||||
          /* read workbook */
 | 
			
		||||
          var bstr = e.target.result;
 | 
			
		||||
          var workbook = XLSX.read(bstr, {type:'binary'});
 | 
			
		||||
 | 
			
		||||
          /* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        reader.readAsBinaryString(changeEvent.target.files[0]);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The demo `SheetJSImportDirective` follows the prescription from the README for
 | 
			
		||||
File input controls using `readAsBinaryString`, converting to a suitable
 | 
			
		||||
representation and updating the scope.
 | 
			
		||||
 | 
			
		||||
## Export Service
 | 
			
		||||
 | 
			
		||||
An export can be triggered at any point!  Depending on how data is represented,
 | 
			
		||||
a workbook object can be built using the utility functions.  For example, using
 | 
			
		||||
an array of objects:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* starting from this data */
 | 
			
		||||
var data = [
 | 
			
		||||
  { name: "Barack Obama", pres: 44 },
 | 
			
		||||
  { name: "Donald Trump", pres: 45 }
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/* generate a worksheet */
 | 
			
		||||
var ws = XLSX.utils.json_to_sheet(data);
 | 
			
		||||
 | 
			
		||||
/* add to workbook */
 | 
			
		||||
var wb = XLSX.utils.book_new();
 | 
			
		||||
XLSX.utils.book_append_sheet(wb, ws, "Presidents");
 | 
			
		||||
 | 
			
		||||
/* write workbook (use type 'binary') */
 | 
			
		||||
var wbout = XLSX.write(wb, {bookType:'xlsx', type:'binary'});
 | 
			
		||||
 | 
			
		||||
/* generate a download */
 | 
			
		||||
function s2ab(s) {
 | 
			
		||||
  var buf = new ArrayBuffer(s.length);
 | 
			
		||||
  var view = new Uint8Array(buf);
 | 
			
		||||
  for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "sheetjs.xlsx");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`SheetJSExportService` exposes export functions for `XLSB` and `XLSX`.  Other
 | 
			
		||||
formats are easily supported by changing the `bookType` variable.  It grabs
 | 
			
		||||
values from the grid, builds an array of arrays, generates a workbook and uses
 | 
			
		||||
FileSaver to generate a download.  By setting the `filename` and `sheetname`
 | 
			
		||||
options in the ui-grid options, the output can be controlled.
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								demos/angular/SheetJS-angular.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								demos/angular/SheetJS-angular.js
									
									
									
									
										vendored
									
									
								
							@ -103,5 +103,5 @@ var SheetJSImportDirective = function() {
 | 
			
		||||
				reader.readAsBinaryString(changeEvent.target.files[0]);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,61 @@ 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.
 | 
			
		||||
 | 
			
		||||
## Array of Arrays
 | 
			
		||||
 | 
			
		||||
`Array<Array<any>>` neatly maps to a table with `ngFor`:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<table class="sjs-table">
 | 
			
		||||
  <tr *ngFor="let row of data">
 | 
			
		||||
    <td *ngFor="let val of row">
 | 
			
		||||
      {{val}}
 | 
			
		||||
    </td>
 | 
			
		||||
  </tr>
 | 
			
		||||
</table>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `aoa_to_sheet` utility function returns a worksheet.  Exporting is simple:
 | 
			
		||||
 | 
			
		||||
```typescript
 | 
			
		||||
/* generate worksheet */
 | 
			
		||||
const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
 | 
			
		||||
 | 
			
		||||
/* generate workbook and add the worksheet */
 | 
			
		||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
 | 
			
		||||
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
 | 
			
		||||
 | 
			
		||||
/* save to file */
 | 
			
		||||
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
 | 
			
		||||
saveAs(new Blob([s2ab(wbout)]), 'SheetJS.xlsx');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`sheet_to_json` with the option `header:1` makes importing simple:
 | 
			
		||||
 | 
			
		||||
```typescript
 | 
			
		||||
/* <input type="file" (change)="onFileChange($event)" multiple="false" /> */
 | 
			
		||||
/* ... (within the component class definition) ... */
 | 
			
		||||
  onFileChange(evt: any) {
 | 
			
		||||
    /* wire up file reader */
 | 
			
		||||
    const target: DataTransfer = <DataTransfer>(evt.target);
 | 
			
		||||
    if (target.files.length !== 1) throw new Error('Cannot use multiple files');
 | 
			
		||||
    const reader: FileReader = new FileReader();
 | 
			
		||||
    reader.onload = (e: any) => {
 | 
			
		||||
      /* read workbook */
 | 
			
		||||
      const bstr: string = e.target.result;
 | 
			
		||||
      const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
 | 
			
		||||
 | 
			
		||||
      /* grab first sheet */
 | 
			
		||||
      const wsname: string = wb.SheetNames[0];
 | 
			
		||||
      const ws: XLSX.WorkSheet = wb.Sheets[wsname];
 | 
			
		||||
 | 
			
		||||
      /* save data */
 | 
			
		||||
      this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
 | 
			
		||||
    };
 | 
			
		||||
    reader.readAsBinaryString(target.files[0]);
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Switching between Angular versions
 | 
			
		||||
 | 
			
		||||
Modules that work with Angular 2 largely work as-is with Angular 4.  Switching
 | 
			
		||||
@ -33,15 +88,14 @@ $ npm install
 | 
			
		||||
$ ng serve
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## XLSX Symlink
 | 
			
		||||
## XLSX Symbolic Link
 | 
			
		||||
 | 
			
		||||
In this tree, `node_modules/xlsx` is a symlink pointing back to the root.  This
 | 
			
		||||
In this tree, `node_modules/xlsx` is a link pointing back to the root.  This
 | 
			
		||||
enables testing the development version of the library.  In order to use this
 | 
			
		||||
demo in other applications, add the `xlsx` dependency:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ npm install --save xlsx
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## SystemJS Configuration
 | 
			
		||||
@ -53,16 +107,18 @@ SystemJS example shows the required meta and map settings:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
	meta: {
 | 
			
		||||
		'xlsx': {
 | 
			
		||||
			exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	map: {
 | 
			
		||||
		'xlsx': 'xlsx.full.min.js', // <-- make sure xlsx.full.min.js is in same dir
 | 
			
		||||
		'fs': '',     // <--|
 | 
			
		||||
		'crypto': '', // <--| suppress native node modules
 | 
			
		||||
		'stream': ''  // <--|
 | 
			
		||||
	}
 | 
			
		||||
  meta: {
 | 
			
		||||
    'xlsx': {
 | 
			
		||||
      exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  map: {
 | 
			
		||||
    'xlsx': 'xlsx.full.min.js', // <-- make sure xlsx.full.min.js is in same dir
 | 
			
		||||
    'fs': '',     // <--|
 | 
			
		||||
    'crypto': '', // <--| suppress native node modules
 | 
			
		||||
    'stream': ''  // <--|
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -9,11 +9,9 @@ import { saveAs } from 'file-saver';
 | 
			
		||||
type AOA = Array<Array<any>>;
 | 
			
		||||
 | 
			
		||||
function s2ab(s: string): ArrayBuffer {
 | 
			
		||||
	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;
 | 
			
		||||
	};
 | 
			
		||||
	const buf: ArrayBuffer = new ArrayBuffer(s.length);
 | 
			
		||||
	const view: Uint8Array = new Uint8Array(buf);
 | 
			
		||||
	for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -33,41 +31,40 @@ function s2ab(s: string): ArrayBuffer {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export class SheetJSComponent {
 | 
			
		||||
	data: AOA = [[1,2],[3,4]];
 | 
			
		||||
	wopts: XLSX.WritingOptions = { bookType:'xlsx', type:'binary' };
 | 
			
		||||
	fileName: string = "SheetJS.xlsx";
 | 
			
		||||
	data: AOA = [ [1, 2], [3, 4] ];
 | 
			
		||||
	wopts: XLSX.WritingOptions = { bookType: 'xlsx', type: 'binary' };
 | 
			
		||||
	fileName: string = 'SheetJS.xlsx';
 | 
			
		||||
 | 
			
		||||
	onFileChange(evt: any) {
 | 
			
		||||
		/* wire up file reader */
 | 
			
		||||
		const target: DataTransfer = <DataTransfer>(evt.target);
 | 
			
		||||
		if(target.files.length != 1) { throw new Error("Cannot upload multiple files on the entry") };
 | 
			
		||||
		const reader = new FileReader();
 | 
			
		||||
		if (target.files.length !== 1) throw new Error('Cannot use multiple files');
 | 
			
		||||
		const reader: FileReader = new FileReader();
 | 
			
		||||
		reader.onload = (e: any) => {
 | 
			
		||||
			/* read workbook */
 | 
			
		||||
			const bstr = e.target.result;
 | 
			
		||||
			const wb = XLSX.read(bstr, {type:'binary'});
 | 
			
		||||
			const bstr: string = e.target.result;
 | 
			
		||||
			const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
 | 
			
		||||
 | 
			
		||||
			/* grab first sheet */
 | 
			
		||||
			const wsname = wb.SheetNames[0];
 | 
			
		||||
			const ws = wb.Sheets[wsname];
 | 
			
		||||
			const wsname: string = wb.SheetNames[0];
 | 
			
		||||
			const ws: XLSX.WorkSheet = wb.Sheets[wsname];
 | 
			
		||||
 | 
			
		||||
			/* save data */
 | 
			
		||||
			this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header:1}));
 | 
			
		||||
			this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsBinaryString(target.files[0]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	export(): void {
 | 
			
		||||
		/* generate worksheet */
 | 
			
		||||
		const ws = XLSX.utils.aoa_to_sheet(this.data);
 | 
			
		||||
		const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
 | 
			
		||||
 | 
			
		||||
		/* generate workbook and add the worksheet */
 | 
			
		||||
		const wb = XLSX.utils.book_new();
 | 
			
		||||
		const wb: XLSX.WorkBook = XLSX.utils.book_new();
 | 
			
		||||
		XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
 | 
			
		||||
 | 
			
		||||
		/* save to file */
 | 
			
		||||
		const wbout = XLSX.write(wb, this.wopts);
 | 
			
		||||
		console.log(this.fileName);
 | 
			
		||||
		const wbout: string = XLSX.write(wb, this.wopts);
 | 
			
		||||
		saveAs(new Blob([s2ab(wbout)]), this.fileName);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
import 'core-js/es6/reflect';
 | 
			
		||||
import 'core-js/es7/reflect';
 | 
			
		||||
import 'zone.js/dist/zone';
 | 
			
		||||
import 'zone.js/dist/zone';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								demos/browserify/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/browserify/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,2 +1,4 @@
 | 
			
		||||
browserify.js
 | 
			
		||||
browserify.min.js
 | 
			
		||||
worker.js
 | 
			
		||||
worker.min.js
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,17 @@
 | 
			
		||||
TOOL=browserify
 | 
			
		||||
.PHONY: all
 | 
			
		||||
all: $(TOOL).min.js
 | 
			
		||||
all: $(TOOL).min.js worker.min.js
 | 
			
		||||
 | 
			
		||||
$(TOOL).min.js: $(TOOL).js
 | 
			
		||||
	uglifyjs $< > $@
 | 
			
		||||
 | 
			
		||||
.PHONY: $(TOOL).js
 | 
			
		||||
$(TOOL).js:
 | 
			
		||||
	browserify -r './main.js:xlsx' > $@
 | 
			
		||||
$(TOOL).js: app.js
 | 
			
		||||
	browserify $< > $@
 | 
			
		||||
 | 
			
		||||
worker.min.js: worker.js
 | 
			
		||||
	uglifyjs $< > $@
 | 
			
		||||
 | 
			
		||||
.PHONY: worker.js
 | 
			
		||||
worker.js: xlsxworker.js
 | 
			
		||||
	browserify $< > $@
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,31 @@
 | 
			
		||||
# Browserify
 | 
			
		||||
 | 
			
		||||
The library is compatible with browserify and should just work out of the box.
 | 
			
		||||
The library is compatible with Browserify and should just work out of the box.
 | 
			
		||||
 | 
			
		||||
This demo uses the `require` form to expose the whole library, enabling client
 | 
			
		||||
code to just `require('xlsx')`.  The included demo and Makefile do just that.
 | 
			
		||||
code to access the library with `var XLSX = require('xlsx')`.  The JS code from
 | 
			
		||||
the root demo was moved to a separate `app.js` script.  That script is bundled:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
browserify app.js > browserify.js
 | 
			
		||||
uglifyjs browserify.js > browserify.min.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Worker Scripts
 | 
			
		||||
 | 
			
		||||
Browserify can also bundle worker scripts!  Instead of using `importScripts`,
 | 
			
		||||
the worker script should require the module:
 | 
			
		||||
 | 
			
		||||
```diff
 | 
			
		||||
-importScripts('dist/xlsx.full.min.js');
 | 
			
		||||
+var XLSX = require('xlsx');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The same process generates the worker script:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
browserify xlsxworker.js > worker.js
 | 
			
		||||
uglifyjs worker.js > worker.min.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										162
									
								
								demos/browserify/app.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										162
									
								
								demos/browserify/app.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,162 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('../../'); // test against development version
 | 
			
		||||
//var XLSX = require('xlsx'); // use in production
 | 
			
		||||
/*jshint browser:true */
 | 
			
		||||
/*global require */
 | 
			
		||||
var X = require('xlsx');
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
	msg: 'xlsx',
 | 
			
		||||
	/* worker scripts */
 | 
			
		||||
	worker: './worker.min.js'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var OUT = document.getElementById('out');
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	var get_format = (function() {
 | 
			
		||||
		var radios = document.getElementsByName( "format" );
 | 
			
		||||
		return function() {
 | 
			
		||||
			for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
 | 
			
		||||
		};
 | 
			
		||||
	})();
 | 
			
		||||
 | 
			
		||||
	var to_json = function to_json(workbook) {
 | 
			
		||||
		var result = {};
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(roa.length) result[sheetName] = roa;
 | 
			
		||||
		});
 | 
			
		||||
		return JSON.stringify(result, 2, 2);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_csv = function to_csv(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(csv.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(csv);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_fmla = function to_fmla(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(formulae.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(formulae.join("\n"));
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_html = function to_html(workbook) {
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(workbook, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
		return "";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		global_wb = wb;
 | 
			
		||||
		var output = "";
 | 
			
		||||
		switch(get_format()) {
 | 
			
		||||
			case "form": output = to_fmla(wb); break;
 | 
			
		||||
			case "html": output = to_html(wb); break;
 | 
			
		||||
			case "json": output = to_json(wb); break;
 | 
			
		||||
			default: output = to_csv(wb);
 | 
			
		||||
		}
 | 
			
		||||
		if(OUT.innerText === undefined) OUT.textContent = output;
 | 
			
		||||
		else OUT.innerText = output;
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("output", new Date());
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
 | 
			
		||||
 | 
			
		||||
var b64it = window.b64it = (function() {
 | 
			
		||||
	var tarea = document.getElementById('b64data');
 | 
			
		||||
	return function b64it() {
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("onload", new Date());
 | 
			
		||||
		var wb = X.read(tarea.value, {type:'base64', WTF:false});
 | 
			
		||||
		process_wb(wb);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	var rABS = typeof FileReader !== "undefined" && (FileReader.prototype||{}).readAsBinaryString;
 | 
			
		||||
	var domrabs = document.getElementsByName("userabs")[0];
 | 
			
		||||
	if(!rABS) domrabs.disabled = !(domrabs.checked = false);
 | 
			
		||||
 | 
			
		||||
	var use_worker = typeof Worker !== 'undefined';
 | 
			
		||||
	var domwork = document.getElementsByName("useworker")[0];
 | 
			
		||||
	if(!use_worker) domwork.disabled = !(domwork.checked = false);
 | 
			
		||||
 | 
			
		||||
	var xw = function xw(data, cb) {
 | 
			
		||||
		var worker = new Worker(XW.worker);
 | 
			
		||||
		worker.onmessage = function(e) {
 | 
			
		||||
			switch(e.data.t) {
 | 
			
		||||
				case 'ready': break;
 | 
			
		||||
				case 'e': console.error(e.data.d); break;
 | 
			
		||||
				case XW.msg: cb(JSON.parse(e.data.d)); break;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		worker.postMessage({d:data,b:rABS?'binary':'array'});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		rABS = domrabs.checked;
 | 
			
		||||
		use_worker = domwork.checked;
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			if(!rABS) data = new Uint8Array(data);
 | 
			
		||||
			if(use_worker) xw(data, process_wb);
 | 
			
		||||
			else process_wb(X.read(data, {type: rABS ? 'binary' : 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		if(rABS) reader.readAsBinaryString(f);
 | 
			
		||||
		else reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
	if(!drop.addEventListener) return;
 | 
			
		||||
 | 
			
		||||
	function handleDrop(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		do_file(e.dataTransfer.files);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function handleDragover(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		e.dataTransfer.dropEffect = 'copy';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drop.addEventListener('dragenter', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('dragover', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('drop', handleDrop, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var xlf = document.getElementById('xlf');
 | 
			
		||||
	if(!xlf.addEventListener) return;
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
@ -47,167 +47,8 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="browserify.min.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
/*jshint browser:true */
 | 
			
		||||
/*global require */
 | 
			
		||||
var X = require('xlsx');
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
	msg: 'xlsx',
 | 
			
		||||
	/* worker scripts */
 | 
			
		||||
	worker: './xlsxworker.js'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var OUT = document.getElementById('out');
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	var get_format = (function() {
 | 
			
		||||
		var radios = document.getElementsByName( "format" );
 | 
			
		||||
		return function() {
 | 
			
		||||
			for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
 | 
			
		||||
		};
 | 
			
		||||
	})();
 | 
			
		||||
 | 
			
		||||
	var to_json = function to_json(workbook) {
 | 
			
		||||
		var result = {};
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(roa.length) result[sheetName] = roa;
 | 
			
		||||
		});
 | 
			
		||||
		return JSON.stringify(result, 2, 2);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_csv = function to_csv(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(csv.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(csv);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_fmla = function to_fmla(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(formulae.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(formulae.join("\n"));
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_html = function to_html(workbook) {
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(workbook, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
		return "";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		global_wb = wb;
 | 
			
		||||
		var output = "";
 | 
			
		||||
		switch(get_format()) {
 | 
			
		||||
			case "form": output = to_fmla(wb); break;
 | 
			
		||||
			case "html": output = to_html(wb); break;
 | 
			
		||||
			case "json": output = to_json(wb); break;
 | 
			
		||||
			default: output = to_csv(wb);
 | 
			
		||||
		}
 | 
			
		||||
		if(OUT.innerText === undefined) OUT.textContent = output;
 | 
			
		||||
		else OUT.innerText = output;
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("output", new Date());
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
 | 
			
		||||
 | 
			
		||||
var b64it = window.b64it = (function() {
 | 
			
		||||
	var tarea = document.getElementById('b64data');
 | 
			
		||||
	return function b64it() {
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("onload", new Date());
 | 
			
		||||
		var wb = X.read(tarea.value, {type:'base64', WTF:false});
 | 
			
		||||
		process_wb(wb);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	var rABS = typeof FileReader !== "undefined" && (FileReader.prototype||{}).readAsBinaryString;
 | 
			
		||||
	var domrabs = document.getElementsByName("userabs")[0];
 | 
			
		||||
	if(!rABS) domrabs.disabled = !(domrabs.checked = false);
 | 
			
		||||
 | 
			
		||||
	var use_worker = typeof Worker !== 'undefined';
 | 
			
		||||
	var domwork = document.getElementsByName("useworker")[0];
 | 
			
		||||
	if(!use_worker) domwork.disabled = !(domwork.checked = false);
 | 
			
		||||
 | 
			
		||||
	var xw = function xw(data, cb) {
 | 
			
		||||
		var worker = new Worker(XW.worker);
 | 
			
		||||
		worker.onmessage = function(e) {
 | 
			
		||||
			switch(e.data.t) {
 | 
			
		||||
				case 'ready': break;
 | 
			
		||||
				case 'e': console.error(e.data.d); break;
 | 
			
		||||
				case XW.msg: cb(JSON.parse(e.data.d)); break;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		worker.postMessage({d:data,b:rABS?'binary':'array'});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		rABS = domrabs.checked;
 | 
			
		||||
		use_worker = domwork.checked;
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			if(!rABS) data = new Uint8Array(data);
 | 
			
		||||
			if(use_worker) xw(data, process_wb);
 | 
			
		||||
			else process_wb(X.read(data, {type: rABS ? 'binary' : 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		if(rABS) reader.readAsBinaryString(f);
 | 
			
		||||
		else reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
	if(!drop.addEventListener) return;
 | 
			
		||||
 | 
			
		||||
	function handleDrop(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		do_file(e.dataTransfer.files);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function handleDragover(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		e.dataTransfer.dropEffect = 'copy';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drop.addEventListener('dragenter', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('dragover', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('drop', handleDrop, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var xlf = document.getElementById('xlf');
 | 
			
		||||
	if(!xlf.addEventListener) return;
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
/* eslint no-use-before-define:0 */
 | 
			
		||||
	var _gaq = _gaq || [];
 | 
			
		||||
	_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
	_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
@ -1,4 +0,0 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('../../'); // test against development version
 | 
			
		||||
//var XLSX = require('xlsx'); // use in production
 | 
			
		||||
module.exports = XLSX;
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
importScripts('browserify.min.js');
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
var XLSX = require('../../'); // test against development version
 | 
			
		||||
//var XLSX = require('xlsx'); // use in production
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (oEvent) {
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(oEvent.data.d, {type: oEvent.data.b});
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ with other JS libraries such as data grids for previewing data.  After extensive
 | 
			
		||||
testing, [`canvas-datagrid`](https://tonygermaneri.github.io/canvas-datagrid/)
 | 
			
		||||
stood out as a very high-performance grid with an incredibly simple API.
 | 
			
		||||
 | 
			
		||||
This demo is available at <http://oss.sheetjs.com/js-xlsx/datagrid.html>
 | 
			
		||||
 | 
			
		||||
## Obtaining the Library
 | 
			
		||||
 | 
			
		||||
The [`canvas-datagrid` npm nodule](http://npm.im/canvas-datagrid) includes a
 | 
			
		||||
@ -27,8 +29,8 @@ Grid initialization is a one-liner:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var grid = canvasDatagrid({
 | 
			
		||||
	parentNode: document.getElementById('gridctr'),
 | 
			
		||||
	data: []
 | 
			
		||||
  parentNode: document.getElementById('gridctr'),
 | 
			
		||||
  data: []
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -44,15 +46,30 @@ features to support multiple worksheets.
 | 
			
		||||
 | 
			
		||||
## Editing
 | 
			
		||||
 | 
			
		||||
The library handles the whole edit cycle.  No intervention is necessary.
 | 
			
		||||
`canvas-datagrid` handles the entire edit cycle.  No intervention is necessary.
 | 
			
		||||
 | 
			
		||||
## Saving Data
 | 
			
		||||
 | 
			
		||||
`grid.data` is immediately readable and can be converted back to a worksheet:
 | 
			
		||||
`grid.data` is immediately readable and can be converted back to a worksheet.
 | 
			
		||||
Some versions return an array-like object without the length, so a little bit of
 | 
			
		||||
preparation may be needed:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* converts an array of array-like objects into an array of arrays */
 | 
			
		||||
function prep(arr) {
 | 
			
		||||
  var out = [];
 | 
			
		||||
  for(var i = 0; i < arr.length; ++i) {
 | 
			
		||||
    if(!arr[i]) continue;
 | 
			
		||||
    if(Array.isArray(arr[i])) { out[i] = arr[i]; continue };
 | 
			
		||||
    var o = new Array();
 | 
			
		||||
    Object.keys(arr[i]).forEach(function(k) { o[+k] = arr[i][k] });
 | 
			
		||||
    out[i] = o;
 | 
			
		||||
  }
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* build worksheet from the grid data */
 | 
			
		||||
var ws = XLSX.utils.aoa_to_sheet(grid.data);
 | 
			
		||||
var ws = XLSX.utils.aoa_to_sheet(prep(grid.data));
 | 
			
		||||
 | 
			
		||||
/* build up workbook */
 | 
			
		||||
var wb = XLSX.utils.book_new();
 | 
			
		||||
@ -65,3 +82,5 @@ XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
 | 
			
		||||
 | 
			
		||||
This demo barely scratches the surface.  The underlying grid component includes
 | 
			
		||||
many additional features including massive data streaming, sorting and styling.
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -33,11 +33,10 @@ a { text-decoration: none }
 | 
			
		||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
 | 
			
		||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
 | 
			
		||||
<textarea id="b64data">... or paste a base64-encoding here</textarea>
 | 
			
		||||
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
 | 
			
		||||
<b>Advanced Demo Options:</b>
 | 
			
		||||
Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" checked>
 | 
			
		||||
</pre>
 | 
			
		||||
<p><input type="submit" value="Export to XLSX!" id="xport" onclick="doit();" disabled="true"></p>
 | 
			
		||||
<p><input type="submit" value="Export to XLSX!" id="xport" onclick="export_xlsx();" disabled="true"></p>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="https://unpkg.com/canvas-datagrid/dist/canvas-datagrid.js"></script>
 | 
			
		||||
@ -52,147 +51,117 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
 | 
			
		||||
/*global XLSX */
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
 | 
			
		||||
var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";
 | 
			
		||||
if(!rABS) {
 | 
			
		||||
	document.getElementsByName("userabs")[0].disabled = true;
 | 
			
		||||
	document.getElementsByName("userabs")[0].checked = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var wtf_mode = false;
 | 
			
		||||
 | 
			
		||||
function fixdata(data) {
 | 
			
		||||
	var o = "", l = 0, w = 10240;
 | 
			
		||||
	for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
 | 
			
		||||
	o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
 | 
			
		||||
	return o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function ab2str(data) {
 | 
			
		||||
	var o = "", l = 0, w = 10240;
 | 
			
		||||
	for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint16Array(data.slice(l*w,l*w+w)));
 | 
			
		||||
	o+=String.fromCharCode.apply(null, new Uint16Array(data.slice(l*w)));
 | 
			
		||||
	return o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function s2ab(s) {
 | 
			
		||||
	var b = new ArrayBuffer(s.length), v = new Uint8Array(b);
 | 
			
		||||
	for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
	return b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_radio_value( radioName ) {
 | 
			
		||||
	var radios = document.getElementsByName( radioName );
 | 
			
		||||
	for( var i = 0; i < radios.length; i++ ) {
 | 
			
		||||
		if( radios[i].checked || radios.length === 1 ) {
 | 
			
		||||
			return radios[i].value;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var tarea = document.getElementById('b64data');
 | 
			
		||||
function b64it() {
 | 
			
		||||
	if(typeof console !== 'undefined') console.log("onload", new Date());
 | 
			
		||||
	var wb = X.read(tarea.value, {type: 'base64',WTF:wtf_mode});
 | 
			
		||||
	process_wb(wb);
 | 
			
		||||
}
 | 
			
		||||
window.b64it = b64it;
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
var cDg;
 | 
			
		||||
function process_wb(wb) {
 | 
			
		||||
	global_wb = wb;
 | 
			
		||||
	var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
	var data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
	if(!cDg) cDg = canvasDatagrid({ parentNode:document.getElementById('htmlout'), data:data });
 | 
			
		||||
	else cDg.data = data;
 | 
			
		||||
	var range = XLSX.utils.decode_range(ws['!ref']);
 | 
			
		||||
	for(var i = range.s.c; i <= range.e.c; ++i) cDg.schema[i - range.s.c].title = XLSX.utils.encode_col(i);
 | 
			
		||||
	document.getElementById('xport').disabled = false;
 | 
			
		||||
	if(typeof console !== 'undefined') console.log("output", new Date());
 | 
			
		||||
}
 | 
			
		||||
function doit() {
 | 
			
		||||
	var new_wb = XLSX.utils.book_new();
 | 
			
		||||
	var new_ws = XLSX.utils.aoa_to_sheet(cDg.data);
 | 
			
		||||
	XLSX.utils.book_append_sheet(new_wb, new_ws, 'SheetJS');
 | 
			
		||||
	var wbout = XLSX.write(new_wb, {bookType:'xlsx', bookSST:true, type:'binary'});
 | 
			
		||||
	var fname = 'sheetjs.xlsx';
 | 
			
		||||
	try {
 | 
			
		||||
		saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), fname);
 | 
			
		||||
	} catch(e) { if(typeof console != 'undefined') console.log(e, wbout); }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drop = document.getElementById('drop');
 | 
			
		||||
function handleDrop(e) {
 | 
			
		||||
	e.stopPropagation();
 | 
			
		||||
	e.preventDefault();
 | 
			
		||||
	rABS = document.getElementsByName("userabs")[0].checked;
 | 
			
		||||
	var files = e.dataTransfer.files;
 | 
			
		||||
	var f = files[0];
 | 
			
		||||
	{
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var XPORT = document.getElementById('xport');
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		/* get data */
 | 
			
		||||
		var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
		var data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
 | 
			
		||||
		/* update canvas-datagrid */
 | 
			
		||||
		if(!cDg) cDg = canvasDatagrid({ parentNode:HTMLOUT, data:data });
 | 
			
		||||
		cDg.data = data;
 | 
			
		||||
		XPORT.disabled = false;
 | 
			
		||||
 | 
			
		||||
		/* create schema (for A,B,C column headings) */
 | 
			
		||||
		var range = XLSX.utils.decode_range(ws['!ref']);
 | 
			
		||||
		for(var i = range.s.c; i <= range.e.c; ++i) cDg.schema[i - range.s.c].title = XLSX.utils.encode_col(i);
 | 
			
		||||
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("output", new Date());
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	var rABS = typeof FileReader !== "undefined" && (FileReader.prototype||{}).readAsBinaryString;
 | 
			
		||||
	var domrabs = document.getElementsByName("userabs")[0];
 | 
			
		||||
	if(!rABS) domrabs.disabled = !(domrabs.checked = false);
 | 
			
		||||
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		rABS = domrabs.checked;
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		//var name = f.name;
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS);
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			{
 | 
			
		||||
				var wb;
 | 
			
		||||
				if(rABS) {
 | 
			
		||||
					wb = X.read(data, {type: 'binary'});
 | 
			
		||||
				} else {
 | 
			
		||||
					var arr = fixdata(data);
 | 
			
		||||
					wb = X.read(btoa(arr), {type: 'base64'});
 | 
			
		||||
				}
 | 
			
		||||
				process_wb(wb);
 | 
			
		||||
			}
 | 
			
		||||
			if(!rABS) data = new Uint8Array(data);
 | 
			
		||||
			process_wb(X.read(data, {type: rABS ? 'binary' : 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		if(rABS) reader.readAsBinaryString(f);
 | 
			
		||||
		else reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
	if(!drop.addEventListener) return;
 | 
			
		||||
 | 
			
		||||
	function handleDrop(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		do_file(e.dataTransfer.files);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function handleDragover(e) {
 | 
			
		||||
	e.stopPropagation();
 | 
			
		||||
	e.preventDefault();
 | 
			
		||||
	e.dataTransfer.dropEffect = 'copy';
 | 
			
		||||
}
 | 
			
		||||
	function handleDragover(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		e.dataTransfer.dropEffect = 'copy';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
if(drop.addEventListener) {
 | 
			
		||||
	drop.addEventListener('dragenter', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('dragover', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('drop', handleDrop, false);
 | 
			
		||||
}
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var xlf = document.getElementById('xlf');
 | 
			
		||||
	if(!xlf.addEventListener) return;
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var xlf = document.getElementById('xlf');
 | 
			
		||||
function handleFile(e) {
 | 
			
		||||
	rABS = document.getElementsByName("userabs")[0].checked;
 | 
			
		||||
	var files = e.target.files;
 | 
			
		||||
	var f = files[0];
 | 
			
		||||
	{
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		//var name = f.name;
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS);
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			{
 | 
			
		||||
				var wb;
 | 
			
		||||
				if(rABS) {
 | 
			
		||||
					wb = X.read(data, {type: 'binary'});
 | 
			
		||||
				} else {
 | 
			
		||||
					var arr = fixdata(data);
 | 
			
		||||
					wb = X.read(btoa(arr), {type: 'base64'});
 | 
			
		||||
				}
 | 
			
		||||
				process_wb(wb);
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		if(rABS) reader.readAsBinaryString(f);
 | 
			
		||||
		else reader.readAsArrayBuffer(f);
 | 
			
		||||
var export_xlsx = (function() {
 | 
			
		||||
	function prep(arr) {
 | 
			
		||||
		var out = [];
 | 
			
		||||
		for(var i = 0; i < arr.length; ++i) {
 | 
			
		||||
			if(!arr[i]) continue;
 | 
			
		||||
			if(Array.isArray(arr[i])) { out[i] = arr[i]; continue };
 | 
			
		||||
			var o = new Array();
 | 
			
		||||
			Object.keys(arr[i]).forEach(function(k) { o[+k] = arr[i][k] });
 | 
			
		||||
			out[i] = o;
 | 
			
		||||
		}
 | 
			
		||||
		return out;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
	function s2ab(s) {
 | 
			
		||||
		var b = new ArrayBuffer(s.length), v = new Uint8Array(b);
 | 
			
		||||
		for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
		return b;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return function export_xlsx() {
 | 
			
		||||
		if(!cDg) return;
 | 
			
		||||
		/* convert canvas-datagrid data to worksheet */
 | 
			
		||||
		var new_ws = XLSX.utils.aoa_to_sheet(prep(cDg.data));
 | 
			
		||||
 | 
			
		||||
		/* build workbook */
 | 
			
		||||
		var new_wb = XLSX.utils.book_new();
 | 
			
		||||
		XLSX.utils.book_append_sheet(new_wb, new_ws, 'SheetJS');
 | 
			
		||||
 | 
			
		||||
		/* write file and trigger a download */
 | 
			
		||||
		var wbout = XLSX.write(new_wb, {bookType:'xlsx', bookSST:true, type:'binary'});
 | 
			
		||||
		var fname = 'sheetjs.xlsx';
 | 
			
		||||
		try {
 | 
			
		||||
			saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), fname);
 | 
			
		||||
		} catch(e) { if(typeof console != 'undefined') console.log(e, wbout); }
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
/* eslint no-use-before-define:0 */
 | 
			
		||||
	var _gaq = _gaq || [];
 | 
			
		||||
	_gaq.push(['_setAccount', 'UA-36810333-1']);
 | 
			
		||||
	_gaq.push(['_trackPageview']);
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# 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 demonstration uses Electron 1.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.
 | 
			
		||||
 | 
			
		||||
@ -9,11 +9,28 @@ 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/)
 | 
			
		||||
 | 
			
		||||
The core data in this demo is an editable HTML table.  The readers build up the
 | 
			
		||||
table using `sheet_to_html` (with `editable:true` option) and the writers scrape
 | 
			
		||||
the table using `table_to_book`.
 | 
			
		||||
 | 
			
		||||
## Reading and Writing Files
 | 
			
		||||
 | 
			
		||||
Since electron provides an `fs` implementation, `readFile` and `writeFile` can
 | 
			
		||||
be used in conjunction with the standard dialogs.  For example:
 | 
			
		||||
be used in conjunction with the standard dialog windows.  For example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* from app code, require('electron').remote calls back to main process */
 | 
			
		||||
var dialog = require('electron').remote.dialog;
 | 
			
		||||
var o = (dialog.showOpenDialog({ properties: ['openFile'] })||[''])[0];
 | 
			
		||||
var workbook = X.readFile(o);
 | 
			
		||||
 | 
			
		||||
/* show a file-open dialog and read the first selected file */
 | 
			
		||||
var o = dialog.showOpenDialog({ properties: ['openFile'] });
 | 
			
		||||
var workbook = X.readFile(o[0]);
 | 
			
		||||
 | 
			
		||||
/* show a file-save dialog and write the workbook */
 | 
			
		||||
var o = dialog.showSaveDialog();
 | 
			
		||||
XLSX.writeFile(workbook, o);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ a { text-decoration: none }
 | 
			
		||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
 | 
			
		||||
 | 
			
		||||
</pre>
 | 
			
		||||
<p><input type="submit" value="Export Data!" id="xport" onclick="export_xlsx();" disabled="true"></p>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="index.js"></script>
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,15 @@
 | 
			
		||||
var X = require('xlsx');
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
var electron = require('electron').remote;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
	var XPORT = document.getElementById('xport');
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		XPORT.disabled = false;
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		wb.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(wb, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			var htmlstr = XLSX.utils.sheet_to_html(wb.Sheets[sheetName],{editable:true});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
@ -30,7 +32,7 @@ var do_file = (function() {
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			data = new Uint8Array(data);
 | 
			
		||||
			process_wb(X.read(data, {type: 'array'}));
 | 
			
		||||
			process_wb(XLSX.read(data, {type: 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
@ -67,7 +69,7 @@ var do_file = (function() {
 | 
			
		||||
			}],
 | 
			
		||||
			properties: ['openFile']
 | 
			
		||||
		});
 | 
			
		||||
		if(o.length > 0) process_wb(X.readFile(o[0]));
 | 
			
		||||
		if(o.length > 0) process_wb(XLSX.readFile(o[0]));
 | 
			
		||||
	}
 | 
			
		||||
	readf.addEventListener('click', handleF, false);
 | 
			
		||||
})();
 | 
			
		||||
@ -77,3 +79,21 @@ var do_file = (function() {
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var export_xlsx = (function() {
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
	var XTENSION = "xls|xlsx|xlsm|xlsb|xml|csv|txt|dif|sylk|slk|prn|ods|fods|htm|html".split("|")
 | 
			
		||||
	return function() {
 | 
			
		||||
		var wb = XLSX.utils.table_to_book(HTMLOUT);
 | 
			
		||||
		var o = electron.dialog.showSaveDialog({
 | 
			
		||||
			title: 'Save file as',
 | 
			
		||||
			filters: [{
 | 
			
		||||
				name: "Spreadsheets",
 | 
			
		||||
				extensions: XTENSION
 | 
			
		||||
			}]
 | 
			
		||||
		});
 | 
			
		||||
		console.log(o);
 | 
			
		||||
		XLSX.writeFile(wb, o);
 | 
			
		||||
		electron.dialog.showMessageBox({ message: "Exported data to " + o, buttons: ["OK"] });
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,34 @@
 | 
			
		||||
# ExtendScript demos
 | 
			
		||||
# Adobe ExtendScript
 | 
			
		||||
 | 
			
		||||
ExtendScript adds some features to a limited form of ECMAScript version 3.  With
 | 
			
		||||
the included shim, the library can run within Photoshop and other Adobe apps!
 | 
			
		||||
 | 
			
		||||
The main file is `test.jsx`.  Target-specific files prepend target directives.
 | 
			
		||||
 | 
			
		||||
Copy the `test.jsx` file as well as the `shim.js` and `xlsx.core.min.js` files
 | 
			
		||||
to wherever you want the scripts to reside.  The demo shows opening a file and
 | 
			
		||||
converting to an array of arrays.
 | 
			
		||||
to wherever you want the scripts to reside.
 | 
			
		||||
 | 
			
		||||
The demo shows opening a file and converting to an array of arrays:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* include library */
 | 
			
		||||
#include "shim.js"
 | 
			
		||||
#include "xlsx.core.min.js"
 | 
			
		||||
 | 
			
		||||
/* get data as binary string */
 | 
			
		||||
var filename = "sheetjs.xlsx";
 | 
			
		||||
var base = new File($.fileName);
 | 
			
		||||
var infile = File(base.path + "/" + filename);
 | 
			
		||||
infile.open("r");
 | 
			
		||||
infile.encoding = "binary";
 | 
			
		||||
var data = infile.read();
 | 
			
		||||
 | 
			
		||||
/* parse data */
 | 
			
		||||
var workbook = XLSX.read(data, {type:"binary"});
 | 
			
		||||
 | 
			
		||||
/* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
NOTE: [We forked the minifier](https://www.npmjs.com/package/@sheetjs/uglify-js)
 | 
			
		||||
and included a bugfix for ExtendScript's misparsing of switch statements.
 | 
			
		||||
and included a patch for ExtendScript's switch statement semicolon issue.
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/headless/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/headless/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
*.pdf
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
# Headless Browsers
 | 
			
		||||
 | 
			
		||||
The library, intentionally conservative in the use of ES5+ features, plays nicely
 | 
			
		||||
The library, eschewing unstable and nascent ECMAScript features, plays nicely
 | 
			
		||||
with most headless browsers.  This demo shows a few common headless scenarios.
 | 
			
		||||
 | 
			
		||||
## PhantomJS
 | 
			
		||||
 | 
			
		||||
This was tested in phantomjs 2.1.1, installed using the node module:
 | 
			
		||||
This was tested in PhantomJS 2.1.1, installed using the node module:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ npm install -g phantomjs
 | 
			
		||||
@ -17,12 +17,12 @@ $ phantomjs phantomjs.js
 | 
			
		||||
This was tested in wkhtmltopdf 0.12.4, installed using the official binaries:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ wkhtmltopdf --javascript-delay 60000 http://localhost:8000/ test.pdf
 | 
			
		||||
``` 
 | 
			
		||||
$ wkhtmltopdf --javascript-delay 20000 http://oss.sheetjs.com/js-xlsx/tests/ test.pdf
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Puppeteer
 | 
			
		||||
 | 
			
		||||
This was tested in puppeteer 0.9.0 and Chromium r494755, installed using node:
 | 
			
		||||
This was tested in puppeteer 0.9.0 and Chromium revision 494755:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ npm install puppeteer
 | 
			
		||||
@ -34,10 +34,11 @@ the webpage.  The `dist` versions are suitable for web pages.
 | 
			
		||||
 | 
			
		||||
## SlimerJS
 | 
			
		||||
 | 
			
		||||
This was tested in slimerjs 0.10.3 and FF 52.0, installed using `brew` on OSX:
 | 
			
		||||
This was tested in SlimerJS 0.10.3 and FF 52.0, installed using `brew` on OSX:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ brew install slimerjs
 | 
			
		||||
$ slimerjs slimerjs.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ var fs = require('fs');
 | 
			
		||||
var xlsx = require('../../xlsx');
 | 
			
		||||
var page = require('webpage').create();
 | 
			
		||||
 | 
			
		||||
page.open('http://www.google.com', function(status) {
 | 
			
		||||
page.open('http://oss.sheetjs.com/js-xlsx/tests/', function(status) {
 | 
			
		||||
 | 
			
		||||
  var data = fs.read('sheetjs.xlsx', {mode: 'rb', charset: 'utf8'});
 | 
			
		||||
  var workbook = xlsx.read(data, {type: 'binary'});
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ const puppeteer = require('puppeteer');
 | 
			
		||||
 | 
			
		||||
  const browser = await puppeteer.launch();
 | 
			
		||||
  const page = await browser.newPage();
 | 
			
		||||
  await page.goto('http://localhost:8000', {waitUntil: 'load'});
 | 
			
		||||
  await page.goto('http://oss.sheetjs.com/js-xlsx/tests/', {waitUntil: 'load'});
 | 
			
		||||
	await page.waitFor(30*1000);
 | 
			
		||||
  await page.pdf({path: 'test.pdf', format: 'A4'});
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ var fs = require('fs');
 | 
			
		||||
var xlsx = require('../../dist/xlsx.full.min');
 | 
			
		||||
var page = require('webpage').create();
 | 
			
		||||
 | 
			
		||||
page.open('http://www.google.com', function(status) {
 | 
			
		||||
page.open('http://oss.sheetjs.com/js-xlsx/tests/', function(status) {
 | 
			
		||||
 | 
			
		||||
  var data = fs.read('sheetjs.xlsx', {mode: 'rb', charset: 'utf8'});
 | 
			
		||||
  var workbook = xlsx.read(data, {type: 'binary'});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/meteor/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/meteor/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +1,2 @@
 | 
			
		||||
.meteor
 | 
			
		||||
node_modules/
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,11 @@ start:
 | 
			
		||||
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init:
 | 
			
		||||
	if [ ! -e .meteor ]; then meteor create .; fi;
 | 
			
		||||
	@npm install babel-runtime meteor-node-stubs
 | 
			
		||||
	@meteor add pfafman:filesaver
 | 
			
		||||
	@meteor add pfafman:filesaver check
 | 
			
		||||
	@mkdir -p node_modules; cd node_modules; ln -s ../../../ xlsx; cd -
 | 
			
		||||
 | 
			
		||||
.PHONY: lint
 | 
			
		||||
lint:
 | 
			
		||||
	@meteor npm run lint
 | 
			
		||||
@ -5,34 +5,70 @@ tables in the browser, streaming write in nodejs), the core is ES3/ES5 and can
 | 
			
		||||
be used in any reasonably compliant JS implementation.  It should play nice with
 | 
			
		||||
meteor out of the box.
 | 
			
		||||
 | 
			
		||||
Using the npm module, the library can be imported from client or server side:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import XLSX from 'xlsx'
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
All of the functions and utilities are available in both realms. Since the core
 | 
			
		||||
data representations are simple JS objects, the workbook object can be passed on
 | 
			
		||||
the wire, enabling hybrid workflows where the server processes data and client
 | 
			
		||||
finishes the work.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## This demonstration
 | 
			
		||||
 | 
			
		||||
You can split the work between the client and server side as you see fit.  The
 | 
			
		||||
obvious extremes of pure-client code and pure-server code are straightforward.
 | 
			
		||||
This demo tries to split the work to demonstrate that the workbook object can be
 | 
			
		||||
passed on the wire.
 | 
			
		||||
Note: the obvious extremes of pure-client code and pure-server code are covered
 | 
			
		||||
in other demos.
 | 
			
		||||
 | 
			
		||||
The read demo:
 | 
			
		||||
### Reading Data
 | 
			
		||||
 | 
			
		||||
The parse demo:
 | 
			
		||||
- accepts files from the client side
 | 
			
		||||
- sends binary string to server
 | 
			
		||||
- processes data on server side
 | 
			
		||||
- sends workbook object to client
 | 
			
		||||
- renders HTML and adds to a DOM element
 | 
			
		||||
 | 
			
		||||
The write demo:
 | 
			
		||||
- generates workbook on server side
 | 
			
		||||
- sends workbook object to client
 | 
			
		||||
- generates file on client side
 | 
			
		||||
- triggers a download.
 | 
			
		||||
The logic from within the `FileReader` is split as follows:
 | 
			
		||||
 | 
			
		||||
This demo uses the FileSaver.js library for writing files, installed through the
 | 
			
		||||
[`pfafman:filesaver` wrapper](https://atmospherejs.com/pfafman/filesaver):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
meteor add pfafman:filesaver
 | 
			
		||||
```js
 | 
			
		||||
// CLIENT SIDE
 | 
			
		||||
const bstr = e.target.result;
 | 
			
		||||
// SERVER SIDE
 | 
			
		||||
const wb = XLSX.read(bstr, { type: 'binary' });
 | 
			
		||||
// CLIENT SIDE
 | 
			
		||||
const ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
const html = XLSX.utils.sheet_to_html(ws, { editable: true });
 | 
			
		||||
document.getElementById('out').innerHTML = html;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Writing Data
 | 
			
		||||
 | 
			
		||||
The write demo:
 | 
			
		||||
- grabs HTML from the client side
 | 
			
		||||
- sends HTML string to server
 | 
			
		||||
- processes data on server side
 | 
			
		||||
- sends workbook object to client
 | 
			
		||||
- generates file on client side and triggers a download
 | 
			
		||||
 | 
			
		||||
The logic from within the `click` event is split as follows:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// CLIENT SIDE
 | 
			
		||||
const html = document.getElementById('out').innerHTML;
 | 
			
		||||
// SERVER SIDE
 | 
			
		||||
const wb = XLSX.read(html, { type: 'binary' });
 | 
			
		||||
// CLIENT SIDE
 | 
			
		||||
const o = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
 | 
			
		||||
saveAs(new Blob([s2ab(o)], {type:'application/octet-stream'}), 'sheetjs.xlsx');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This demo uses the FileSaver library for writing files, installed through the
 | 
			
		||||
[`pfafman:filesaver` wrapper](https://atmospherejs.com/pfafman/filesaver).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Setup
 | 
			
		||||
 | 
			
		||||
This tree does not include the `.meteor` structure.  Rebuild the project with:
 | 
			
		||||
@ -45,12 +81,14 @@ meteor
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Environment-specific features
 | 
			
		||||
## Environment-Specific Features
 | 
			
		||||
 | 
			
		||||
File-related operations (e.g. `XLSX.readFile` and `XLSX.writeFile`) will not be
 | 
			
		||||
File-related operations like `XLSX.readFile` and `XLSX.writeFile` will not be
 | 
			
		||||
available in client-side code. If you need to read a local file from the client,
 | 
			
		||||
use a file input or drag-and-drop.
 | 
			
		||||
 | 
			
		||||
Browser-specific operations (e.g. `XLSX.utils.table_to_book`) are limited to
 | 
			
		||||
Browser-specific operations like `XLSX.utils.table_to_book` are limited to
 | 
			
		||||
client side code. You should never have to read from DOM elements on the server
 | 
			
		||||
side, but you can use a third-party virtual DOM to provide the required API.
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -6,22 +6,13 @@
 | 
			
		||||
<pre>
 | 
			
		||||
<b><a href="//sheetjs.com">SheetJS Meteor Demo</a></b>
 | 
			
		||||
 | 
			
		||||
<b>Meteor Read Demo</b>
 | 
			
		||||
 | 
			
		||||
{{> read}}
 | 
			
		||||
 | 
			
		||||
<b>Meteor Write Demo</b>
 | 
			
		||||
 | 
			
		||||
{{> write}}
 | 
			
		||||
{{> sheetjs}}
 | 
			
		||||
 | 
			
		||||
</pre>
 | 
			
		||||
</body>
 | 
			
		||||
 | 
			
		||||
<template name="read">
 | 
			
		||||
<template name="sheetjs">
 | 
			
		||||
	<label for="upload">Parse File: </label><input type="file" id="upload" />
 | 
			
		||||
	<div id="out"></div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<template name="write">
 | 
			
		||||
	<label for="dnload">Write File: </label><button id="dnload">Generate Worksheet</button>
 | 
			
		||||
	<button id="dnload" disabled="true">Generate Worksheet</button>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@ -1,51 +1,49 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
/* note: saveAs is made available via the smart package */
 | 
			
		||||
/* global saveAs */
 | 
			
		||||
 | 
			
		||||
import { Meteor } from 'meteor/meteor';
 | 
			
		||||
import { Template } from 'meteor/templating';
 | 
			
		||||
import { ReactiveVar } from 'meteor/reactive-var';
 | 
			
		||||
 | 
			
		||||
import './main.html';
 | 
			
		||||
 | 
			
		||||
const XLSX = require('xlsx');
 | 
			
		||||
 | 
			
		||||
Template.read.events({
 | 
			
		||||
	'change input' (evt, instance) {
 | 
			
		||||
		/* "Browser file upload form element" from SheetJS README */
 | 
			
		||||
		const file = evt.currentTarget.files[0];
 | 
			
		||||
		const reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			const data = e.target.result;
 | 
			
		||||
			const name = file.name;
 | 
			
		||||
			/* Meteor magic */
 | 
			
		||||
			Meteor.call('upload', data, name, function(err, wb) {
 | 
			
		||||
				if(err) console.error(err);
 | 
			
		||||
				else {
 | 
			
		||||
					/* do something here -- this just dumps an array of arrays to console */
 | 
			
		||||
					console.log(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {header:1}));
 | 
			
		||||
					document.getElementById('out').innerHTML = (XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]));
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsBinaryString(file);
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Template.write.events({
 | 
			
		||||
	'click button' (evt, instance) {
 | 
			
		||||
		Meteor.call('download', function(err, wb) {
 | 
			
		||||
			if(err) console.error(err);
 | 
			
		||||
			else {
 | 
			
		||||
				console.log(wb);
 | 
			
		||||
				/* "Browser download file" from SheetJS README */
 | 
			
		||||
				var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
 | 
			
		||||
				var wbout = XLSX.write(wb, wopts);
 | 
			
		||||
				saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "meteor.xlsx");
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
Template.sheetjs.events({
 | 
			
		||||
  'change input' (event) {
 | 
			
		||||
    /* "Browser file upload form element" from SheetJS README */
 | 
			
		||||
    const file = event.currentTarget.files[0];
 | 
			
		||||
    const reader = new FileReader();
 | 
			
		||||
    reader.onload = function(e) {
 | 
			
		||||
      const data = e.target.result;
 | 
			
		||||
      const name = file.name;
 | 
			
		||||
      /* Meteor magic */
 | 
			
		||||
      Meteor.call('upload', data, name, function(err, wb) {
 | 
			
		||||
        if (err) throw err;
 | 
			
		||||
        /* load the first worksheet */
 | 
			
		||||
        const ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
        /* generate HTML table and enable export */
 | 
			
		||||
        const html = XLSX.utils.sheet_to_html(ws, { editable: true });
 | 
			
		||||
        document.getElementById('out').innerHTML = html;
 | 
			
		||||
        document.getElementById('dnload').disabled = false;
 | 
			
		||||
      });
 | 
			
		||||
    };
 | 
			
		||||
    reader.readAsBinaryString(file);
 | 
			
		||||
  },
 | 
			
		||||
  'click button' () {
 | 
			
		||||
    const html = document.getElementById('out').innerHTML;
 | 
			
		||||
    Meteor.call('download', html, function(err, wb) {
 | 
			
		||||
      if (err) throw err;
 | 
			
		||||
      /* "Browser download file" from SheetJS README */
 | 
			
		||||
      const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
 | 
			
		||||
      saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), 'sheetjs.xlsx');
 | 
			
		||||
    });
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/* eslint no-bitwise:0, no-plusplus:0 */
 | 
			
		||||
function s2ab(s) {
 | 
			
		||||
	var buf = new ArrayBuffer(s.length);
 | 
			
		||||
	var view = new Uint8Array(buf);
 | 
			
		||||
	for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
 | 
			
		||||
	return buf;
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,27 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "meteor-xlsx",
 | 
			
		||||
  "version": "0.0.0",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "lint": "eslint .",
 | 
			
		||||
    "start": "meteor run"
 | 
			
		||||
  },
 | 
			
		||||
  "eslintConfig": {
 | 
			
		||||
    "extends": "@meteorjs/eslint-config-meteor"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "babel-runtime": "^6.20.0",
 | 
			
		||||
    "meteor-node-stubs": "~0.2.4"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@meteorjs/eslint-config-meteor": "^1.0.5",
 | 
			
		||||
    "babel-eslint": "^7.2.3",
 | 
			
		||||
    "eslint": "^3.19.0",
 | 
			
		||||
    "eslint-config-airbnb": "^13.0.0",
 | 
			
		||||
    "eslint-import-resolver-meteor": "^0.3.4",
 | 
			
		||||
    "eslint-plugin-import": "^2.7.0",
 | 
			
		||||
    "eslint-plugin-jsx-a11y": "^2.2.3",
 | 
			
		||||
    "eslint-plugin-meteor": "^4.1.4",
 | 
			
		||||
    "eslint-plugin-react": "^6.10.3"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,30 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
import { Meteor } from 'meteor/meteor';
 | 
			
		||||
 | 
			
		||||
const XLSX = require('xlsx');
 | 
			
		||||
import { check } from 'meteor/check';
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
 | 
			
		||||
Meteor.methods({
 | 
			
		||||
	upload: (bstr, name) => {
 | 
			
		||||
		/* read the data and return the workbook object to the frontend */
 | 
			
		||||
		return XLSX.read(bstr, {type:'binary'});
 | 
			
		||||
	},
 | 
			
		||||
	download: () => {
 | 
			
		||||
		/* generate a workbook object and return to the frontend */
 | 
			
		||||
		const data = [
 | 
			
		||||
			["a", "b", "c"],
 | 
			
		||||
			[ 1 ,  2 ,  3 ]
 | 
			
		||||
		];
 | 
			
		||||
		const ws = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
		const wb = {SheetNames: ["Sheet1"], Sheets:{Sheet1:ws }};
 | 
			
		||||
		return wb;
 | 
			
		||||
	}
 | 
			
		||||
  upload: (bstr, name) => {
 | 
			
		||||
    /* read the data and return the workbook object to the frontend */
 | 
			
		||||
    check(bstr, String);
 | 
			
		||||
    check(name, String);
 | 
			
		||||
    return XLSX.read(bstr, { type: 'binary' });
 | 
			
		||||
  },
 | 
			
		||||
  download: (html) => {
 | 
			
		||||
    check(html, String);
 | 
			
		||||
    let wb;
 | 
			
		||||
    if (html.length > 3) {
 | 
			
		||||
      /* parse workbook if html is available */
 | 
			
		||||
      wb = XLSX.read(html, { type: 'binary' });
 | 
			
		||||
    } else {
 | 
			
		||||
      /* generate a workbook object otherwise */
 | 
			
		||||
      const data = [['a', 'b', 'c'], [1, 2, 3]];
 | 
			
		||||
      const ws = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
      wb = XLSX.utils.book_new();
 | 
			
		||||
      XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
 | 
			
		||||
    }
 | 
			
		||||
    return wb;
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
Meteor.startup(() => { });
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,34 @@
 | 
			
		||||
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.
 | 
			
		||||
## Reading data
 | 
			
		||||
 | 
			
		||||
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/)
 | 
			
		||||
the [SheetJS Data Preview Live Demo](http://oss.sheetjs.com/js-xlsx/).
 | 
			
		||||
 | 
			
		||||
## Writing data
 | 
			
		||||
 | 
			
		||||
File input elements with the attribute `nwsaveas` show UI for saving a file. The
 | 
			
		||||
standard trick is to generate a hidden file input DOM element and "click" it.
 | 
			
		||||
Since NW.js does not present a `writeFileSync` in the `fs` package, a manual
 | 
			
		||||
step is required:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* from within the input change callback, `this.value` is the file name */
 | 
			
		||||
var filename = this.value, bookType = (filename.match(/[^\.]*$/)||["xlsx"])[0];
 | 
			
		||||
 | 
			
		||||
/* convert the TABLE element back to a workbook */
 | 
			
		||||
var wb = XLSX.utils.table_to_book(HTMLOUT);
 | 
			
		||||
 | 
			
		||||
/* write to buffer */
 | 
			
		||||
var wbout = XLSX.write(wb, {type:'buffer', bookType:bookType});
 | 
			
		||||
 | 
			
		||||
/* use the async fs.writeFile to save the data */
 | 
			
		||||
fs.writeFile(filename, wbout, function(err) {
 | 
			
		||||
	if(!err) return alert("Saved to " + filename);
 | 
			
		||||
	alert("Error: " + (err.message || err));
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ a { text-decoration: none }
 | 
			
		||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
 | 
			
		||||
 | 
			
		||||
</pre>
 | 
			
		||||
<p><input type="submit" value="Export Data!" id="xport" onclick="export_xlsx();" disabled="true"></p>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,14 @@
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
	var XPORT = document.getElementById('xport');
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		XPORT.disabled = false;
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		wb.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(wb, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			var htmlstr = XLSX.utils.sheet_to_html(wb.Sheets[sheetName],{editable:true});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
	};
 | 
			
		||||
@ -29,7 +31,7 @@ var do_file = (function() {
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			data = new Uint8Array(data);
 | 
			
		||||
			process_wb(X.read(data, {type: 'array'}));
 | 
			
		||||
			process_wb(XLSX.read(data, {type: 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
@ -60,3 +62,25 @@ var do_file = (function() {
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var export_xlsx = (function() {
 | 
			
		||||
	/* pre-build the nwsaveas input element */
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
	var input = document.createElement('input');
 | 
			
		||||
	input.style.display = 'none';
 | 
			
		||||
	input.setAttribute('nwsaveas', 'sheetjs.xlsx');
 | 
			
		||||
	input.setAttribute('type', 'file');
 | 
			
		||||
	document.body.appendChild(input);
 | 
			
		||||
	input.addEventListener('cancel',function(){ alert("Save was canceled!"); });
 | 
			
		||||
	input.addEventListener('change',function(e){
 | 
			
		||||
		var filename=this.value, bookType=(filename.match(/[^\.]*$/)||["xlsx"])[0];
 | 
			
		||||
		var wb = XLSX.utils.table_to_book(HTMLOUT);
 | 
			
		||||
		var wbout = XLSX.write(wb, {type:'buffer', bookType:bookType});
 | 
			
		||||
		fs.writeFile(filename, wbout, function(err) {
 | 
			
		||||
			if(!err) return alert("Saved to " + filename);
 | 
			
		||||
			alert("Error: " + (err.message || err));
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	return function() { input.click(); };
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,9 @@ react: ## Simple server for react and clones
 | 
			
		||||
	python -mSimpleHTTPServer
 | 
			
		||||
 | 
			
		||||
.PHONY: next
 | 
			
		||||
next: ## next.js demo
 | 
			
		||||
	# next doesn't support jsx extension
 | 
			
		||||
next: init ## next.js demo
 | 
			
		||||
	mkdir -p pages
 | 
			
		||||
	cp sheetjs.jsx pages/sheetjs.js
 | 
			
		||||
	cat nexthdr.js sheetjs.jsx > pages/sheetjs.js
 | 
			
		||||
	next
 | 
			
		||||
 | 
			
		||||
.PHONY: native
 | 
			
		||||
@ -20,3 +19,9 @@ ios: native ## react-native ios sim
 | 
			
		||||
.PHONY: android
 | 
			
		||||
android: native ## react-native android sim
 | 
			
		||||
	cd SheetJS; react-native run-android; cd -
 | 
			
		||||
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init: ## set up node_modules and symlink
 | 
			
		||||
	mkdir -p node_modules
 | 
			
		||||
	cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd -
 | 
			
		||||
	if [ ! -e node_modules/file-saver ]; then npm install file-saver; fi
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
# 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.
 | 
			
		||||
into web pages with script tags:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
@ -30,11 +30,7 @@ state in this demo is shaped like the following object:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
{
 | 
			
		||||
  cols: [
 | 
			
		||||
    { name: "A", key: 0 },
 | 
			
		||||
    { name: "B", key: 1 },
 | 
			
		||||
    { name: "C", key: 2 },
 | 
			
		||||
  ],
 | 
			
		||||
  cols: [{ name: "A", key: 0 }, { name: "B", key: 1 }, { name: "C", key: 2 }],
 | 
			
		||||
  data: [
 | 
			
		||||
    [ "id",    "name", "value" ],
 | 
			
		||||
    [    1, "sheetjs",    7262 ]
 | 
			
		||||
@ -43,7 +39,32 @@ state in this demo is shaped like the following object:
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The appropriate state model is application-specific.
 | 
			
		||||
`sheet_to_json` and `aoa_to_sheet` utility functions can convert between arrays
 | 
			
		||||
of arrays and worksheets:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* convert from workbook to array of arrays */
 | 
			
		||||
var first_worksheet = workbook.Sheets[workbook.SheetNames[0]];
 | 
			
		||||
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
 | 
			
		||||
 | 
			
		||||
/* convert from array of arrays to workbook */
 | 
			
		||||
var worksheet = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
var new_workbook = XLSX.utils.book_new();
 | 
			
		||||
XLSX.utils.book_append_sheet(new_workbook, worksheet, "SheetJS");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The column objects can be generated with the `encode_col` utility function:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
function make_cols(refstr/*:string*/) {
 | 
			
		||||
  var o = [];
 | 
			
		||||
  var range = XLSX.utils.decode_range(refstr);
 | 
			
		||||
  for(var i = 0; i <= range.e.c; ++i) {
 | 
			
		||||
    o.push({name: XLSX.utils.encode_col(i), key:i});
 | 
			
		||||
  }
 | 
			
		||||
  return o;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## React Native
 | 
			
		||||
 | 
			
		||||
@ -52,6 +73,7 @@ The appropriate state model is application-specific.
 | 
			
		||||
Reproducing the full project is straightforward:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
# see native.sh
 | 
			
		||||
react-native init SheetJS
 | 
			
		||||
cd SheetJS
 | 
			
		||||
npm i -S xlsx react react-native react-native-table-component react-native-fs
 | 
			
		||||
@ -60,9 +82,44 @@ 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:
 | 
			
		||||
`react-native-table-component` draws the data table.  `react-native-fs` reads
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
`react-native-fs` supports `"ascii"` encoding for `readFile` and `writeFile`.
 | 
			
		||||
In practice, that encoding uses binary strings compatible with `"binary"` type:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import { writeFile, readFile } from 'react-native-fs';
 | 
			
		||||
 | 
			
		||||
/* read a workbook */
 | 
			
		||||
readFile(file, 'ascii').then((res) => {
 | 
			
		||||
  const workbook = XLSX.read(res, {type:'binary'});
 | 
			
		||||
  /* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/* write a workbook */
 | 
			
		||||
const wbout = XLSX.write(wb, {type:'binary', bookType:"xlsx"});
 | 
			
		||||
writeFile(file, wbout, 'ascii').then((r)=>{/* :) */}).catch((e)=>{/* :( */});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Other Demos
 | 
			
		||||
 | 
			
		||||
#### Preact
 | 
			
		||||
 | 
			
		||||
`preact-compat` is an easy-to-use compatibility layer that provides equivalents
 | 
			
		||||
for `React` and `ReactDOM`.  The `preact` demo uses the same JSX component code!
 | 
			
		||||
[The docs](https://npm.im/preact-compat#use-without-webpackbrowserify) explain
 | 
			
		||||
how to convert the in-browser React demo to Preact.
 | 
			
		||||
 | 
			
		||||
#### Server-Rendered React Components with Next.js
 | 
			
		||||
 | 
			
		||||
The demo uses the same component code as the in-browser version, but the build
 | 
			
		||||
step adds a small header that imports the library.  The import is not needed in
 | 
			
		||||
deployments that use script tags to include the library.
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
if [ ! -e SheetJS ]; then
 | 
			
		||||
	react-native init SheetJS
 | 
			
		||||
	cd SheetJS
 | 
			
		||||
@ -13,5 +13,5 @@ fi
 | 
			
		||||
cp react-native.js SheetJS/index.ios.js
 | 
			
		||||
cp react-native.js SheetJS/index.android.js
 | 
			
		||||
cd SheetJS;
 | 
			
		||||
react-native link
 | 
			
		||||
RNFB_ANDROID_PERMISSIONS=true react-native link
 | 
			
		||||
cd -;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								demos/react/nexthdr.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								demos/react/nexthdr.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
import * as XLSX from 'xlsx';
 | 
			
		||||
import { saveAs } from 'file-saver';
 | 
			
		||||
@ -6,16 +6,11 @@ export default () => (
 | 
			
		||||
		<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">
 | 
			
		||||
	<div className="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 />
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								demos/react/react-native.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										31
									
								
								demos/react/react-native.js
									
									
									
									
										vendored
									
									
								
							@ -1,13 +1,24 @@
 | 
			
		||||
/* 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'
 | 
			
		||||
 | 
			
		||||
// react-native-fs
 | 
			
		||||
import { writeFile, readFile, DocumentDirectoryPath } from 'react-native-fs';
 | 
			
		||||
const DDP = DocumentDirectoryPath + "/";
 | 
			
		||||
const input = res => res;
 | 
			
		||||
const output = str => str;
 | 
			
		||||
 | 
			
		||||
// react-native-fetch-blob
 | 
			
		||||
/*
 | 
			
		||||
import RNFetchBlob from 'react-native-fetch-blob';
 | 
			
		||||
const { writeFile, readFile, dirs:{ DocumentDir } } = RNFetchBlob.fs;
 | 
			
		||||
const DDP = DocumentDir + "/";
 | 
			
		||||
const input = res => res.map(x => String.fromCharCode(x)).join("");
 | 
			
		||||
const output = str => str.split("").map(x => x.charCodeAt(0));
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const make_cols = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, (x,i) => XLSX.utils.encode_col(i));
 | 
			
		||||
 | 
			
		||||
@ -26,22 +37,32 @@ export default class SheetJS extends Component {
 | 
			
		||||
			{text: 'Cancel', onPress: () => {}, style: 'cancel' },
 | 
			
		||||
			{text: 'Import', onPress: () => {
 | 
			
		||||
				readFile(DDP + "sheetjs.xlsx", 'ascii').then((res) => {
 | 
			
		||||
					const wb = XLSX.read(res, {type:'binary'});
 | 
			
		||||
					/* parse file */
 | 
			
		||||
					const wb = XLSX.read(input(res), {type:'binary'});
 | 
			
		||||
 | 
			
		||||
					/* convert first worksheet to AOA */
 | 
			
		||||
					const wsname = wb.SheetNames[0];
 | 
			
		||||
					const ws = wb.Sheets[wsname];
 | 
			
		||||
					const data = XLSX.utils.sheet_to_json(ws, {header:1});
 | 
			
		||||
 | 
			
		||||
					/* update state */
 | 
			
		||||
					this.setState({ data: data, cols: make_cols(ws['!ref']) });
 | 
			
		||||
				}).catch((err) => { Alert.alert("importFile Error", "Error " + err.message); });
 | 
			
		||||
			}}
 | 
			
		||||
		]);
 | 
			
		||||
	}
 | 
			
		||||
	exportFile() {
 | 
			
		||||
		/* convert AOA back to worksheet */
 | 
			
		||||
		const ws = XLSX.utils.aoa_to_sheet(this.state.data);
 | 
			
		||||
 | 
			
		||||
		/* build new workbook */
 | 
			
		||||
		const wb = XLSX.utils.book_new();
 | 
			
		||||
		XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
		const wbout = XLSX.write(wb, {type:"binary", bookType:"xlsx"});
 | 
			
		||||
 | 
			
		||||
		/* write file */
 | 
			
		||||
		const wbout = XLSX.write(wb, {type:'binary', bookType:"xlsx"});
 | 
			
		||||
		const file = DDP + "sheetjsw.xlsx";
 | 
			
		||||
		writeFile(file, wbout, 'ascii').then((res) =>{
 | 
			
		||||
		writeFile(file, output(wbout), 'ascii').then((res) =>{
 | 
			
		||||
				Alert.alert("exportFile success", "Exported to " + file);
 | 
			
		||||
		}).catch((err) => { Alert.alert("exportFile Error", "Error " + err.message); });
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@ -1,95 +1,16 @@
 | 
			
		||||
/* 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;
 | 
			
		||||
/* Notes:
 | 
			
		||||
   - usage: `ReactDOM.render( <SheetJSApp />, document.getElementById('app') );`
 | 
			
		||||
   - xlsx.full.min.js is loaded in the head of the HTML page
 | 
			
		||||
   - this script should be referenced with type="text/babel"
 | 
			
		||||
   - babel.js in-browser transpiler should be loaded before this script
 | 
			
		||||
*/
 | 
			
		||||
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 } */
 | 
			
		||||
			cols: []  /* Array of column objects e.g. { name: "C", K: 2 } */
 | 
			
		||||
		};
 | 
			
		||||
		this.handleFile = this.handleFile.bind(this);
 | 
			
		||||
		this.exportFile = this.exportFile.bind(this);
 | 
			
		||||
@ -137,3 +58,91 @@ class SheetJSApp extends React.Component {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if(typeof module !== 'undefined') module.exports = SheetJSApp
 | 
			
		||||
 | 
			
		||||
/* -------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  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>
 | 
			
		||||
	); };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
  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 key={c.key}>{c.name}</th>)}</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tbody>
 | 
			
		||||
			{this.props.data.map((r,i) => <tr key={i}>
 | 
			
		||||
				{this.props.cols.map(c => <td key={c.key}>{ r[c.key] }</td>)}
 | 
			
		||||
			</tr>)}
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>
 | 
			
		||||
	); };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* list of supported file types */
 | 
			
		||||
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(",");
 | 
			
		||||
 | 
			
		||||
/* see Browser download file example in docs */
 | 
			
		||||
function s2ab(s/*:string*/)/*:ArrayBuffer*/ {
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 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}));
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								demos/requirejs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/requirejs/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
xlsx.full*
 | 
			
		||||
r.js
 | 
			
		||||
require.js
 | 
			
		||||
requirejs-built.js
 | 
			
		||||
app-built.js
 | 
			
		||||
 | 
			
		||||
@ -7,4 +7,4 @@ $(TOOL).js:
 | 
			
		||||
	if [ ! -e require.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/comments/require.js; fi
 | 
			
		||||
	if [ ! -e r.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/r.js; fi
 | 
			
		||||
	rm -f xlsx.full.min.js; ln -s ../../dist/xlsx.full.min.js
 | 
			
		||||
	node r.js -o build.js
 | 
			
		||||
	node r.js -o build.js paths.requireLib=./require include=requireLib
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,75 @@
 | 
			
		||||
 | 
			
		||||
The minified dist files trip up the RequireJS mechanism.  To bypass, the scripts
 | 
			
		||||
automatically expose an `XLSX` variable that can be used if the require callback
 | 
			
		||||
argument is `_XLSX` rather than `XLSX`:
 | 
			
		||||
argument is `_XLSX` rather than `XLSX`.  This trick is employed in the included
 | 
			
		||||
`xlsx-shim.js` script:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
require(["xlsx.full.min"], function(_XLSX) { /* ... */ });
 | 
			
		||||
/* xlsx-shim.js */
 | 
			
		||||
define(['xlsx'], function (_XLSX) {
 | 
			
		||||
	return XLSX;
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This demo uses the `r.js` optimizer to build a source file.
 | 
			
		||||
The require config should set `xlsx` path to the appropriate dist file:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
	paths: {
 | 
			
		||||
		xlsx: "xlsx.full.min"
 | 
			
		||||
	},
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Once that is set, app code can freely require `"xlsx-shim"`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
require(["xlsx-shim"], function(XLSX) {
 | 
			
		||||
	/* use XLSX here */
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Deployments
 | 
			
		||||
 | 
			
		||||
`browser.html` demonstrates a dynamic deployment, using the in-browser config:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="require.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
require.config({
 | 
			
		||||
	baseUrl: ".",
 | 
			
		||||
	name: "app",
 | 
			
		||||
	paths: {
 | 
			
		||||
		xlsx: "xlsx.full.min"
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
<script src="app.js"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`optimizer.html` demonstrates an optimized deployment using `build.js` config:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* build config */
 | 
			
		||||
({
 | 
			
		||||
	baseUrl: ".",
 | 
			
		||||
	name: "app",
 | 
			
		||||
	paths: {
 | 
			
		||||
		xlsx: "xlsx.full.min"
 | 
			
		||||
	},
 | 
			
		||||
	out: "app-built.js"
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The optimizer is invoked with:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node r.js -o build.js paths.requireLib=./require include=requireLib
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
That step creates a file `app-built.js` that can be included in a page:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<!-- final bundle includes require.js, xlsx-shim, library and app code -->
 | 
			
		||||
<script src="app-built.js"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
require(["xlsx.full.min"], function(_XLSX) {
 | 
			
		||||
require(["xlsx-shim"], function(XLSX) {
 | 
			
		||||
console.log(XLSX);
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
							
								
								
									
										69
									
								
								demos/requirejs/browser.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										69
									
								
								demos/requirejs/browser.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
 | 
			
		||||
<!-- vim: set ts=2: -->
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 | 
			
		||||
<title>SheetJS Live Demo</title>
 | 
			
		||||
<style>
 | 
			
		||||
#drop{
 | 
			
		||||
	border:2px dashed #bbb;
 | 
			
		||||
	-moz-border-radius:5px;
 | 
			
		||||
	-webkit-border-radius:5px;
 | 
			
		||||
	border-radius:5px;
 | 
			
		||||
	padding:25px;
 | 
			
		||||
	text-align:center;
 | 
			
		||||
	font:20pt bold,"Vollkorn";color:#bbb
 | 
			
		||||
}
 | 
			
		||||
#b64data{
 | 
			
		||||
	width:100%;
 | 
			
		||||
}
 | 
			
		||||
a { text-decoration: none }
 | 
			
		||||
</style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<pre>
 | 
			
		||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
 | 
			
		||||
(Base64 text works back to IE6; drag and drop works back to IE10)
 | 
			
		||||
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
 | 
			
		||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a>
 | 
			
		||||
Output Format: <select name="format" onchange="setfmt()">
 | 
			
		||||
<option value="csv" selected> CSV</option>
 | 
			
		||||
<option value="json"> JSON</option>
 | 
			
		||||
<option value="form"> FORMULAE</option>
 | 
			
		||||
<option value="html"> HTML</option>
 | 
			
		||||
</select><br />
 | 
			
		||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
 | 
			
		||||
<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
 | 
			
		||||
 | 
			
		||||
<textarea id="b64data">... or paste a base64-encoding here</textarea>
 | 
			
		||||
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
 | 
			
		||||
<b>Advanced Demo Options:</b>
 | 
			
		||||
Use Web Workers: (when available) <input type="checkbox" name="useworker" checked>
 | 
			
		||||
Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" checked>
 | 
			
		||||
</pre>
 | 
			
		||||
<pre id="out"></pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script>
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
	msg: 'xlsx',
 | 
			
		||||
	/* worker scripts */
 | 
			
		||||
	worker: './xlsxworker.js'
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script src="require.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
require.config({
 | 
			
		||||
	baseUrl: ".",
 | 
			
		||||
	name: "app",
 | 
			
		||||
	paths: {
 | 
			
		||||
		xlsx: "xlsx.full.min"
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
<script src="app.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@ -1,6 +1,9 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
({
 | 
			
		||||
	baseUrl: ".",
 | 
			
		||||
	name: "requirejs",
 | 
			
		||||
	out: "requirejs-built.js"
 | 
			
		||||
	name: "app",
 | 
			
		||||
	paths: {
 | 
			
		||||
		xlsx: "xlsx.full.min"
 | 
			
		||||
	},
 | 
			
		||||
	out: "app-built.js"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,6 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
 | 
			
		||||
<pre id="out"></pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="require.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
@ -55,6 +54,6 @@ var XW = {
 | 
			
		||||
	worker: './xlsxworker.js'
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script src="requirejs-built.js"></script>
 | 
			
		||||
<script src="app-built.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										5
									
								
								demos/requirejs/xlsx-shim.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								demos/requirejs/xlsx-shim.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
define(['xlsx'], function (_XLSX) {
 | 
			
		||||
	/* work around require.js */
 | 
			
		||||
	return XLSX;
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										2
									
								
								demos/rollup/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								demos/rollup/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,5 @@
 | 
			
		||||
rollup.js
 | 
			
		||||
rollup.min.js
 | 
			
		||||
rollup.node.js
 | 
			
		||||
worker.js
 | 
			
		||||
worker.min.js
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
TOOL=rollup
 | 
			
		||||
.PHONY: all
 | 
			
		||||
all: $(TOOL).min.js
 | 
			
		||||
all: $(TOOL).min.js worker.min.js
 | 
			
		||||
 | 
			
		||||
$(TOOL).min.js: $(TOOL).js
 | 
			
		||||
	uglifyjs $< > $@
 | 
			
		||||
@ -12,6 +12,10 @@ $(TOOL).js:
 | 
			
		||||
	node -e 'require("./rollup.node")'
 | 
			
		||||
	# browser
 | 
			
		||||
	rollup -c
 | 
			
		||||
	rollup -c rollup.config.worker.js
 | 
			
		||||
 | 
			
		||||
worker.min.js: worker.js
 | 
			
		||||
	uglifyjs $< > $@
 | 
			
		||||
 | 
			
		||||
.PHONY: init
 | 
			
		||||
init:
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,11 @@
 | 
			
		||||
 | 
			
		||||
This library presents itself as a CommonJS library, so some configuration is
 | 
			
		||||
required.  The examples at <https://rollupjs.org> can be followed pretty much in
 | 
			
		||||
verbatim.  This sample demonstrates a rollup for browser as well as for node.
 | 
			
		||||
verbatim.  This sample demonstrates a bundle for browser as well as for node.
 | 
			
		||||
 | 
			
		||||
This demo uses the `import` form to expose the whole library, enabling client
 | 
			
		||||
code to access the library with `import XLSX from 'xlsx'`.  The JS code from
 | 
			
		||||
the root demo was moved to a separate `app.js` script.
 | 
			
		||||
 | 
			
		||||
## Required Plugins
 | 
			
		||||
 | 
			
		||||
@ -24,3 +28,17 @@ export default {
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For the browser deployments, the output format is `'iife'`.  For node, the
 | 
			
		||||
output format is `'cjs'`.
 | 
			
		||||
 | 
			
		||||
### Worker Scripts
 | 
			
		||||
 | 
			
		||||
Rollup can also bundle worker scripts!  Instead of using `importScripts`, the
 | 
			
		||||
worker script should import the module:
 | 
			
		||||
 | 
			
		||||
```diff
 | 
			
		||||
-importScripts('dist/xlsx.full.min.js');
 | 
			
		||||
+import XLSX from 'xlsx';
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
/*jshint browser:true */
 | 
			
		||||
/*global XLSX */
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
import resolve from 'rollup-plugin-node-resolve';
 | 
			
		||||
import commonjs from 'rollup-plugin-commonjs';
 | 
			
		||||
export default {
 | 
			
		||||
	entry: 'main.js',
 | 
			
		||||
	entry: 'app.js',
 | 
			
		||||
	dest: 'rollup.js',
 | 
			
		||||
	plugins: [
 | 
			
		||||
		resolve({
 | 
			
		||||
@ -11,6 +11,5 @@ export default {
 | 
			
		||||
		}),
 | 
			
		||||
		commonjs()
 | 
			
		||||
	],
 | 
			
		||||
	moduleName: 'XLSX',
 | 
			
		||||
	format: 'iife'
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15
									
								
								demos/rollup/rollup.config.worker.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										15
									
								
								demos/rollup/rollup.config.worker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
import resolve from 'rollup-plugin-node-resolve';
 | 
			
		||||
import commonjs from 'rollup-plugin-commonjs';
 | 
			
		||||
export default {
 | 
			
		||||
	entry: 'xlsxworker.js',
 | 
			
		||||
	dest: 'worker.js',
 | 
			
		||||
	plugins: [
 | 
			
		||||
		resolve({
 | 
			
		||||
			module: false,
 | 
			
		||||
			browser: true,
 | 
			
		||||
		}),
 | 
			
		||||
		commonjs()
 | 
			
		||||
	],
 | 
			
		||||
	format: 'iife'
 | 
			
		||||
};
 | 
			
		||||
@ -46,15 +46,14 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
 | 
			
		||||
<pre id="out"></pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="rollup.min.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
	msg: 'xlsx',
 | 
			
		||||
	/* worker scripts */
 | 
			
		||||
	worker: './xlsxworker.js'
 | 
			
		||||
	worker: './worker.js'
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script src="app.js"></script>
 | 
			
		||||
<script src="rollup.min.js"></script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
importScripts('rollup.min.js');
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (oEvent) {
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(oEvent.data.d, {type: oEvent.data.b});
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								demos/server/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								demos/server/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
xlsx.full.min.js
 | 
			
		||||
@ -19,3 +19,8 @@ micro: init ## micro demo
 | 
			
		||||
.PHONY: koa
 | 
			
		||||
koa: init ## koa demo
 | 
			
		||||
	node koa.js
 | 
			
		||||
 | 
			
		||||
.PHONY: hapi
 | 
			
		||||
hapi: init ## hapi demo
 | 
			
		||||
	cp ../../dist/xlsx.full.min.js .
 | 
			
		||||
	node hapi.js
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,15 @@ request(url, {encoding: null}, function(err, res, data) {
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `readFile` / `writeFile` functions wrap `fs.{read,write}FileSync`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* equivalent to `var wb = XLSX.readFile("sheetjs.xlsx");` */
 | 
			
		||||
var buf = fs.readFileSync("sheetjs.xlsx");
 | 
			
		||||
var wb = XLSX.read(buf, {type:'buffer'});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Example servers
 | 
			
		||||
 | 
			
		||||
Each example server is expected to hold an array-of-arrays in memory.  They are
 | 
			
		||||
@ -82,11 +91,11 @@ 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
 | 
			
		||||
## command-line utility 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 npm module ships with the `xlsx` command line tool. For global installs, the
 | 
			
		||||
script `bin/xlsx.njs` is added to a directory in `PATH`. For local installs, the
 | 
			
		||||
appropriate script or symbolic link 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
 | 
			
		||||
@ -94,3 +103,26 @@ array of arrays to a CSV, the server writes the file, and the `xlsx` command is
 | 
			
		||||
used to generate files of different formats.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## tiny-worker with hapi
 | 
			
		||||
 | 
			
		||||
`tiny-worker` provides a Web Worker-like interface.  Binary strings and simple
 | 
			
		||||
objects are readily passed across the Worker divide.
 | 
			
		||||
 | 
			
		||||
The main server script is `hapi.js` and the worker script is `worker.js`.  State
 | 
			
		||||
is maintained in the server script.
 | 
			
		||||
 | 
			
		||||
Note: due to an issue with hapi payload parsing, the route `POST /file` is used
 | 
			
		||||
to handle the case of reading from file, so the cURL test is:
 | 
			
		||||
 | 
			
		||||
```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/file?f=sheetjs.xlsx
 | 
			
		||||
# write sheetjs.xlsb in the XLSB format
 | 
			
		||||
curl -X GET http://localhost:7262/?f=sheetjs.xlsb
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,36 +1,61 @@
 | 
			
		||||
/* 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 Worker = require('tiny-worker');
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
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 work = new Worker('worker.js');
 | 
			
		||||
	work.onmessage = function(e) {
 | 
			
		||||
		if(e.data.err) console.log(e.data.err);
 | 
			
		||||
		return res(e.data.data);
 | 
			
		||||
	};
 | 
			
		||||
	work.postMessage({action:"write", type:type, data:data});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function get_file(req, res, file) {
 | 
			
		||||
	var work = new Worker('worker.js');
 | 
			
		||||
	work.onmessage = function(e) {
 | 
			
		||||
		fs.writeFileSync(file, e.data.data, 'binary');
 | 
			
		||||
		return res("wrote to " + file + "\n");
 | 
			
		||||
	};
 | 
			
		||||
	work.postMessage({action:"write", file:file, data:data});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_file(req, res, file) {
 | 
			
		||||
	var work = new Worker('worker.js');
 | 
			
		||||
	work.onmessage = function(e) {
 | 
			
		||||
		data = e.data.data;
 | 
			
		||||
		return res("read from " + file + "\n");
 | 
			
		||||
	};
 | 
			
		||||
	work.postMessage({action:"read", file:file});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function post_data(req, res, type) {
 | 
			
		||||
	var keys = Object.keys(req.payload), k = keys[0];
 | 
			
		||||
	post_file(req, res, req.payload[k].path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var port = 7262;
 | 
			
		||||
server.connection({ host:'localhost', port: port});
 | 
			
		||||
 | 
			
		||||
server.route({ method: 'GET', path: '/', handler: function(req, res) {
 | 
			
		||||
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);
 | 
			
		||||
	if(req.query.t) get_data(req, res, req.query.t);
 | 
			
		||||
	else if(req.query.f) get_file(req, res, req.query.f);
 | 
			
		||||
	else res('Forbidden').code(403);
 | 
			
		||||
}});
 | 
			
		||||
server.route({ method: 'POST', path: '/', handler: function(req, res) {
 | 
			
		||||
server.route({ method: 'POST', path: '/',
 | 
			
		||||
config:{payload:{ output: 'file', parse: true, allow: 'multipart/form-data'}},
 | 
			
		||||
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.route({ method: 'POST', path: '/file',
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								demos/server/worker.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										22
									
								
								demos/server/worker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
var fs = require('fs');
 | 
			
		||||
 | 
			
		||||
onmessage = function(e) {
 | 
			
		||||
	try { switch(e.data.action) {
 | 
			
		||||
		case 'write':
 | 
			
		||||
			var ws = XLSX.utils.aoa_to_sheet(e.data.data);
 | 
			
		||||
			var wb = XLSX.utils.book_new();
 | 
			
		||||
			XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
 | 
			
		||||
			postMessage({data: XLSX.write(wb, {type:'binary', bookType:e.data.type || e.data.file.match(/\.([^\.]*)$/)[1]})});
 | 
			
		||||
			break;
 | 
			
		||||
		case 'read':
 | 
			
		||||
			var wb;
 | 
			
		||||
			if(e.data.file) wb = XLSX.readFile(e.data.file);
 | 
			
		||||
			else wb = XLSX.read(e.data.data);
 | 
			
		||||
			var ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
			postMessage({data: XLSX.utils.sheet_to_json(ws, {header:1})});
 | 
			
		||||
			break;
 | 
			
		||||
		default: throw "unknown action";
 | 
			
		||||
	}} catch(e) { postMessage({err:e.message || e}); }
 | 
			
		||||
};
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
.PHONY: test
 | 
			
		||||
test:
 | 
			
		||||
	cp ../../dist/xlsx.full.min.js .
 | 
			
		||||
	node systemjsnode.js
 | 
			
		||||
	node test.node.js
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,29 @@ var j = XLSX.utils.sheet_to_json(w.Sheets[w.SheetNames[0]], {header:1});
 | 
			
		||||
console.log(j);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The file functions `readFile` and `writeFile` are not available in the browser.
 | 
			
		||||
Note: The `readFile` and `writeFile` functions are not available in the browser.
 | 
			
		||||
 | 
			
		||||
## Web Workers
 | 
			
		||||
 | 
			
		||||
Web Workers can load the SystemJS library with `importScripts`, but the imported
 | 
			
		||||
code cannot assign the original worker's `onmessage` callback.  This demo works
 | 
			
		||||
around the limitation by exposing the desired function as a global:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* main worker script */
 | 
			
		||||
importScripts('system.js');
 | 
			
		||||
 | 
			
		||||
SystemJS.config({ /* ... browser config ... */ });
 | 
			
		||||
 | 
			
		||||
onmessage = function(evt) {
 | 
			
		||||
	SystemJS.import('xlsxworker.js').then(function() { _cb(evt); });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* xlsxworker.js */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
 | 
			
		||||
_cb = function (evt) { /* ... do work here ... */ };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Node
 | 
			
		||||
 | 
			
		||||
@ -64,3 +86,4 @@ SystemJS.import('xlsx').then(function(XLSX) {
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,154 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
/*jshint browser:true */
 | 
			
		||||
/*global XLSX */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
console.log(XLSX);
 | 
			
		||||
var w = XLSX.read('abc,def\nghi,jkl', {type:'binary'});
 | 
			
		||||
var j = XLSX.utils.sheet_to_json(w.Sheets[w.SheetNames[0]], {header:1});
 | 
			
		||||
console.log(j);
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
 | 
			
		||||
var process_wb = (function() {
 | 
			
		||||
	var OUT = document.getElementById('out');
 | 
			
		||||
	var HTMLOUT = document.getElementById('htmlout');
 | 
			
		||||
 | 
			
		||||
	var get_format = (function() {
 | 
			
		||||
		var radios = document.getElementsByName( "format" );
 | 
			
		||||
		return function() {
 | 
			
		||||
			for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
 | 
			
		||||
		};
 | 
			
		||||
	})();
 | 
			
		||||
 | 
			
		||||
	var to_json = function to_json(workbook) {
 | 
			
		||||
		var result = {};
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(roa.length) result[sheetName] = roa;
 | 
			
		||||
		});
 | 
			
		||||
		return JSON.stringify(result, 2, 2);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_csv = function to_csv(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(csv.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(csv);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_fmla = function to_fmla(workbook) {
 | 
			
		||||
		var result = [];
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
 | 
			
		||||
			if(formulae.length){
 | 
			
		||||
				result.push("SHEET: " + sheetName);
 | 
			
		||||
				result.push("");
 | 
			
		||||
				result.push(formulae.join("\n"));
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		return result.join("\n");
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	var to_html = function to_html(workbook) {
 | 
			
		||||
		HTMLOUT.innerHTML = "";
 | 
			
		||||
		workbook.SheetNames.forEach(function(sheetName) {
 | 
			
		||||
			var htmlstr = X.write(workbook, {sheet:sheetName, type:'binary', bookType:'html'});
 | 
			
		||||
			HTMLOUT.innerHTML += htmlstr;
 | 
			
		||||
		});
 | 
			
		||||
		return "";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function process_wb(wb) {
 | 
			
		||||
		global_wb = wb;
 | 
			
		||||
		var output = "";
 | 
			
		||||
		switch(get_format()) {
 | 
			
		||||
			case "form": output = to_fmla(wb); break;
 | 
			
		||||
			case "html": output = to_html(wb); break;
 | 
			
		||||
			case "json": output = to_json(wb); break;
 | 
			
		||||
			default: output = to_csv(wb);
 | 
			
		||||
		}
 | 
			
		||||
		if(OUT.innerText === undefined) OUT.textContent = output;
 | 
			
		||||
		else OUT.innerText = output;
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("output", new Date());
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
 | 
			
		||||
 | 
			
		||||
var b64it = window.b64it = (function() {
 | 
			
		||||
	var tarea = document.getElementById('b64data');
 | 
			
		||||
	return function b64it() {
 | 
			
		||||
		if(typeof console !== 'undefined') console.log("onload", new Date());
 | 
			
		||||
		var wb = X.read(tarea.value, {type:'base64', WTF:false});
 | 
			
		||||
		process_wb(wb);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
var do_file = (function() {
 | 
			
		||||
	var rABS = typeof FileReader !== "undefined" && (FileReader.prototype||{}).readAsBinaryString;
 | 
			
		||||
	var domrabs = document.getElementsByName("userabs")[0];
 | 
			
		||||
	if(!rABS) domrabs.disabled = !(domrabs.checked = false);
 | 
			
		||||
 | 
			
		||||
	var use_worker = typeof Worker !== 'undefined';
 | 
			
		||||
	var domwork = document.getElementsByName("useworker")[0];
 | 
			
		||||
	if(!use_worker) domwork.disabled = !(domwork.checked = false);
 | 
			
		||||
 | 
			
		||||
	var xw = function xw(data, cb) {
 | 
			
		||||
		var worker = new Worker(XW.worker);
 | 
			
		||||
		worker.onmessage = function(e) {
 | 
			
		||||
			switch(e.data.t) {
 | 
			
		||||
				case 'ready': break;
 | 
			
		||||
				case 'e': console.error(e.data.d); break;
 | 
			
		||||
				case XW.msg: cb(JSON.parse(e.data.d)); break;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		worker.postMessage({d:data,b:rABS?'binary':'array'});
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	return function do_file(files) {
 | 
			
		||||
		rABS = domrabs.checked;
 | 
			
		||||
		use_worker = domwork.checked;
 | 
			
		||||
		var f = files[0];
 | 
			
		||||
		var reader = new FileReader();
 | 
			
		||||
		reader.onload = function(e) {
 | 
			
		||||
			if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
 | 
			
		||||
			var data = e.target.result;
 | 
			
		||||
			if(!rABS) data = new Uint8Array(data);
 | 
			
		||||
			if(use_worker) xw(data, process_wb);
 | 
			
		||||
			else process_wb(X.read(data, {type: rABS ? 'binary' : 'array'}));
 | 
			
		||||
		};
 | 
			
		||||
		if(rABS) reader.readAsBinaryString(f);
 | 
			
		||||
		else reader.readAsArrayBuffer(f);
 | 
			
		||||
	};
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var drop = document.getElementById('drop');
 | 
			
		||||
	if(!drop.addEventListener) return;
 | 
			
		||||
 | 
			
		||||
	function handleDrop(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		do_file(e.dataTransfer.files);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function handleDragover(e) {
 | 
			
		||||
		e.stopPropagation();
 | 
			
		||||
		e.preventDefault();
 | 
			
		||||
		e.dataTransfer.dropEffect = 'copy';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drop.addEventListener('dragenter', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('dragover', handleDragover, false);
 | 
			
		||||
	drop.addEventListener('drop', handleDrop, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
	var xlf = document.getElementById('xlf');
 | 
			
		||||
	if(!xlf.addEventListener) return;
 | 
			
		||||
	function handleFile(e) { do_file(e.target.files); }
 | 
			
		||||
	xlf.addEventListener('change', handleFile, false);
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								demos/systemjs/main.simple.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										6
									
								
								demos/systemjs/main.simple.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
console.log(XLSX);
 | 
			
		||||
var w = XLSX.read('abc,def\nghi,jkl', {type:'binary'});
 | 
			
		||||
var j = XLSX.utils.sheet_to_json(w.Sheets[w.SheetNames[0]], {header:1});
 | 
			
		||||
console.log(j);
 | 
			
		||||
							
								
								
									
										18
									
								
								demos/systemjs/simple.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										18
									
								
								demos/systemjs/simple.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.16/system.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
	meta: {
 | 
			
		||||
		'xlsx': {
 | 
			
		||||
			exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	map: {
 | 
			
		||||
		'xlsx': 'xlsx.full.min.js', // <-- make sure xlsx.full.min.js is in same dir
 | 
			
		||||
		'fs': '',     // <--|
 | 
			
		||||
		'crypto': '', // <--| suppress native node modules
 | 
			
		||||
		'stream': ''  // <--|
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
SystemJS.import('main.simple.js');
 | 
			
		||||
</script>
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.16/system.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
	SystemJS.config({
 | 
			
		||||
		meta: {
 | 
			
		||||
			'xlsx': {
 | 
			
		||||
				exports: 'XLSX'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		map: {
 | 
			
		||||
			'xlsx': 'xlsx.full.min.js',
 | 
			
		||||
			'fs': '',
 | 
			
		||||
			'crypto': '',
 | 
			
		||||
			'stream': ''
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
  SystemJS.import('main.js');
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								demos/systemjs/worker.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								demos/systemjs/worker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
importScripts('https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.19/system.js');
 | 
			
		||||
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
	meta: {
 | 
			
		||||
		'xlsx': {
 | 
			
		||||
			exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	map: {
 | 
			
		||||
		'xlsx': 'xlsx.full.min.js', // <-- make sure xlsx.full.min.js is in same dir
 | 
			
		||||
		'fs': '',     // <--|
 | 
			
		||||
		'crypto': '', // <--| suppress native node modules
 | 
			
		||||
		'stream': ''  // <--|
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onmessage = function(evt) {
 | 
			
		||||
	/* the real action is in the _cb function from xlsxworker.js */
 | 
			
		||||
	SystemJS.import('xlsxworker.js').then(function() { _cb(evt); });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										12
									
								
								demos/systemjs/xlsxworker.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										12
									
								
								demos/systemjs/xlsxworker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
/* expose a global that can be accessed from the worker script */
 | 
			
		||||
_cb = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
@ -1,36 +1,85 @@
 | 
			
		||||
# VueJS 2
 | 
			
		||||
 | 
			
		||||
The `xlsx.core.min.js` and `xlsx.full.min.js` scripts are designed to be dropped
 | 
			
		||||
into web pages with script tags e.g.
 | 
			
		||||
into web pages with script tags:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<script src="xlsx.full.min.js"></script>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Strictly speaking, there should be no need for a Vue.JS demo!  You can proceed
 | 
			
		||||
as you would with any other browser-friendly library.
 | 
			
		||||
The library can also be imported directly from single-file components with:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
import XLSX from 'xlsx';
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
a pre-generated 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
 | 
			
		||||
## Internal State
 | 
			
		||||
 | 
			
		||||
For Single File Components, a simple `import XLSX from 'xlsx'` should suffice.
 | 
			
		||||
The webpack demo includes a sample `webpack.config.js`.
 | 
			
		||||
The plain JS demo embeds state in the DOM.  Other demos use proper 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 ]
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`sheet_to_json` and `aoa_to_sheet` utility functions can convert between arrays
 | 
			
		||||
of arrays and worksheets:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* convert from workbook to array of arrays */
 | 
			
		||||
var first_worksheet = workbook.Sheets[workbook.SheetNames[0]];
 | 
			
		||||
var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1});
 | 
			
		||||
 | 
			
		||||
/* convert from array of arrays to workbook */
 | 
			
		||||
var worksheet = XLSX.utils.aoa_to_sheet(data);
 | 
			
		||||
var new_workbook = XLSX.utils.book_new();
 | 
			
		||||
XLSX.utils.book_append_sheet(new_workbook, worksheet, "SheetJS");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The column objects can be generated with the `encode_col` utility function:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
function make_cols(refstr/*:string*/) {
 | 
			
		||||
  var o = [];
 | 
			
		||||
  var range = XLSX.utils.decode_range(refstr);
 | 
			
		||||
  for(var i = 0; i <= range.e.c; ++i) {
 | 
			
		||||
    o.push({name: XLSX.utils.encode_col(i), key:i});
 | 
			
		||||
  }
 | 
			
		||||
  return o;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## WeeX
 | 
			
		||||
 | 
			
		||||
<img src="screen.png" width="400px"/>
 | 
			
		||||
 | 
			
		||||
Reproducing the full project is a little bit tricky.  The included `weex.sh`
 | 
			
		||||
script performs the necessary installation steps.
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
Using NodeJS it is straightforward to convert to/from Base64:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* convert sheetjs.xlsx -> sheetjs.xlsx.b64 */
 | 
			
		||||
@ -42,24 +91,9 @@ var str = fs.readFileSync("sheetjs.xls.b64").toString();
 | 
			
		||||
fs.writeFileSync("sheetjs.xls", new Buffer(str, "base64"));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Nuxt and State
 | 
			
		||||
## Other Demos
 | 
			
		||||
 | 
			
		||||
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 ]
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
#### Server-Rendered VueJS Components with Nuxt.js
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
@ -69,3 +103,5 @@ const _XLSX = require('xlsx');
 | 
			
		||||
const X = typeof XLSX !== 'undefined' ? XLSX : _XLSX;
 | 
			
		||||
/* use the variable X rather than XLSX in the component */
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -29,8 +29,6 @@ function s2ab(s) {
 | 
			
		||||
Vue.component('html-preview', {
 | 
			
		||||
	template: SJSTemplate,
 | 
			
		||||
	methods: {
 | 
			
		||||
		// as per: https://github.com/SheetJS/js-xlsx/wiki/Reading-XLSX-from-FileReader.readAsArrayBuffer()
 | 
			
		||||
		// changing the readAsBinaryString (deprecated) to readAsArrayBuffer()
 | 
			
		||||
		onchange: function(evt) {
 | 
			
		||||
			var file;
 | 
			
		||||
			var files = evt.target.files;
 | 
			
		||||
@ -38,7 +36,7 @@ Vue.component('html-preview', {
 | 
			
		||||
			if (!files || files.length == 0) return;
 | 
			
		||||
 | 
			
		||||
			file = files[0];
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			var reader = new FileReader();
 | 
			
		||||
			reader.onload = function (e) {
 | 
			
		||||
				// pre-process data
 | 
			
		||||
@ -48,7 +46,7 @@ Vue.component('html-preview', {
 | 
			
		||||
				for (var i = 0; i < length; i++) {
 | 
			
		||||
					binary += String.fromCharCode(bytes[i]);
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
 | 
			
		||||
				/* read workbook */
 | 
			
		||||
				var wb = XLSX.read(binary, {type: 'binary'});
 | 
			
		||||
 | 
			
		||||
@ -57,7 +55,7 @@ Vue.component('html-preview', {
 | 
			
		||||
				var ws = wb.Sheets[wsname];
 | 
			
		||||
 | 
			
		||||
				/* generate HTML */
 | 
			
		||||
				var HTML = XLSX.utils.sheet_to_html(ws); 
 | 
			
		||||
				var HTML = XLSX.utils.sheet_to_html(ws);
 | 
			
		||||
 | 
			
		||||
				/* update table */
 | 
			
		||||
				document.getElementById('out-table').innerHTML = HTML;
 | 
			
		||||
 | 
			
		||||
@ -9,9 +9,9 @@
 | 
			
		||||
		<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">
 | 
			
		||||
			<div class="row" v-for="(row, ridx) in data" :key="ridx">
 | 
			
		||||
				<text>ROW {{ridx + 1}}</text>
 | 
			
		||||
				<text v-for="(cell, cidx) in row">CELL {{get_label(ridx, cidx)}}:{{cell}}</text>
 | 
			
		||||
				<text v-for="(cell, cidx) in row" :key="cidx">CELL {{get_label(ridx, cidx)}}:{{cell}}</text>
 | 
			
		||||
			</div>
 | 
			
		||||
		</scroller>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
<!-- 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">
 | 
			
		||||
@ -16,11 +16,13 @@
 | 
			
		||||
		<div class="table-responsive">
 | 
			
		||||
			<table class="table table-striped">
 | 
			
		||||
				<thead><tr>
 | 
			
		||||
					<th v-for="c in cols">{{c.name}}</th>
 | 
			
		||||
					<th v-for="c in cols" :key="c.key">{{c.name}}</th>
 | 
			
		||||
				</tr></thead>
 | 
			
		||||
				<tbody><tr v-for="r in data">
 | 
			
		||||
					<td v-for="c in cols"> {{ r[c.key] }}</td>
 | 
			
		||||
				</tr></tbody>
 | 
			
		||||
				<tbody>
 | 
			
		||||
					<tr v-for="(r, key) in data" :key="key">
 | 
			
		||||
						<td v-for="c in cols" :key="c.key"> {{ r[c.key] }}</td>
 | 
			
		||||
					</tr>
 | 
			
		||||
				</tbody>
 | 
			
		||||
			</table>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div></div>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								demos/vue/screen.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								demos/vue/screen.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 97 KiB  | 
@ -5,9 +5,9 @@ if [ ! -e SheetJS ]; then
 | 
			
		||||
	cd SheetJS
 | 
			
		||||
	npm install
 | 
			
		||||
	weexpack platform add ios
 | 
			
		||||
	sed -i 's/ATSDK-Weex/ATSDK/g' platforms/ios/Podfile
 | 
			
		||||
	# see https://github.com/weexteam/weex-pack/issues/133#issuecomment-295806132
 | 
			
		||||
	sed -i.bak '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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								demos/webpack/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								demos/webpack/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,3 @@
 | 
			
		||||
webpack.js
 | 
			
		||||
webpack.min.js
 | 
			
		||||
main.js
 | 
			
		||||
main.min.js
 | 
			
		||||
*.out.js
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,15 @@
 | 
			
		||||
TOOL=webpack
 | 
			
		||||
WPOPTS=--display-modules --display-reasons --profile
 | 
			
		||||
.PHONY: all
 | 
			
		||||
all: $(TOOL).min.js core.out.js full.out.js
 | 
			
		||||
all: main.min.js core.out.js full.out.js app.out.js
 | 
			
		||||
 | 
			
		||||
$(TOOL).min.js: $(TOOL).js
 | 
			
		||||
main.min.js: main.out.js
 | 
			
		||||
	uglifyjs $< > $@
 | 
			
		||||
 | 
			
		||||
.PHONY: $(TOOL).js
 | 
			
		||||
$(TOOL).js:
 | 
			
		||||
	webpack main.js --output-filename $@ $(WPOPTS)
 | 
			
		||||
 | 
			
		||||
.PHONY: core.out.js full.out.js
 | 
			
		||||
core.out.js full.out.js: %.out.js: %.js
 | 
			
		||||
.PHONY: main.out.js core.out.js full.out.js
 | 
			
		||||
main.out.js core.out.js full.out.js: %.out.js: %.js
 | 
			
		||||
	webpack $< --output-filename $@ $(WPOPTS)
 | 
			
		||||
 | 
			
		||||
.PHONY: app.out.js
 | 
			
		||||
app.out.js: webpack.app.js app.js appworker.js
 | 
			
		||||
	webpack --config $< $(WPOPTS)
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,30 @@ This library is built with some dynamic logic to determine if it is invoked in a
 | 
			
		||||
script tag or in nodejs.  Webpack does not understand those feature tests, so by
 | 
			
		||||
default it will do some strange things.
 | 
			
		||||
 | 
			
		||||
## Basic Usage
 | 
			
		||||
 | 
			
		||||
`webpack.app.js` demonstrates bundling an entire app script in a bundle.  For
 | 
			
		||||
basic projects requiring the module from the npm package, it is sufficient to
 | 
			
		||||
suppress the node shims:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* webpack config for app.out.js */
 | 
			
		||||
{
 | 
			
		||||
	/* entry point app.js */
 | 
			
		||||
	entry: './app.js',
 | 
			
		||||
 | 
			
		||||
	/* write to app.out.js */
 | 
			
		||||
	output: { path:__dirname, filename: './app.out.js' },
 | 
			
		||||
 | 
			
		||||
	/* suppress node shims */
 | 
			
		||||
	node: {
 | 
			
		||||
		fs: false,
 | 
			
		||||
		process: false,
 | 
			
		||||
		Buffer: false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Suppressing the Node shims
 | 
			
		||||
 | 
			
		||||
The library properly guards against accidental leakage of node features in the
 | 
			
		||||
@ -17,18 +41,6 @@ browser but webpack disregards those.  The config should explicitly suppress:
 | 
			
		||||
	}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Exporting the XLSX variable
 | 
			
		||||
 | 
			
		||||
This library will not assign to module.exports if it is run in the browser.  To
 | 
			
		||||
convince webpack, set `output` in the webpack config:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
	output: {
 | 
			
		||||
		libraryTarget: 'var',
 | 
			
		||||
		library: 'XLSX'
 | 
			
		||||
	}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Omitting optional dependencies
 | 
			
		||||
 | 
			
		||||
The `codepage` is needed in certain special cases, including files generated by
 | 
			
		||||
@ -41,6 +53,8 @@ the module can be omitted by aliasing the dependency:
 | 
			
		||||
	},
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Alternatively, bundling the `xlsx.core.min.js` script always omits dependencies.
 | 
			
		||||
 | 
			
		||||
## Bower and minified versions
 | 
			
		||||
 | 
			
		||||
Webpack may show a message like "This seems to be a pre-built javascript file"
 | 
			
		||||
@ -55,3 +69,44 @@ harmless.  To suppress the message, set `module.noParse` in the webpack config:
 | 
			
		||||
		]
 | 
			
		||||
	}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Other Demos
 | 
			
		||||
 | 
			
		||||
This demo also attempts to demonstrate bundling of the library as well as the
 | 
			
		||||
core and full distribution versions.  `app.js` is the common app code (it will
 | 
			
		||||
not be bundled).  The individual bundles merely wrap and reflect `XLSX`.  The
 | 
			
		||||
app code uses the bundles with script tag inclusion in the main HTML files. The
 | 
			
		||||
worker scripts use the bundles with `importScripts` references.
 | 
			
		||||
 | 
			
		||||
| required script |   HTML page |     entry |   worker script |
 | 
			
		||||
|----------------:|------------:|----------:|----------------:|
 | 
			
		||||
| main `xlsx` lib | `main.html` | `main.js` | `mainworker.js` |
 | 
			
		||||
| `xlsx.core.min` | `core.html` | `core.js` | `coreworker.js` |
 | 
			
		||||
| `xlsx.full.min` | `full.html` | `full.js` | `fullworker.js` |
 | 
			
		||||
 | 
			
		||||
The entry points in the demo merely require and re-export the library:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* main.js */
 | 
			
		||||
var XLSX = require('../../');
 | 
			
		||||
console.log("it works!");
 | 
			
		||||
module.exports = XLSX;
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The main advantage of reflecting the library is deduplication: the library code
 | 
			
		||||
is only downloaded once.  The basic example builds a separate worker script and
 | 
			
		||||
eventually ships the library twice.
 | 
			
		||||
 | 
			
		||||
### Reflecting the XLSX variable
 | 
			
		||||
 | 
			
		||||
This library will not assign to `module.exports` if it is run in the browser. To
 | 
			
		||||
convince webpack, the demo webpack config sets `output`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
	output: {
 | 
			
		||||
		libraryTarget: 'var',
 | 
			
		||||
		library: 'XLSX'
 | 
			
		||||
	}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
/*jshint browser:true */
 | 
			
		||||
/*global XLSX */
 | 
			
		||||
var X = XLSX;
 | 
			
		||||
var X = typeof require !== "undefined" && require('../../') || XLSX;
 | 
			
		||||
 | 
			
		||||
var global_wb;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
importScripts('webpack.min.js');
 | 
			
		||||
var XLSX = require('../../');
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (oEvent) {
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(oEvent.data.d, {type: oEvent.data.b});
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
@ -2,10 +2,10 @@
 | 
			
		||||
importScripts('core.out.js');
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (oEvent) {
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(oEvent.data.d, {type: oEvent.data.b});
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,10 @@
 | 
			
		||||
importScripts('full.out.js');
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (oEvent) {
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(oEvent.data.d, {type: oEvent.data.b});
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -46,13 +46,13 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
 | 
			
		||||
<pre id="out"></pre>
 | 
			
		||||
<div id="htmlout"></div>
 | 
			
		||||
<br />
 | 
			
		||||
<script src="webpack.min.js"></script>
 | 
			
		||||
<script src="main.min.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
var XW = {
 | 
			
		||||
	/* worker message */
 | 
			
		||||
	msg: 'xlsx',
 | 
			
		||||
	/* worker scripts */
 | 
			
		||||
	worker: './xlsxworker.js'
 | 
			
		||||
	worker: './mainworker.js'
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script src="app.js"></script>
 | 
			
		||||
							
								
								
									
										11
									
								
								demos/webpack/mainworker.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										11
									
								
								demos/webpack/mainworker.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
 | 
			
		||||
importScripts('main.min.js');
 | 
			
		||||
postMessage({t:"ready"});
 | 
			
		||||
 | 
			
		||||
onmessage = function (evt) {
 | 
			
		||||
  var v;
 | 
			
		||||
  try {
 | 
			
		||||
    v = XLSX.read(evt.data.d, {type: evt.data.b});
 | 
			
		||||
postMessage({t:"xlsx", d:JSON.stringify(v)});
 | 
			
		||||
  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										26
									
								
								demos/webpack/webpack.app.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										26
									
								
								demos/webpack/webpack.app.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
var commonops = {
 | 
			
		||||
	/* suppress node shims */
 | 
			
		||||
	node: {
 | 
			
		||||
		fs: false,
 | 
			
		||||
		process: false,
 | 
			
		||||
		Buffer: false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* app.out.js */
 | 
			
		||||
var app_config = Object.assign({
 | 
			
		||||
	entry: './app.js',
 | 
			
		||||
	output: { path:__dirname, filename: './app.out.js' }
 | 
			
		||||
}, commonops);
 | 
			
		||||
 | 
			
		||||
/* appworker.out.js */
 | 
			
		||||
var appworker_config = Object.assign({
 | 
			
		||||
	entry: './appworker.js',
 | 
			
		||||
	output: { path:__dirname, filename: './appworker.out.js' }
 | 
			
		||||
}, commonops);
 | 
			
		||||
 | 
			
		||||
module.exports = [
 | 
			
		||||
	app_config,
 | 
			
		||||
	appworker_config
 | 
			
		||||
]
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
 | 
			
		||||
module.exports = {
 | 
			
		||||
	/* ensure that the XLSX variable is exported */
 | 
			
		||||
	output: {
 | 
			
		||||
		libraryTarget: 'var',
 | 
			
		||||
		library: 'XLSX'
 | 
			
		||||
@ -17,6 +18,7 @@ module.exports = {
 | 
			
		||||
		alias: { "./dist/cpexcel.js": "" }
 | 
			
		||||
	},
 | 
			
		||||
	*/
 | 
			
		||||
	/* suppress node shims */
 | 
			
		||||
	node: {
 | 
			
		||||
		fs: false,
 | 
			
		||||
		process: false,
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,20 @@ web browser clients and web servers.  Since this library works in web browsers,
 | 
			
		||||
server conversion work can be offloaded to the client!  This demo shows a few
 | 
			
		||||
common scenarios involving browser APIs and popular wrapper libraries.
 | 
			
		||||
 | 
			
		||||
## Sample Server
 | 
			
		||||
## Demos
 | 
			
		||||
 | 
			
		||||
The included demos focus on an editable table.  There are two separate flows:
 | 
			
		||||
 | 
			
		||||
- When the page is accessed, the browser will attempt to download `sheetjs.xlsx`
 | 
			
		||||
  and read the workbook.  The old table will be replaced with an editable table
 | 
			
		||||
  whose contents match the first worksheet.  The table is generated using the
 | 
			
		||||
  `sheet_to_html` utility with `editable:true` option
 | 
			
		||||
 | 
			
		||||
- When the upload button is clicked, the browser will generate a new worksheet
 | 
			
		||||
  using `table_to_book` and build up a new workbook.  It will then attempt to
 | 
			
		||||
  generate a Base64-encoded XLSX string and upload it to the server.
 | 
			
		||||
 | 
			
		||||
### Demo Server
 | 
			
		||||
 | 
			
		||||
The `server.js` nodejs server serves static files on `GET` request.  On a `POST`
 | 
			
		||||
request to `/upload`, the server processes the body and looks for the `file` and
 | 
			
		||||
@ -14,6 +27,7 @@ name specified in `file`.
 | 
			
		||||
 | 
			
		||||
To start the demo, run `npm start` and navigate to <http://localhost:7262/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## XMLHttpRequest
 | 
			
		||||
 | 
			
		||||
For downloading data, the `arraybuffer` response type generates an `ArrayBuffer`
 | 
			
		||||
@ -26,10 +40,10 @@ 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 */
 | 
			
		||||
  /* parse the data when it is received */
 | 
			
		||||
  var data = new Uint8Array(req.response);
 | 
			
		||||
  var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
  /* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
};
 | 
			
		||||
req.send();
 | 
			
		||||
```
 | 
			
		||||
@ -48,31 +62,57 @@ fd.append('data', b64);
 | 
			
		||||
/* send data */
 | 
			
		||||
var req = new XMLHttpRequest();
 | 
			
		||||
req.open("POST", "/upload", true);
 | 
			
		||||
req.send(formdata);
 | 
			
		||||
req.send(fd);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
axios and superagent patterns are similar to the XMLHttpRequest pattern but
 | 
			
		||||
involve much less boilerplate:
 | 
			
		||||
### superagent Wrapper Library
 | 
			
		||||
 | 
			
		||||
The `superagent` library usage mirrors XHR:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* 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 */
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The upload portion only differs in the actual request command:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* send data (fd is the FormData object) */
 | 
			
		||||
superagent.post("/upload").send(fd);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### superagent Wrapper Library
 | 
			
		||||
 | 
			
		||||
The `axios` library presents a Promise interface.  The axios demo uses a single
 | 
			
		||||
promise, but for production deployments it may make sense to separate parsing:
 | 
			
		||||
 | 
			
		||||
```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 */
 | 
			
		||||
axios(url, {responseType:'arraybuffer'}).catch(function(err) {
 | 
			
		||||
  /* error in getting data */
 | 
			
		||||
}).then(function(res) {
 | 
			
		||||
  /* parse the data when it is received */
 | 
			
		||||
  var data = new Uint8Array(res.data);
 | 
			
		||||
  var workbook = XLSX.read(data, {type:"array"});
 | 
			
		||||
  return workbook;
 | 
			
		||||
}).catch(function(err) {
 | 
			
		||||
  /* error in parsing */
 | 
			
		||||
}).then(function(workbook) {
 | 
			
		||||
  /* 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 */
 | 
			
		||||
});
 | 
			
		||||
The upload portion only differs in the actual request command:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* send data (fd is the FormData object) */
 | 
			
		||||
axios("/upload", {method: "POST", data: fd});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## fetch
 | 
			
		||||
@ -82,20 +122,29 @@ 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();
 | 
			
		||||
  /* get the data as a Blob */
 | 
			
		||||
  if(!res.ok) throw new Error("fetch failed");
 | 
			
		||||
  return res.blob();
 | 
			
		||||
}).catch(function(err) {
 | 
			
		||||
  /* error in getting data */
 | 
			
		||||
}).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"});
 | 
			
		||||
  /* 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);
 | 
			
		||||
    /* DO SOMETHING WITH workbook HERE */
 | 
			
		||||
  });
 | 
			
		||||
  reader.readAsArrayBuffer(blob);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The upload code is identical to `axios`, except for the variable name:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
fetch("/upload", {method: "POST", body: fd});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
@ -46,10 +46,10 @@ axios(url, {responseType:'arraybuffer'}).then(function(res) {
 | 
			
		||||
document.getElementById('ulbutton').onclick = function() {
 | 
			
		||||
	var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
 | 
			
		||||
	console.log(wb);
 | 
			
		||||
	var formdata = new FormData();
 | 
			
		||||
	formdata.append('file', demo + '.' + book);
 | 
			
		||||
	formdata.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	axios("/upload", {method: "POST", data: formdata});
 | 
			
		||||
	var fd = new FormData();
 | 
			
		||||
	fd.append('file', demo + '.' + book);
 | 
			
		||||
	fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	axios("/upload", {method: "POST", data: fd});
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
@ -55,10 +55,10 @@ fetch(url).then(function(res) {
 | 
			
		||||
document.getElementById('ulbutton').onclick = function() {
 | 
			
		||||
	var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
 | 
			
		||||
	console.log(wb);
 | 
			
		||||
	var formdata = new FormData();
 | 
			
		||||
	formdata.append('file', demo + '.' + book);
 | 
			
		||||
	formdata.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	fetch("/upload", {method: "POST", body: formdata}).then(function(r) { return r.text(); }).then(function(t) { console.log(t); }); 
 | 
			
		||||
	var fd = new FormData();
 | 
			
		||||
	fd.append('file', demo + '.' + book);
 | 
			
		||||
	fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	fetch("/upload", {method: "POST", body: fd}).then(function(r) { return r.text(); }).then(function(t) { console.log(t); });
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,6 @@ a { text-decoration: none }
 | 
			
		||||
<script>
 | 
			
		||||
var demo = 'superagent', book = 'xlsx';
 | 
			
		||||
 | 
			
		||||
var request = window.superagent;
 | 
			
		||||
function process_wb(wb) {
 | 
			
		||||
	console.log(wb);
 | 
			
		||||
	htmlout.innerHTML = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]], {editable:true}).replace("<table", '<table id="table" border="1"');
 | 
			
		||||
@ -38,7 +37,7 @@ var url = "sheetjs.xlsx";
 | 
			
		||||
document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download original file</a>';
 | 
			
		||||
document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>';
 | 
			
		||||
 | 
			
		||||
request.get(url)
 | 
			
		||||
superagent.get(url)
 | 
			
		||||
	.responseType('arraybuffer')
 | 
			
		||||
	.end(function(err, res) {
 | 
			
		||||
		var data = new Uint8Array(res.body);
 | 
			
		||||
@ -49,10 +48,10 @@ request.get(url)
 | 
			
		||||
document.getElementById('ulbutton').onclick = function() {
 | 
			
		||||
	var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
 | 
			
		||||
	console.log(wb);
 | 
			
		||||
	var formdata = new FormData();
 | 
			
		||||
	formdata.append('file', demo + '.' + book);
 | 
			
		||||
	formdata.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	request.post("/upload").send(formdata).end(function(e,r) { console.log(r.text); });
 | 
			
		||||
	var fd = new FormData();
 | 
			
		||||
	fd.append('file', demo + '.' + book);
 | 
			
		||||
	fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	superagent.post("/upload").send(fd).end(function(e,r) { console.log(r.text); });
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
@ -40,26 +40,26 @@ document.getElementById('fileurl').innerHTML = '<a href="' + url + '">Download o
 | 
			
		||||
document.getElementById('outfile').innerHTML = '<a href="' + demo + '.' + book + '">Download new file</a>';
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
	var oReq = new XMLHttpRequest();
 | 
			
		||||
	oReq.open("GET", url, true);
 | 
			
		||||
	oReq.responseType = "arraybuffer";
 | 
			
		||||
	oReq.onload = function(e) {
 | 
			
		||||
		var data = new Uint8Array(oReq.response);
 | 
			
		||||
	var req = new XMLHttpRequest();
 | 
			
		||||
	req.open("GET", url, true);
 | 
			
		||||
	req.responseType = "arraybuffer";
 | 
			
		||||
	req.onload = function(e) {
 | 
			
		||||
		var data = new Uint8Array(req.response);
 | 
			
		||||
		var wb = XLSX.read(data, {type:"array"});
 | 
			
		||||
		process_wb(wb);
 | 
			
		||||
	};
 | 
			
		||||
	oReq.send();
 | 
			
		||||
	req.send();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.getElementById('ulbutton').onclick = function() {
 | 
			
		||||
	var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
 | 
			
		||||
	console.log(wb);
 | 
			
		||||
	var formdata = new FormData();
 | 
			
		||||
	formdata.append('file', demo + '.' + book);
 | 
			
		||||
	formdata.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	var oReq = new XMLHttpRequest();
 | 
			
		||||
	oReq.open("POST", "/upload", true);
 | 
			
		||||
	oReq.send(formdata);
 | 
			
		||||
	var fd = new FormData();
 | 
			
		||||
	fd.append('file', demo + '.' + book);
 | 
			
		||||
	fd.append('data', XLSX.write(wb, {bookType:book, type:'base64'}));
 | 
			
		||||
	var req = new XMLHttpRequest();
 | 
			
		||||
	req.open("POST", "/upload", true);
 | 
			
		||||
	req.send(fd);
 | 
			
		||||
};
 | 
			
		||||
</script>
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,7 @@ enhancements, additional features by request, and dedicated support.
 | 
			
		||||
[**File format support for known spreadsheet data formats:**](#file-formats)
 | 
			
		||||
 | 
			
		||||
<details>
 | 
			
		||||
	<summary><b>Graph of supported formats</b> (click to show)</summary>
 | 
			
		||||
  <summary><b>Graph of supported formats</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ enhancements, additional features by request, and dedicated support.
 | 
			
		||||
[](https://semaphoreci.com/sheetjs/js-xlsx)
 | 
			
		||||
[](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
 | 
			
		||||
[](https://david-dm.org/sheetjs/js-xlsx)
 | 
			
		||||
[](https://npmjs.org/package/xlsx)
 | 
			
		||||
[](https://npmjs.org/package/xlsx)
 | 
			
		||||
[](https://ghit.me/repo/sheetjs/js-xlsx)
 | 
			
		||||
[](https://github.com/SheetJS/js-xlsx)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user