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/)
|
||||
|
||||
[![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"] });
|
||||
};
|
||||
})();
|
||||
|
@ -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.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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));
|
||||
});
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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>
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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';
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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) {
|
||||
});
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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 */
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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'
|
||||
}
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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});
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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>
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
@ -42,7 +42,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
|
||||
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
|
||||
[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
[![npm Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](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