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/)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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);
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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': '' // <--|
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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);
|
||||
```
|
||||
|
||||
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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"] });
|
||||
};
|
||||
})();
|
||||
|