forked from sheetjs/sheetjs
precise time parse (h/t @ragearino @MyAddonsDev )
This commit is contained in:
parent
c02eb14255
commit
fdbbf2d6bf
@ -159,22 +159,22 @@ function fuzzynum(s/*:string*/)/*:number*/ {
|
||||
}
|
||||
|
||||
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))([ap])m?/;
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
||||
|
||||
function fuzzytime1(M) /*:Date*/ {
|
||||
/* TODO: 1904 adjustment */
|
||||
if(!M[2]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
/* TODO: 1904 adjustment, keep in sync with base date */
|
||||
if(!M[2]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
if(M[3]) {
|
||||
if(M[4]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1900,0,0,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
if(M[4]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1899,11,30,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
}
|
||||
else if(M[5]) return new Date(1900, 0, 0, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
else if(M[5]) return new Date(1899,11,30, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
}
|
||||
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
||||
function fuzzydate(s/*:string*/)/*:Date*/ {
|
||||
var lower = s.toLowerCase();
|
||||
var lnos = lower.replace(/\s+/g, "");
|
||||
var lnos = lower.replace(/\s+/g, " ").trim();
|
||||
var M = lnos.match(FDRE1);
|
||||
if(M) return fuzzytime1(M);
|
||||
|
||||
|
@ -960,12 +960,12 @@ var PRN = /*#__PURE__*/(function() {
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
|
||||
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
||||
cell.z = o.dateNF || table_fmt[14];
|
||||
var k = 0;
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s, k); }
|
||||
else { cell.t = 'n'; cell.v = datenum(parseDate(s, k)); }
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; v = parseDate(s, k); }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
||||
else { cell.t = 'n'; cell.v = datenum(v); }
|
||||
if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
||||
if(!o.cellNF) delete cell.z;
|
||||
} else {
|
||||
|
@ -18,7 +18,7 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
### Included Demos
|
||||
|
||||
**JavaScript APIs**
|
||||
- [`XMLHttpRequest and fetch`](xhr/)
|
||||
- [`XMLHttpRequest and fetch`](https://docs.sheetjs.com/docs/getting-started/demos/network)
|
||||
- [`Clipboard Data`](https://docs.sheetjs.com/docs/getting-started/demos/clipboard)
|
||||
- [`Typed Arrays for Machine Learning`](https://docs.sheetjs.com/docs/getting-started/demos/ml)
|
||||
- [`LocalStorage and SessionStorage`](https://docs.sheetjs.com/docs/getting-started/demos/database#localstorage-and-sessionstorage)
|
||||
@ -29,7 +29,6 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
- [`Angular.JS`](https://docs.sheetjs.com/docs/getting-started/demos/legacy#angularjs)
|
||||
- [`Angular 2+ and Ionic`](angular2/)
|
||||
- [`Knockout`](https://docs.sheetjs.com/docs/getting-started/demos/legacy#knockoutjs)
|
||||
- [`Meteor`](meteor/)
|
||||
- [`React, React Native and NextJS`](react/)
|
||||
- [`VueJS, WeeX and NuxtJS`](vue/)
|
||||
|
||||
@ -43,8 +42,7 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
**Platforms and Integrations**
|
||||
- [`Command-Line Tools`](https://docs.sheetjs.com/docs/getting-started/demos/cli)
|
||||
- [`NodeJS Server-Side Processing`](server/)
|
||||
- [`Deno`](deno/)
|
||||
- [`Electron`](electron/)
|
||||
- [`Electron`](https://docs.sheetjs.com/docs/getting-started/demos/desktop#electron)
|
||||
- [`NW.js`](https://docs.sheetjs.com/docs/getting-started/demos/desktop#nwjs)
|
||||
- [`Chrome / Chromium Extension`](https://docs.sheetjs.com/docs/getting-started/demos/chromium)
|
||||
- [`Google Sheets API`](https://docs.sheetjs.com/docs/getting-started/demos/gsheet)
|
||||
@ -68,7 +66,7 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
- [`rollup`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#rollup)
|
||||
- [`snowpack`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#snowpack)
|
||||
- [`swc`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#swc)
|
||||
- [`systemjs`](systemjs/)
|
||||
- [`systemjs`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#systemjs)
|
||||
- [`vite`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#vite)
|
||||
- [`webpack 2.x`](webpack/)
|
||||
- [`wmr`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#wmr)
|
||||
|
@ -1,15 +0,0 @@
|
||||
.PHONY: init
|
||||
init:
|
||||
mkdir -p node_modules
|
||||
cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx ; fi; cd -
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
eslint *.js
|
||||
.PHONY: run
|
||||
run:
|
||||
npm i
|
||||
npx electron .
|
||||
.PHONY: build
|
||||
build:
|
||||
npm run make
|
@ -1,56 +1,6 @@
|
||||
# Electron
|
||||
|
||||
This library is compatible with Electron and should just work out of the box.
|
||||
The demonstration uses Electron 18.2.0. The library is added via `require` from
|
||||
the renderer process.
|
||||
|
||||
The library can also be required from the main process, as shown in this demo
|
||||
to render a version string in the About dialog on OSX.
|
||||
|
||||
The standard HTML5 `FileReader` techniques from the browser apply to Electron.
|
||||
This demo includes a drag-and-drop box as well as a file input box, mirroring
|
||||
the [SheetJS Data Preview Live Demo](http://oss.sheetjs.com/sheetjs/)
|
||||
|
||||
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`.
|
||||
|
||||
The demo project is structured for `electron-forge`:
|
||||
- `npm start` will start the app.
|
||||
- `npm run make` will build a standalone app.
|
||||
|
||||
The standalone app was tested on an Intel Mac (`darwin-x64`).
|
||||
|
||||
## Reading and Writing Files
|
||||
|
||||
Since electron provides an `fs` implementation, `readFile` and `writeFile` can
|
||||
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;
|
||||
|
||||
/* show a file-open dialog and read the first selected file */
|
||||
var o = dialog.showOpenDialog({ properties: ['openFile'] });
|
||||
var workbook = XLSX.readFile(o[0]);
|
||||
|
||||
/* show a file-save dialog and write the workbook */
|
||||
var o = dialog.showSaveDialog();
|
||||
XLSX.writeFile(workbook, o);
|
||||
```
|
||||
|
||||
## Breaking Changes in Electron
|
||||
|
||||
The first version of this demo used Electron 1.7.5.
|
||||
|
||||
Electron 9.0.0 and later require the preference `nodeIntegration: true` in order
|
||||
to `require('XLSX')` in the renderer process.
|
||||
|
||||
Electron 12.0.0 and later also require `worldSafeExecuteJavascript: true` and
|
||||
`contextIsolation: true`.
|
||||
|
||||
Electron 14+ must use `@electron/remote` instead of `remote`.
|
||||
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/desktop#electron)
|
||||
includes an improved example and detailed explanations.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,39 +0,0 @@
|
||||
<!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" />
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https:">
|
||||
<title>SheetJS Electron Demo</title>
|
||||
<style>
|
||||
#drop{
|
||||
border:2px dashed #bbb;
|
||||
-moz-border-radius:5px;
|
||||
-webkit-border-radius:5px;
|
||||
border-radius:5px;
|
||||
padding:25px;
|
||||
text-align:center;
|
||||
font:20pt bold,"Vollkorn";color:#bbb
|
||||
}
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Electron Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
<br />
|
||||
<button id="readBtn">Click here to select a file from your computer</button><br />
|
||||
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
|
||||
<input type="file" name="xlfile" id="readIn" /> ... or click here to select a file
|
||||
|
||||
</pre>
|
||||
<p><input type="submit" value="Export Data!" id="exportBtn" disabled="true"></p>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,79 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- https://sheetjs.com */
|
||||
const XLSX = require('xlsx');
|
||||
const electron = require('@electron/remote');
|
||||
|
||||
const EXTENSIONS = "xls|xlsx|xlsm|xlsb|xml|csv|txt|dif|sylk|slk|prn|ods|fods|htm|html".split("|");
|
||||
|
||||
const processWb = function(wb) {
|
||||
const HTMLOUT = document.getElementById('htmlout');
|
||||
const XPORT = document.getElementById('exportBtn');
|
||||
XPORT.disabled = false;
|
||||
HTMLOUT.innerHTML = "";
|
||||
wb.SheetNames.forEach(function(sheetName) {
|
||||
const htmlstr = XLSX.utils.sheet_to_html(wb.Sheets[sheetName],{editable:true});
|
||||
HTMLOUT.innerHTML += htmlstr;
|
||||
});
|
||||
};
|
||||
|
||||
const readFile = function(files) {
|
||||
const f = files[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
let data = e.target.result;
|
||||
data = new Uint8Array(data);
|
||||
processWb(XLSX.read(data, {type: 'array'}));
|
||||
};
|
||||
reader.readAsArrayBuffer(f);
|
||||
};
|
||||
|
||||
const handleReadBtn = async function() {
|
||||
const o = await electron.dialog.showOpenDialog({
|
||||
title: 'Select a file',
|
||||
filters: [{
|
||||
name: "Spreadsheets",
|
||||
extensions: EXTENSIONS
|
||||
}],
|
||||
properties: ['openFile']
|
||||
});
|
||||
if(o.filePaths.length > 0) processWb(XLSX.readFile(o.filePaths[0]));
|
||||
};
|
||||
|
||||
const exportXlsx = async function() {
|
||||
const HTMLOUT = document.getElementById('htmlout');
|
||||
const wb = XLSX.utils.table_to_book(HTMLOUT.getElementsByTagName("TABLE")[0]);
|
||||
const o = await electron.dialog.showSaveDialog({
|
||||
title: 'Save file as',
|
||||
filters: [{
|
||||
name: "Spreadsheets",
|
||||
extensions: EXTENSIONS
|
||||
}]
|
||||
});
|
||||
console.log(o.filePath);
|
||||
XLSX.writeFile(wb, o.filePath);
|
||||
electron.dialog.showMessageBox({ message: "Exported data to " + o.filePath, buttons: ["OK"] });
|
||||
};
|
||||
|
||||
// add event listeners
|
||||
const readBtn = document.getElementById('readBtn');
|
||||
const readIn = document.getElementById('readIn');
|
||||
const exportBtn = document.getElementById('exportBtn');
|
||||
const drop = document.getElementById('drop');
|
||||
|
||||
readBtn.addEventListener('click', handleReadBtn, false);
|
||||
readIn.addEventListener('change', (e) => { readFile(e.target.files); }, false);
|
||||
exportBtn.addEventListener('click', exportXlsx, false);
|
||||
drop.addEventListener('dragenter', (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
}, false);
|
||||
drop.addEventListener('dragover', (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
}, false);
|
||||
drop.addEventListener('drop', (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
readFile(e.dataTransfer.files);
|
||||
}, false);
|
@ -1,30 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* from the electron quick-start */
|
||||
var electron = require('electron');
|
||||
var XLSX = require('xlsx');
|
||||
var app = electron.app;
|
||||
require('@electron/remote/main').initialize();
|
||||
|
||||
var win = null;
|
||||
|
||||
function createWindow() {
|
||||
if (win) return;
|
||||
win = new electron.BrowserWindow({
|
||||
width: 800, height: 600,
|
||||
webPreferences: {
|
||||
worldSafeExecuteJavaScript: true, // required for Electron 12+
|
||||
contextIsolation: false, // required for Electron 12+
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true
|
||||
}
|
||||
});
|
||||
win.loadURL("file://" + __dirname + "/index.html");
|
||||
require('@electron/remote/main').enable(win.webContents);
|
||||
win.webContents.openDevTools();
|
||||
win.on('closed', function () { win = null; });
|
||||
}
|
||||
if (app.setAboutPanelOptions) app.setAboutPanelOptions({ applicationName: 'sheetjs-electron', applicationVersion: "XLSX " + XLSX.version, copyright: "(C) 2017-present SheetJS LLC" });
|
||||
app.on('open-file', function () { console.log(arguments); });
|
||||
app.on('ready', createWindow);
|
||||
app.on('activate', createWindow);
|
||||
app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit(); });
|
@ -1,51 +0,0 @@
|
||||
{
|
||||
"name": "sheetjs-electron",
|
||||
"author": "sheetjs",
|
||||
"version": "0.0.0",
|
||||
"main": "main.js",
|
||||
"dependencies": {
|
||||
"@electron/remote": "2.0.8",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.0-beta.64",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.64",
|
||||
"@electron-forge/maker-rpm": "^6.0.0-beta.64",
|
||||
"@electron-forge/maker-squirrel": "^6.0.0-beta.64",
|
||||
"@electron-forge/maker-zip": "^6.0.0-beta.64",
|
||||
"electron": "19.0.5"
|
||||
},
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"name": "sheetjs_electron"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-zip",
|
||||
"platforms": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-deb",
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-rpm",
|
||||
"config": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
2
demos/meteor/.gitignore
vendored
2
demos/meteor/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
.meteor
|
||||
node_modules/
|
@ -1,14 +0,0 @@
|
||||
.PHONY: start
|
||||
start:
|
||||
@meteor
|
||||
|
||||
.PHONY: init
|
||||
init:
|
||||
if [ ! -e .meteor ]; then meteor create .; fi;
|
||||
@npm install babel-runtime meteor-node-stubs
|
||||
@meteor add check
|
||||
@mkdir -p node_modules; cd node_modules; ln -s ../../../ xlsx; cd -
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@meteor npm run lint
|
@ -1,89 +1,8 @@
|
||||
# Meteor
|
||||
|
||||
This library is universal: outside of environment-specific features (parsing DOM
|
||||
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 * as 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
|
||||
|
||||
Note: this demo intentionally mixes logic between client and server code.
|
||||
Pure-client and pure-server examples are covered in other demos.
|
||||
|
||||
### 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 logic from within the `FileReader` is split as follows:
|
||||
|
||||
```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
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsx');
|
||||
```
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
This tree does not include the `.meteor` structure. Rebuild the project with:
|
||||
|
||||
```bash
|
||||
meteor create .
|
||||
npm install babel-runtime meteor-node-stubs https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
meteor
|
||||
```
|
||||
|
||||
|
||||
## Environment-Specific Features
|
||||
|
||||
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 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.
|
||||
This demo originally covered Meteor's package manager and other nuances. At the
|
||||
time the demo was written, Meteor had its own ecosystem that clashed with the
|
||||
burgeoning NodeJS package ecosystem. Eventually, Meteor added proper support
|
||||
for NodeJS modules. New projects should follow the instructions for packages.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,2 +0,0 @@
|
||||
/* CSS declarations go here */
|
||||
a { text-decoration: none }
|
@ -1,18 +0,0 @@
|
||||
<head>
|
||||
<title>meteor-xlsx</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="//sheetjs.com">SheetJS Meteor Demo</a></b>
|
||||
|
||||
{{> sheetjs}}
|
||||
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<template name="sheetjs">
|
||||
<label for="upload">Parse File: </label><input type="file" id="upload" />
|
||||
<div id="out"></div>
|
||||
<button id="dnload" disabled="true">Generate Worksheet</button>
|
||||
</template>
|
@ -1,39 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
import XLSX from 'xlsx';
|
||||
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
|
||||
import './main.html';
|
||||
|
||||
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('uploadU', new Uint8Array(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.readAsArrayBuffer(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 */
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsx');
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -1,27 +0,0 @@
|
||||
{
|
||||
"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,30 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import XLSX from 'xlsx';
|
||||
|
||||
Meteor.methods({
|
||||
/* read the data and return the workbook object to the frontend */
|
||||
uploadU: (ab, name) => {
|
||||
check(ab, Uint8Array);
|
||||
check(name, String);
|
||||
return XLSX.read(ab, { type: 'array' });
|
||||
},
|
||||
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(() => { });
|
@ -1,7 +0,0 @@
|
||||
.PHONY: test ctest
|
||||
test:
|
||||
cp ../../dist/xlsx.full.min.js .
|
||||
node test.node.js
|
||||
|
||||
ctest:
|
||||
python -mSimpleHTTPServer
|
@ -1,89 +1,6 @@
|
||||
# SystemJS Demos
|
||||
|
||||
SystemJS supports both browser and nodejs deployments. It does not recognize
|
||||
browser environments and automatically suppress node core modules, but with some
|
||||
configuration magic SystemJS can load the library.
|
||||
|
||||
## Browser
|
||||
|
||||
SystemJS fails by default because the library does not export anything in the
|
||||
web browser. The `meta` configuration option can be used to expose `XLSX`:
|
||||
|
||||
```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': '' // <--|
|
||||
}
|
||||
});
|
||||
SystemJS.import('main.js')
|
||||
```
|
||||
|
||||
With the new configuration, `require('xlsx')` will load the library:
|
||||
|
||||
```js
|
||||
var XLSX = require('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);
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
The node core modules should be mapped to their `@node` equivalents:
|
||||
|
||||
```js
|
||||
var SystemJS = require('systemjs');
|
||||
SystemJS.config({
|
||||
map: {
|
||||
'xlsx': 'node_modules/xlsx/xlsx.js',
|
||||
'fs': '@node/fs',
|
||||
'crypto': '@node/crypto',
|
||||
'stream': '@node/stream'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
And use is pretty straightforward:
|
||||
|
||||
```js
|
||||
SystemJS.import('xlsx').then(function(XLSX) {
|
||||
/* XLSX is available here */
|
||||
var w = XLSX.readFile('test.xlsx');
|
||||
var j = XLSX.utils.sheet_to_json(w.Sheets[w.SheetNames[0]], {header:1});
|
||||
console.log(j);
|
||||
});
|
||||
```
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#systemjs)
|
||||
includes a live example and improved explanations.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,5 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var XLSX_1 = require('../../xlsx.js');
|
||||
var XLSX_2 = require('../../dist/xlsx.core.min.js');
|
||||
var XLSX_3 = require('../../dist/xlsx.full.min.js');
|
||||
var XLSX_N = require('xlsx');
|
@ -1,129 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint browser:true */
|
||||
/*global XLSX */
|
||||
var XLSX = require('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 = XLSX.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 = XLSX.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 = XLSX.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 = XLSX.write(workbook, {sheet:sheetName, type:'string', 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 = XLSX.read(tarea.value, {type:'base64', WTF:false});
|
||||
process_wb(wb);
|
||||
};
|
||||
})();
|
||||
|
||||
var do_file = (function() {
|
||||
return function do_file(files) {
|
||||
var f = files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
if(typeof console !== 'undefined') console.log("onload", new Date());
|
||||
var data = e.target.result;
|
||||
data = new Uint8Array(data);
|
||||
process_wb(XLSX.read(data, {type: 'array'}));
|
||||
};
|
||||
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);
|
||||
})();
|
@ -1,6 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var XLSX = require('xlsx');
|
||||
console.log(XLSX.version);
|
||||
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);
|
@ -1,52 +0,0 @@
|
||||
<!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 SystemJS Test</title>
|
||||
<style>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS SystemJS Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
|
||||
Original script: <a href="main.simple.js">main.simple.js</a>
|
||||
|
||||
<b>Console Output:</b>
|
||||
</pre>
|
||||
<pre id="console"></pre>
|
||||
<b>
|
||||
<script>
|
||||
if(typeof console !== "undefined") console = {};
|
||||
console.__log = console.log || function(){};
|
||||
console.log = function(x) {
|
||||
console.__log.apply(console, arguments);
|
||||
document.getElementById('console').innerText += x + "\n";
|
||||
};
|
||||
console.error = console.debug = console.info = console.log
|
||||
</script>
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
@ -1,77 +0,0 @@
|
||||
<!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>
|
||||
</pre>
|
||||
<pre id="out"></pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<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>
|
||||
<script type="text/javascript">
|
||||
/* eslint no-use-before-define:0 */
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,19 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
var SystemJS = require('systemjs');
|
||||
SystemJS.config({
|
||||
meta: {
|
||||
'../../xlsx.js': { format: 'global' },
|
||||
'../../dist/xlsx.core.min.js': { format: 'global' },
|
||||
'../../dist/xlsx.full.min.js': { format: 'global' },
|
||||
},
|
||||
paths: {
|
||||
'npm:': '/usr/local/lib/node_modules/'
|
||||
},
|
||||
map: {
|
||||
'xlsx': 'npm:xlsx/xlsx.js',
|
||||
'fs': '@node/fs',
|
||||
'crypto': '@node/crypto',
|
||||
'stream': '@node/stream'
|
||||
}
|
||||
});
|
||||
SystemJS.import('./app.node.js');
|
@ -1,21 +0,0 @@
|
||||
/* 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
generated
12
demos/systemjs/xlsxworker.js
generated
@ -1,12 +0,0 @@
|
||||
/* 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}); }
|
||||
};
|
@ -2,7 +2,7 @@
|
||||
|
||||
This demo originally covered direct use of the `tsc` TypeScript compiler. At
|
||||
the time when the demo was first written, TypeScript 2.2 had a module system
|
||||
that was incompatibile with the pure JS ecosystem. Since then, various
|
||||
that was incompatible with the pure JS ecosystem. Since then, various
|
||||
language improvements and compiler changes have obviated this demo. Uses of
|
||||
TypeScript are scattered throughout other demos.
|
||||
|
||||
|
1
demos/xhr/.gitignore
vendored
1
demos/xhr/.gitignore
vendored
@ -1 +0,0 @@
|
||||
files/
|
@ -1,7 +0,0 @@
|
||||
.PHONY: serve
|
||||
serve:
|
||||
npm start
|
||||
|
||||
.PHONY: init
|
||||
init:
|
||||
if [ ! -e sheetjs.xlsx ]; then ln -s ../../sheetjs.xlsx; fi
|
@ -1,142 +1,7 @@
|
||||
# XMLHttpRequest and fetch
|
||||
|
||||
`XMLHttpRequest` and `fetch` browser APIs enable binary data transfer between
|
||||
web browser clients and web servers. Since this library works in web browsers,
|
||||
server conversion work can be offloaded to the client! This demo shows a few
|
||||
common scenarios involving browser APIs and popular wrapper libraries.
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/network)
|
||||
includes interactive demos and improved explanations.
|
||||
|
||||
## 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 file 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 uploaded file.
|
||||
It will write the data for the first file to the indicated file name.
|
||||
|
||||
To start the demo, run `npm start` and navigate to <http://localhost:7262/>
|
||||
|
||||
|
||||
## XMLHttpRequest
|
||||
|
||||
For downloading data, the `arraybuffer` response type generates an `ArrayBuffer`
|
||||
that can be viewed as an `Uint8Array` and fed to `XLSX.read` using `array` type:
|
||||
|
||||
```js
|
||||
/* set up an async GET request */
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", url, true);
|
||||
req.responseType = "arraybuffer";
|
||||
|
||||
req.onload = function(e) {
|
||||
/* parse the data when it is received */
|
||||
var data = new Uint8Array(req.response);
|
||||
var workbook = XLSX.read(data, {type:"array"});
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
};
|
||||
req.send();
|
||||
```
|
||||
|
||||
For uploading data, this demo populates a `FormData` object with an ArrayBuffer
|
||||
generated with the `array` output type:
|
||||
|
||||
```js
|
||||
/* generate XLSX as array buffer */
|
||||
var data = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'});
|
||||
|
||||
/* build FormData with the generated file */
|
||||
var fd = new FormData();
|
||||
fd.append('data', new File([data], 'sheetjs.xlsx'));
|
||||
|
||||
/* send data */
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", "/upload", true);
|
||||
req.send(fd);
|
||||
```
|
||||
|
||||
### 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);
|
||||
```
|
||||
|
||||
### axios 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'}).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 */
|
||||
});
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
For downloading data, `response.arrayBuffer()` resolves to an `ArrayBuffer` that
|
||||
can be converted to `Uint8Array` and passed to `XLSX.read`:
|
||||
|
||||
```js
|
||||
fetch(url).then(function(res) {
|
||||
/* get the data as a Blob */
|
||||
if(!res.ok) throw new Error("fetch failed");
|
||||
return res.arrayBuffer();
|
||||
}).then(function(ab) {
|
||||
/* parse the data when it is received */
|
||||
var data = new Uint8Array(ab);
|
||||
var workbook = XLSX.read(data, {type:"array"});
|
||||
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
});
|
||||
```
|
||||
|
||||
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)
|
||||
|
@ -1,80 +0,0 @@
|
||||
<!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>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
<br/><div id="fileurl"></div>
|
||||
</pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<button id="ulbutton">Click here to upload the modified table</button>
|
||||
<pre>
|
||||
<div id="outfile"></div>
|
||||
</pre>
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
|
||||
<script>
|
||||
var demo = 'axios', book = 'xlsx', orig = 'sheetjs.xlsx';
|
||||
|
||||
if(!window.axios) throw new Error("This demo is not supported in your browser");
|
||||
|
||||
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"');
|
||||
}
|
||||
|
||||
var path = 'files/' + demo + '.' + book;
|
||||
document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>';
|
||||
document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>';
|
||||
|
||||
axios(orig, {responseType:'arraybuffer'}).then(function(res) {
|
||||
var data = new Uint8Array(res.data);
|
||||
var wb = XLSX.read(data, {type:"array"});
|
||||
process_wb(wb);
|
||||
}).catch(function(e) {
|
||||
if(/404/.test(e.message) || e.response.status) {
|
||||
var ws = XLSX.utils.aoa_to_sheet([
|
||||
["Fetch for " + orig + " failed :("],
|
||||
["Error Code", e.response.status],
|
||||
["Error Text", e.message],
|
||||
]);
|
||||
ws["!merges"] = [XLSX.utils.decode_range("A1:B1")];
|
||||
process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] });
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
axios("/upload", {method: "POST", data: fd});
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,82 +0,0 @@
|
||||
<!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>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
<br/><div id="fileurl"></div>
|
||||
</pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<button id="ulbutton">Click here to upload the modified table</button>
|
||||
<pre>
|
||||
<div id="outfile"></div>
|
||||
</pre>
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script>
|
||||
var demo = 'fetch', book = 'xlsx', orig = 'sheetjs.xlsx';
|
||||
|
||||
if(!window.fetch) throw new Error("This demo is not supported in your browser");
|
||||
|
||||
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"');
|
||||
}
|
||||
|
||||
var path = 'files/' + demo + '.' + book;
|
||||
document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>';
|
||||
document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>';
|
||||
|
||||
fetch(orig).then(function(res) {
|
||||
if(!res.ok) { var e = new Error(res.statusText); e.response = res; return Promise.reject(e);}
|
||||
return res.arrayBuffer();
|
||||
}).then(function(ab) {
|
||||
var data = new Uint8Array(ab);
|
||||
var wb = XLSX.read(data, {type:"array"});
|
||||
process_wb(wb);
|
||||
}).catch(function(e) {
|
||||
if(/404/.test(e.message) || e.response.status) {
|
||||
var ws = XLSX.utils.aoa_to_sheet([
|
||||
["Fetch for " + orig + " failed :("],
|
||||
["Error Code", e.response.status],
|
||||
["Error Text", e.message],
|
||||
]);
|
||||
ws["!merges"] = [XLSX.utils.decode_range("A1:B1")];
|
||||
process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] });
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
fetch("/upload", {method: "POST", body: fd}).then(function(r) { return r.text(); }).then(function(t) { console.log(t); });
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "sheetjs-xhr-demo",
|
||||
"author": "sheetjs",
|
||||
"version": "0.72.62",
|
||||
"dependencies": {
|
||||
"printj": "1.1.0",
|
||||
"express": "4.15.4",
|
||||
"express-formidable": "1.0.0",
|
||||
"serve-index": "1.9.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node server.js 7262"
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
|
||||
var fs = require('fs'), path = require('path');
|
||||
var express = require('express'), app = express();
|
||||
var sprintf = require('printj').sprintf;
|
||||
|
||||
function logit(req, res, next) {
|
||||
console.log(sprintf("%s %s %d", req.method, req.url, res.statusCode));
|
||||
next();
|
||||
}
|
||||
function cors(req, res, next) {
|
||||
if(!res.headersSent) res.header('Access-Control-Allow-Origin', '*');
|
||||
next();
|
||||
}
|
||||
|
||||
var port = +process.argv[2] || +process.env.PORT || 7262;
|
||||
var basepath = process.cwd();
|
||||
|
||||
var dir = path.join(__dirname, "files");
|
||||
try { fs.mkdirSync(dir); } catch(e) {}
|
||||
|
||||
app.use(logit);
|
||||
app.use(cors);
|
||||
app.use(require('express-formidable')({uploadDir: dir}));
|
||||
app.post('/upload', function(req, res) {
|
||||
console.log(req.files);
|
||||
var f = req.files[Object.keys(req.files)[0]];
|
||||
var newpath = path.join(dir, f.name);
|
||||
fs.renameSync(f.path, newpath);
|
||||
console.log("moved " + f.path + " to " + newpath);
|
||||
res.end("wrote to " + f.name);
|
||||
});
|
||||
app.use(express.static(path.resolve(basepath)));
|
||||
app.use(require('serve-index')(basepath, {'icons':true}));
|
||||
|
||||
app.listen(port, function() { console.log('Serving HTTP on port ' + port); });
|
||||
|
@ -1,82 +0,0 @@
|
||||
<!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>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
<br/><div id="fileurl"></div>
|
||||
</pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<button id="ulbutton">Click here to upload the modified table</button>
|
||||
<pre>
|
||||
<div id="outfile"></div>
|
||||
</pre>
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script src="https://unpkg.com/superagent@7.1.1/dist/superagent.min.js"></script>
|
||||
<script>
|
||||
var demo = 'superagent', book = 'xlsx', orig = 'sheetjs.xlsx';
|
||||
|
||||
if(!window.superagent) throw new Error("This demo is not supported in your browser");
|
||||
|
||||
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"');
|
||||
}
|
||||
|
||||
var path = 'files/' + demo + '.' + book;
|
||||
document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>';
|
||||
document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>';
|
||||
|
||||
superagent.get(orig).responseType('arraybuffer').end(function(e, res) {
|
||||
if(!e) {
|
||||
var data = new Uint8Array(res.body);
|
||||
var wb = XLSX.read(data, {type:"array"});
|
||||
process_wb(wb);
|
||||
return;
|
||||
}
|
||||
if(/404/.test(e.message) || e.response.status) {
|
||||
var ws = XLSX.utils.aoa_to_sheet([
|
||||
["Fetch for " + orig + " failed :("],
|
||||
["Error Code", e.response.status],
|
||||
["Error Text", e.message],
|
||||
]);
|
||||
ws["!merges"] = [XLSX.utils.decode_range("A1:B1")];
|
||||
process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] });
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
superagent.post("/upload").send(fd).end(function(e,r) { console.log(r.text); });
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,87 +0,0 @@
|
||||
<!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>
|
||||
a { text-decoration: none }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
|
||||
|
||||
<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
|
||||
<a href="https://github.com/SheetJS/js-xlsx/issues">Issues? Something look weird? Click here and report an issue</a>
|
||||
<br/><div id="fileurl"></div>
|
||||
</pre>
|
||||
<div id="htmlout"></div>
|
||||
<br />
|
||||
<button id="ulbutton">Click here to upload the modified table</button>
|
||||
<pre>
|
||||
<div id="outfile"></div>
|
||||
</pre>
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script>
|
||||
var demo = 'xhr', book = 'xlsx', orig = 'sheetjs.xlsx2';
|
||||
|
||||
if(!window.XMLHttpRequest || typeof Uint8Array === 'undefined') throw new Error("This demo is not supported in your browser");
|
||||
|
||||
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"');
|
||||
}
|
||||
|
||||
var path = 'files/' + demo + '.' + book;
|
||||
document.getElementById('fileurl').innerHTML = '<a href="' + orig + '">Download original file</a>';
|
||||
document.getElementById('outfile').innerHTML = '<a href="' + path + '">Download new file: ' + path + '</a>';
|
||||
|
||||
{
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("GET", orig, true);
|
||||
req.responseType = "arraybuffer";
|
||||
req.onload = function(e) {
|
||||
if(req.status == 200) {
|
||||
var data = new Uint8Array(req.response);
|
||||
var wb = XLSX.read(data, {type:"array"});
|
||||
process_wb(wb);
|
||||
return;
|
||||
}
|
||||
var ws = XLSX.utils.aoa_to_sheet([
|
||||
["Fetch for " + orig + " failed :("],
|
||||
["Error Code", req.status],
|
||||
["Error Text", req.statusText],
|
||||
]);
|
||||
ws["!merges"] = [XLSX.utils.decode_range("A1:B1")];
|
||||
process_wb({ "Sheets": { "Sheet1": ws }, "SheetNames": [ "Sheet1" ] });
|
||||
};
|
||||
req.send();
|
||||
}
|
||||
|
||||
document.getElementById('ulbutton').onclick = function() {
|
||||
var wb = XLSX.utils.table_to_book(document.getElementById('htmlout'));
|
||||
console.log(wb);
|
||||
var fd = new FormData();
|
||||
var data = XLSX.write(wb, {bookType:book, type:'array'});
|
||||
console.log(data);
|
||||
fd.append('data', new File([data], demo + '.' + book));
|
||||
var req = new XMLHttpRequest();
|
||||
req.open("POST", "/upload", true);
|
||||
req.send(fd);
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
demos/xhr/xlsx.full.min.js
vendored
1
demos/xhr/xlsx.full.min.js
vendored
@ -1 +0,0 @@
|
||||
../../dist/xlsx.full.min.js
|
11
packages/s2c/README.md
Normal file
11
packages/s2c/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# s2c
|
||||
|
||||
`mod.ts` exports the following methods:
|
||||
|
||||
- `parse_book_from_request` reads a field from a request, parses the field with
|
||||
the Drash body parser, and returns a SheetJS workbook object. This does not
|
||||
use the filesystem, so it supports Deno Deploy and other restricted services.
|
||||
|
||||
`s2c.ts` is the script that powers <https://s2c.sheetjs.com>
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
21
packages/s2c/mod.ts
Normal file
21
packages/s2c/mod.ts
Normal file
@ -0,0 +1,21 @@
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
|
||||
import { read, set_cptable } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-latest/package/dist/cpexcel.full.mjs';
|
||||
set_cptable(cptable);
|
||||
|
||||
import type { Request } from "https://deno.land/x/drash@v2.5.4/mod.ts";
|
||||
import { Types } from "https://deno.land/x/drash@v2.5.4/mod.ts";
|
||||
|
||||
/**
|
||||
* Parse a workbook from an uploaded file
|
||||
*
|
||||
* This works with Deno Deploy (Drash body parser does not use temp files)
|
||||
*
|
||||
* request is a Drash.Request object
|
||||
* field is the name of the field to read
|
||||
*/
|
||||
export function parse_book_from_request(request: Request, field: string) {
|
||||
const file = request.bodyParam<Types.BodyFile>(field);
|
||||
if(!file) throw new Error(`Field ${field} is missing!`);
|
||||
return read(file.content, { type: "buffer" });
|
||||
}
|
78
packages/s2c/s2c.ts
Normal file
78
packages/s2c/s2c.ts
Normal file
@ -0,0 +1,78 @@
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
|
||||
import { read, utils, set_cptable, version } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-latest/package/dist/cpexcel.full.mjs';
|
||||
set_cptable(cptable);
|
||||
|
||||
import * as Drash from "https://deno.land/x/drash@v2.5.4/mod.ts";
|
||||
|
||||
|
||||
class S2CResource extends Drash.Resource {
|
||||
public paths = ["/"];
|
||||
|
||||
// see https://github.com/drashland/drash/issues/194
|
||||
public OPTIONS(request: Drash.Request, response: Drash.Response) {
|
||||
const allHttpMethods: string[] = [ "GET", "POST", "PUT", "DELETE" ];
|
||||
response.headers.set("Allow", allHttpMethods.join()); // Use this
|
||||
response.headers.set("Access-Control-Allow-Methods", allHttpMethods.join()); // or this
|
||||
response.headers.set("access-control-allow-origin", "*");
|
||||
response.status_code = 204;
|
||||
return response;
|
||||
}
|
||||
|
||||
public POST(request: Drash.Request, response: Drash.Response) {
|
||||
const file = request.bodyParam<Drash.Types.BodyFile>("file");
|
||||
try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {}
|
||||
if (!file) throw new Error("File is required!");
|
||||
var wb = read(file.content, {type: "buffer"});
|
||||
return response.html( utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]));
|
||||
}
|
||||
|
||||
public GET(request: Drash.Request, response: Drash.Response): void {
|
||||
try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {}
|
||||
return response.html(`\
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SheetJS Spreadsheet to HTML Conversion Service</title>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<pre><h3><a href="//sheetjs.com/">SheetJS</a> Spreadsheet Conversion Service</h3>
|
||||
<b>API</b>
|
||||
|
||||
Send a POST request to https://s2c.deno.dev/ with the file in the "file" body parameter:
|
||||
|
||||
$ curl -X POST -F"file=@test.xlsx" https://s2c.deno.dev/
|
||||
|
||||
The response will be an HTML TABLE generated from the first worksheet.
|
||||
|
||||
<b>Try it out!</b><form action="/" method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="file" name="file" />
|
||||
|
||||
Use the file input element to select a file, then click "Submit"
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
Library Version: ${version}
|
||||
</pre>
|
||||
</body>
|
||||
</html>`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Create and run your server
|
||||
const server = new Drash.Server({
|
||||
hostname: "",
|
||||
port: 3000,
|
||||
protocol: "http",
|
||||
resources: [
|
||||
S2CResource,
|
||||
],
|
||||
});
|
||||
|
||||
server.run();
|
||||
|
||||
console.log(`Server running at ${server.address}.`);
|
74
packages/s2c/test.ts
Normal file
74
packages/s2c/test.ts
Normal file
@ -0,0 +1,74 @@
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
|
||||
import { utils, set_cptable, version } from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
|
||||
import { parse_book_from_request } from "./mod.ts";
|
||||
import * as Drash from "https://deno.land/x/drash@v2.5.4/mod.ts";
|
||||
|
||||
class S2CResource extends Drash.Resource {
|
||||
public paths = ["/"];
|
||||
|
||||
// see https://github.com/drashland/drash/issues/194
|
||||
public OPTIONS(request: Drash.Request, response: Drash.Response) {
|
||||
const allHttpMethods: string[] = [ "GET", "POST", "PUT", "DELETE" ];
|
||||
response.headers.set("Allow", allHttpMethods.join()); // Use this
|
||||
response.headers.set("Access-Control-Allow-Methods", allHttpMethods.join()); // or this
|
||||
response.headers.set("access-control-allow-origin", "*");
|
||||
response.status_code = 204;
|
||||
return response;
|
||||
}
|
||||
|
||||
public POST(request: Drash.Request, response: Drash.Response) {
|
||||
try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {}
|
||||
var wb = parse_book_from_request(request, "file");
|
||||
return response.html( utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]));
|
||||
}
|
||||
|
||||
public GET(request: Drash.Request, response: Drash.Response): void {
|
||||
try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {}
|
||||
return response.html(`\
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SheetJS Spreadsheet to HTML Conversion Service</title>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<pre><h3><a href="//sheetjs.com/">SheetJS</a> Spreadsheet Conversion Service</h3>
|
||||
<b>API</b>
|
||||
|
||||
Send a POST request to https://s2c.deno.dev/ with the file in the "file" body parameter:
|
||||
|
||||
$ curl -X POST -F"file=@test.xlsx" https://s2c.deno.dev/
|
||||
|
||||
The response will be an HTML TABLE generated from the first worksheet.
|
||||
|
||||
<b>Try it out!</b><form action="/" method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="file" name="file" />
|
||||
|
||||
Use the file input element to select a file, then click "Submit"
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
|
||||
Library Version: ${version}
|
||||
</pre>
|
||||
</body>
|
||||
</html>`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Create and run your server
|
||||
const server = new Drash.Server({
|
||||
hostname: "",
|
||||
port: 3000,
|
||||
protocol: "http",
|
||||
resources: [
|
||||
S2CResource,
|
||||
],
|
||||
});
|
||||
|
||||
server.run();
|
||||
|
||||
console.log(`Server running at ${server.address}.`);
|
||||
|
24
test.js
24
test.js
@ -2197,6 +2197,30 @@ describe('CSV', function() {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
it('should parse date-less meridien time values', function() {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
describe('output', function(){
|
||||
var data, ws;
|
||||
|
24
test.mjs
generated
24
test.mjs
generated
@ -2183,6 +2183,30 @@ describe('CSV', function() {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
it('should parse date-less meridien time values', function() {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
describe('output', function(){
|
||||
var data, ws;
|
||||
|
24
test.mts
24
test.mts
@ -2139,6 +2139,30 @@ describe('CSV', function() {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
it('should parse date-less meridien time values', function() {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
describe('output', function(){
|
||||
var data = [
|
||||
|
24
test.ts
24
test.ts
@ -2139,6 +2139,30 @@ Deno.test('CSV', async function(t) {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
await t.step('should parse date-less meridien time values', async function(t) {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
await t.step('output', async function(t){
|
||||
var data = [
|
||||
|
24
testnocp.ts
24
testnocp.ts
@ -2138,6 +2138,30 @@ Deno.test('CSV', async function(t) {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
await t.step('should parse date-less meridien time values', async function(t) {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
await t.step('output', async function(t){
|
||||
var data = [
|
||||
|
24
tests/core.js
generated
24
tests/core.js
generated
@ -2196,6 +2196,30 @@ describe('CSV', function() {
|
||||
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
|
||||
});
|
||||
});
|
||||
it('should parse date-less meridien time values', function() {
|
||||
var aoa = [
|
||||
["3a", "3 a", "3 a-1"],
|
||||
["3b", "3 b", "3 b-1"],
|
||||
["3p", "3 P", "3 p-1"],
|
||||
]
|
||||
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); console.log(B1); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
|
||||
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
|
||||
for(var R = 0; R < 3; ++R) {
|
||||
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
|
||||
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
|
||||
}
|
||||
assert.equal(get_cell(ws, "B2").v, "3 b");
|
||||
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal(B1.v * 24, 3);
|
||||
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal(B3.v * 24, 15);
|
||||
|
||||
});
|
||||
});
|
||||
describe('output', function(){
|
||||
var data, ws;
|
||||
|
32
xlsx.flow.js
32
xlsx.flow.js
@ -3447,22 +3447,22 @@ function fuzzynum(s/*:string*/)/*:number*/ {
|
||||
}
|
||||
|
||||
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))([ap])m?/;
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
||||
|
||||
function fuzzytime1(M) /*:Date*/ {
|
||||
/* TODO: 1904 adjustment */
|
||||
if(!M[2]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
/* TODO: 1904 adjustment, keep in sync with base date */
|
||||
if(!M[2]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
if(M[3]) {
|
||||
if(M[4]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1900,0,0,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
if(M[4]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1899,11,30,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
}
|
||||
else if(M[5]) return new Date(1900, 0, 0, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
else if(M[5]) return new Date(1899,11,30, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
}
|
||||
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
||||
function fuzzydate(s/*:string*/)/*:Date*/ {
|
||||
var lower = s.toLowerCase();
|
||||
var lnos = lower.replace(/\s+/g, "");
|
||||
var lnos = lower.replace(/\s+/g, " ").trim();
|
||||
var M = lnos.match(FDRE1);
|
||||
if(M) return fuzzytime1(M);
|
||||
|
||||
@ -8064,6 +8064,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
}
|
||||
wb.Workbook.Names.push(nn);
|
||||
} break;
|
||||
// case 'NE': // ??
|
||||
// case 'NU': // ??
|
||||
case 'C': /* cell */
|
||||
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1, formula = "", cell_t = "z";
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
@ -8097,6 +8099,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
case 'G': break; // unknown
|
||||
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
// case 'P': // ??
|
||||
// case 'D': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(C_seen_K) {
|
||||
@ -8150,6 +8154,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
|
||||
else if(Mval === 0) rowinfo[R].hidden = true;
|
||||
break;
|
||||
// case 'K': // ??
|
||||
// case 'E': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
@ -8575,12 +8581,12 @@ var PRN = /*#__PURE__*/(function() {
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
|
||||
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
||||
cell.z = o.dateNF || table_fmt[14];
|
||||
var k = 0;
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s, k); }
|
||||
else { cell.t = 'n'; cell.v = datenum(parseDate(s, k)); }
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; v = parseDate(s, k); }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
||||
else { cell.t = 'n'; cell.v = datenum(v); }
|
||||
if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
||||
if(!o.cellNF) delete cell.z;
|
||||
} else {
|
||||
@ -23896,6 +23902,8 @@ function parse_numbers_iwa(cfb, opts) {
|
||||
cfb.FileIndex.forEach(function(s) {
|
||||
if (!s.name.match(/\.iwa$/))
|
||||
return;
|
||||
if (s.content[0] == 98)
|
||||
return;
|
||||
var o;
|
||||
try {
|
||||
o = decompress_iwa_file(s.content);
|
||||
|
32
xlsx.js
generated
32
xlsx.js
generated
@ -3373,22 +3373,22 @@ function fuzzynum(s) {
|
||||
}
|
||||
|
||||
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))([ap])m?/;
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
||||
|
||||
function fuzzytime1(M) {
|
||||
/* TODO: 1904 adjustment */
|
||||
if(!M[2]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
/* TODO: 1904 adjustment, keep in sync with base date */
|
||||
if(!M[2]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
if(M[3]) {
|
||||
if(M[4]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1900,0,0,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
if(M[4]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1899,11,30,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
}
|
||||
else if(M[5]) return new Date(1900, 0, 0, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
else if(M[5]) return new Date(1899,11,30, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
}
|
||||
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
||||
function fuzzydate(s) {
|
||||
var lower = s.toLowerCase();
|
||||
var lnos = lower.replace(/\s+/g, "");
|
||||
var lnos = lower.replace(/\s+/g, " ").trim();
|
||||
var M = lnos.match(FDRE1);
|
||||
if(M) return fuzzytime1(M);
|
||||
|
||||
@ -7974,6 +7974,8 @@ var SYLK = (function() {
|
||||
}
|
||||
wb.Workbook.Names.push(nn);
|
||||
} break;
|
||||
// case 'NE': // ??
|
||||
// case 'NU': // ??
|
||||
case 'C': /* cell */
|
||||
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1, formula = "", cell_t = "z";
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
@ -8007,6 +8009,8 @@ var SYLK = (function() {
|
||||
case 'G': break; // unknown
|
||||
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
// case 'P': // ??
|
||||
// case 'D': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(C_seen_K) {
|
||||
@ -8060,6 +8064,8 @@ var SYLK = (function() {
|
||||
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
|
||||
else if(Mval === 0) rowinfo[R].hidden = true;
|
||||
break;
|
||||
// case 'K': // ??
|
||||
// case 'E': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
@ -8485,12 +8491,12 @@ var PRN = (function() {
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
|
||||
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
||||
cell.z = o.dateNF || table_fmt[14];
|
||||
var k = 0;
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s, k); }
|
||||
else { cell.t = 'n'; cell.v = datenum(parseDate(s, k)); }
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; v = parseDate(s, k); }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
||||
else { cell.t = 'n'; cell.v = datenum(v); }
|
||||
if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
||||
if(!o.cellNF) delete cell.z;
|
||||
} else {
|
||||
@ -23786,6 +23792,8 @@ function parse_numbers_iwa(cfb, opts) {
|
||||
cfb.FileIndex.forEach(function(s) {
|
||||
if (!s.name.match(/\.iwa$/))
|
||||
return;
|
||||
if (s.content[0] == 98)
|
||||
return;
|
||||
var o;
|
||||
try {
|
||||
o = decompress_iwa_file(s.content);
|
||||
|
32
xlsx.mjs
generated
32
xlsx.mjs
generated
@ -3446,22 +3446,22 @@ function fuzzynum(s/*:string*/)/*:number*/ {
|
||||
}
|
||||
|
||||
/* NOTE: Chrome rejects bare times like 1:23 PM */
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))([ap])m?/;
|
||||
var FDRE1 = /^(0?\d|1[0-2])(?:|:([0-5]?\d)(?:|(\.\d+)(?:|:([0-5]?\d))|:([0-5]?\d)(|\.\d+)))\s+([ap])m?$/;
|
||||
|
||||
function fuzzytime1(M) /*:Date*/ {
|
||||
/* TODO: 1904 adjustment */
|
||||
if(!M[2]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
/* TODO: 1904 adjustment, keep in sync with base date */
|
||||
if(!M[2]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), 0, 0, 0);
|
||||
if(M[3]) {
|
||||
if(M[4]) return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1900,0,0,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
if(M[4]) return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[4], parseFloat(M[3])*1000);
|
||||
else return new Date(1899,11,30,(M[7] == "p" ? 12 : 0), +M[1], +M[2], parseFloat(M[3])*1000);
|
||||
}
|
||||
else if(M[5]) return new Date(1900, 0, 0, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1900,0,0,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
else if(M[5]) return new Date(1899,11,30, (+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], +M[5], M[6] ? parseFloat(M[6]) * 1000 : 0);
|
||||
else return new Date(1899,11,30,(+M[1]%12) + (M[7] == "p" ? 12 : 0), +M[2], 0, 0);
|
||||
}
|
||||
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
||||
function fuzzydate(s/*:string*/)/*:Date*/ {
|
||||
var lower = s.toLowerCase();
|
||||
var lnos = lower.replace(/\s+/g, "");
|
||||
var lnos = lower.replace(/\s+/g, " ").trim();
|
||||
var M = lnos.match(FDRE1);
|
||||
if(M) return fuzzytime1(M);
|
||||
|
||||
@ -8059,6 +8059,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
}
|
||||
wb.Workbook.Names.push(nn);
|
||||
} break;
|
||||
// case 'NE': // ??
|
||||
// case 'NU': // ??
|
||||
case 'C': /* cell */
|
||||
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1, formula = "", cell_t = "z";
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
@ -8092,6 +8094,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
case 'G': break; // unknown
|
||||
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
|
||||
// case 'P': // ??
|
||||
// case 'D': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(C_seen_K) {
|
||||
@ -8145,6 +8149,8 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
|
||||
else if(Mval === 0) rowinfo[R].hidden = true;
|
||||
break;
|
||||
// case 'K': // ??
|
||||
// case 'E': // ??
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
if(F_seen < 1) next_cell_format = null; break;
|
||||
@ -8570,12 +8576,12 @@ var PRN = /*#__PURE__*/(function() {
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
|
||||
else if(!isNaN((v = fuzzydate(s)).getDate()) || _re && s.match(_re)) {
|
||||
cell.z = o.dateNF || table_fmt[14];
|
||||
var k = 0;
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s, k); }
|
||||
else { cell.t = 'n'; cell.v = datenum(parseDate(s, k)); }
|
||||
if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; v = parseDate(s, k); }
|
||||
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
|
||||
else { cell.t = 'n'; cell.v = datenum(v); }
|
||||
if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
|
||||
if(!o.cellNF) delete cell.z;
|
||||
} else {
|
||||
@ -23891,6 +23897,8 @@ function parse_numbers_iwa(cfb, opts) {
|
||||
cfb.FileIndex.forEach(function(s) {
|
||||
if (!s.name.match(/\.iwa$/))
|
||||
return;
|
||||
if (s.content[0] == 98)
|
||||
return;
|
||||
var o;
|
||||
try {
|
||||
o = decompress_iwa_file(s.content);
|
||||
|
Loading…
Reference in New Issue
Block a user