forked from sheetjs/sheetjs
version bump 0.11.6: ancillary format update
- BIFF5 XLS write (bookType "biff5") - DBF Level 7 read - ODS whitespace and repeated rows - flow and lint cleanup
This commit is contained in:
parent
ef9f3f9ca5
commit
f968dfe4ed
@ -2,7 +2,6 @@
|
||||
.*/node_modules/.*
|
||||
.*/dist/.*
|
||||
.*/tmp/.*
|
||||
.*/test.js
|
||||
|
||||
.*/bits/.*
|
||||
.*/ctest/.*
|
||||
@ -25,6 +24,7 @@ xlsxworker.flow.js
|
||||
xlsx.flow.js
|
||||
.*/bin/.*.njs
|
||||
.*/demo/browser.flow.js
|
||||
test.js
|
||||
|
||||
[libs]
|
||||
bits/09_types.js
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@ tmp
|
||||
*.html
|
||||
*.sheetjs
|
||||
*.exe
|
||||
*.img
|
||||
|
@ -29,6 +29,7 @@ tmp
|
||||
*.html
|
||||
*.sheetjs
|
||||
*.exe
|
||||
*.img
|
||||
.gitignore
|
||||
.fossaignore
|
||||
.spelling
|
||||
|
@ -70,6 +70,8 @@ filesystem
|
||||
javascript
|
||||
metadata
|
||||
natively
|
||||
pre-built
|
||||
pre-generated
|
||||
prepend
|
||||
prepended
|
||||
repo
|
||||
|
@ -4,6 +4,10 @@ This log is intended to keep track of backwards-incompatible changes, including
|
||||
but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
## 0.11.6 (2017-10-16)
|
||||
|
||||
* Semicolon-delimited files are detected
|
||||
|
||||
## 0.11.5 (2017-09-30)
|
||||
|
||||
* Bower main script shifted to full version
|
||||
|
2
Makefile
2
Makefile
@ -213,7 +213,7 @@ book: readme graph ## Update summary for documentation
|
||||
<README.md grep -vE "(details|summary)>" > misc/docs/README.md
|
||||
|
||||
DEMOMDS=$(sort $(wildcard demos/*/README.md))
|
||||
MDLINT=$(DEMODS) $(READEPS) demos/README.md
|
||||
MDLINT=$(DEMOMDS) $(READEPS) demos/README.md
|
||||
.PHONY: mdlint
|
||||
mdlint: $(MDLINT) ## Check markdown documents
|
||||
alex $^
|
||||
|
12
README.md
12
README.md
@ -1565,8 +1565,9 @@ Plain text format guessing follows the priority order:
|
||||
| XML | starts with `<` |
|
||||
| RTF | starts with `{\rt` |
|
||||
| DSV | starts with `/sep=.$/`, separator is the specified character |
|
||||
| CSV | more unquoted `","` characters than `"\t"` chars in the first 1024 |
|
||||
| TSV | one of the first 1024 characters is a tab char `"\t"` |
|
||||
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
|
||||
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
|
||||
| CSV | one of the first 1024 characters is a comma `","` |
|
||||
| PRN | (default) |
|
||||
|
||||
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`
|
||||
@ -1629,6 +1630,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
@ -1638,7 +1640,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
@ -1957,7 +1959,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | :o: |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | :o: | :o: |
|
||||
@ -1976,7 +1978,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
|
@ -21,7 +21,7 @@ program
|
||||
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
|
||||
.option('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
|
||||
.option('-8, --xls', 'emit XLS to <sheetname> or <file>.xls (BIFF8)')
|
||||
//.option('-5, --biff5','emit XLS to <sheetname> or <file>.xls (BIFF5)')
|
||||
.option('-5, --biff5','emit XLS to <sheetname> or <file>.xls (BIFF5)')
|
||||
//.option('-4, --biff4','emit XLS to <sheetname> or <file>.xls (BIFF4)')
|
||||
//.option('-3, --biff3','emit XLS to <sheetname> or <file>.xls (BIFF3)')
|
||||
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
|
||||
@ -44,11 +44,10 @@ program
|
||||
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
|
||||
.option('--sst', 'generate shared string table for XLS* formats')
|
||||
.option('--compress', 'use compression when writing XLSX/M/B and ODS')
|
||||
.option('--read-only', 'do not generate output')
|
||||
.option('--read', 'read but do not generate output')
|
||||
.option('--all', 'parse everything; write as much as possible')
|
||||
.option('--dev', 'development mode')
|
||||
.option('--sparse', 'sparse mode')
|
||||
.option('--read', 'read but do not print out contents')
|
||||
.option('-q, --quiet', 'quiet mode');
|
||||
|
||||
program.on('--help', function() {
|
||||
@ -176,9 +175,8 @@ try {
|
||||
process.exit(4);
|
||||
}
|
||||
|
||||
if(program.readOnly) process.exit(0);
|
||||
|
||||
/* single worksheet formats */
|
||||
/* single worksheet file formats */
|
||||
[
|
||||
['biff2', '.xls'],
|
||||
['biff3', '.xls'],
|
||||
|
@ -1,7 +1,5 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint -W041 */
|
||||
/*jshint funcscope:true, eqnull:true, loopfunc:true */
|
||||
/*exported XLSX */
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.11.5';
|
||||
XLSX.version = '0.11.6';
|
||||
|
@ -28,14 +28,14 @@ var debom = function(data/*:string*/)/*:string*/ {
|
||||
return data;
|
||||
};
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
var _getchar = function _gc1(x/*:number*/)/*:string*/ { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; };
|
||||
debom = function(data) {
|
||||
set_cp = function(cp/*:number*/) { current_codepage = cp; };
|
||||
debom = function(data/*:string*/) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
};
|
||||
_getchar = function _gc2(x) {
|
||||
_getchar = function _gc2(x/*:number*/)/*:string*/ {
|
||||
if(current_codepage === 1200) return String.fromCharCode(x);
|
||||
return cptable.utils.decode(current_codepage, [x&255,x>>8])[0];
|
||||
};
|
||||
|
@ -102,7 +102,7 @@ var utf8read/*:StringConv*/ = function utf8reada(orig) {
|
||||
};
|
||||
|
||||
var utf8write/*:StringConv*/ = function(orig) {
|
||||
var out = [], i = 0, c = 0, d = 0;
|
||||
var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
switch(true) {
|
||||
@ -197,7 +197,7 @@ function writextag(f,g,h) { return '<' + f + (isval(h) /*:: && h */? wxt_helper(
|
||||
|
||||
function write_w3cdtf(d/*:Date*/, t/*:?boolean*/)/*:string*/ { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } return ""; }
|
||||
|
||||
function write_vt(s) {
|
||||
function write_vt(s)/*:string*/ {
|
||||
switch(typeof s) {
|
||||
case 'string': return writextag('vt:lpwstr', s);
|
||||
case 'number': return writextag((s|0)==s?'vt:i4':'vt:r8', String(s));
|
||||
|
@ -74,6 +74,7 @@ var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/
|
||||
var __readInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
|
||||
var __readUInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
var __readInt32BE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx]<<24)|(b[idx+1]<<16)|(b[idx+2]<<8)|b[idx+3]; };
|
||||
|
||||
var ___unhexlify = function(s/*:string*/)/*:Array<number>*/ { return (s.match(/../g)||[]).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s/*:string*/)/*:Array<number>|Buffer*/ { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
@ -141,10 +142,15 @@ function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
|
||||
switch(size) {
|
||||
case 1: oI = __readUInt8(this, this.l); this.l++; return oI;
|
||||
case 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI;
|
||||
case 4:
|
||||
if(t === 'i' || (this[this.l+3] & 0x80)===0) { oI = __readInt32LE(this, this.l); this.l += 4; return oI; }
|
||||
case 4: case -4:
|
||||
if(t === 'i' || (this[this.l+3] & 0x80)===0) { oI = (size > 0 ? __readInt32LE : __readInt32BE)(this, this.l); this.l += 4; return oI; }
|
||||
else { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR;
|
||||
case 8: if(t === 'f') { oR = __double(this, this.l); this.l += 8; return oR; }
|
||||
case 8: case -8:
|
||||
if(t === 'f') {
|
||||
if(size == 8) oR = __double(this, this.l);
|
||||
else oR = __double([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]], 0);
|
||||
this.l += 8; return oR;
|
||||
} else size = 8;
|
||||
/* falls through */
|
||||
case 16: o = __hexlify(this, this.l, size); break;
|
||||
}}
|
||||
@ -162,6 +168,9 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/
|
||||
for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
|
||||
size = 2 * val.length;
|
||||
} else if(f === 'sbcs') {
|
||||
/* TODO: codepage */
|
||||
/*:: if(typeof val !== 'string') throw new Error("unreachable"); */
|
||||
val = val.replace(/[^\x00-\x7F]/g, "_");
|
||||
/*:: if(typeof val !== 'string') throw new Error("unreachable"); */
|
||||
for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
size = val.length;
|
||||
|
@ -1,45 +1,43 @@
|
||||
/* [MS-OLEPS] 2.2 PropertyType */
|
||||
{
|
||||
//var VT_EMPTY = 0x0000;
|
||||
//var VT_NULL = 0x0001;
|
||||
var VT_I2 = 0x0002;
|
||||
var VT_I4 = 0x0003;
|
||||
//var VT_R4 = 0x0004;
|
||||
//var VT_R8 = 0x0005;
|
||||
//var VT_CY = 0x0006;
|
||||
//var VT_DATE = 0x0007;
|
||||
//var VT_BSTR = 0x0008;
|
||||
//var VT_ERROR = 0x000A;
|
||||
var VT_BOOL = 0x000B;
|
||||
var VT_VARIANT = 0x000C;
|
||||
//var VT_DECIMAL = 0x000E;
|
||||
//var VT_I1 = 0x0010;
|
||||
//var VT_UI1 = 0x0011;
|
||||
//var VT_UI2 = 0x0012;
|
||||
var VT_UI4 = 0x0013;
|
||||
//var VT_I8 = 0x0014;
|
||||
var VT_UI8 = 0x0015;
|
||||
//var VT_INT = 0x0016;
|
||||
//var VT_UINT = 0x0017;
|
||||
var VT_LPSTR = 0x001E;
|
||||
//var VT_LPWSTR = 0x001F;
|
||||
var VT_FILETIME = 0x0040;
|
||||
//var VT_BLOB = 0x0041;
|
||||
//var VT_STREAM = 0x0042;
|
||||
//var VT_STORAGE = 0x0043;
|
||||
//var VT_STREAMED_Object = 0x0044;
|
||||
//var VT_STORED_Object = 0x0045;
|
||||
//var VT_BLOB_Object = 0x0046;
|
||||
var VT_CF = 0x0047;
|
||||
//var VT_CLSID = 0x0048;
|
||||
//var VT_VERSIONED_STREAM = 0x0049;
|
||||
var VT_VECTOR = 0x1000;
|
||||
//var VT_ARRAY = 0x2000;
|
||||
//var VT_EMPTY = 0x0000;
|
||||
//var VT_NULL = 0x0001;
|
||||
var VT_I2 = 0x0002;
|
||||
var VT_I4 = 0x0003;
|
||||
//var VT_R4 = 0x0004;
|
||||
//var VT_R8 = 0x0005;
|
||||
//var VT_CY = 0x0006;
|
||||
//var VT_DATE = 0x0007;
|
||||
//var VT_BSTR = 0x0008;
|
||||
//var VT_ERROR = 0x000A;
|
||||
var VT_BOOL = 0x000B;
|
||||
var VT_VARIANT = 0x000C;
|
||||
//var VT_DECIMAL = 0x000E;
|
||||
//var VT_I1 = 0x0010;
|
||||
//var VT_UI1 = 0x0011;
|
||||
//var VT_UI2 = 0x0012;
|
||||
var VT_UI4 = 0x0013;
|
||||
//var VT_I8 = 0x0014;
|
||||
var VT_UI8 = 0x0015;
|
||||
//var VT_INT = 0x0016;
|
||||
//var VT_UINT = 0x0017;
|
||||
var VT_LPSTR = 0x001E;
|
||||
//var VT_LPWSTR = 0x001F;
|
||||
var VT_FILETIME = 0x0040;
|
||||
//var VT_BLOB = 0x0041;
|
||||
//var VT_STREAM = 0x0042;
|
||||
//var VT_STORAGE = 0x0043;
|
||||
//var VT_STREAMED_Object = 0x0044;
|
||||
//var VT_STORED_Object = 0x0045;
|
||||
//var VT_BLOB_Object = 0x0046;
|
||||
var VT_CF = 0x0047;
|
||||
//var VT_CLSID = 0x0048;
|
||||
//var VT_VERSIONED_STREAM = 0x0049;
|
||||
var VT_VECTOR = 0x1000;
|
||||
//var VT_ARRAY = 0x2000;
|
||||
|
||||
var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
|
||||
var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
|
||||
var VT_CUSTOM = [VT_STRING, VT_USTR];
|
||||
}
|
||||
var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
|
||||
var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
|
||||
var VT_CUSTOM = [VT_STRING, VT_USTR];
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */
|
||||
var DocSummaryPIDDSI = {
|
||||
|
@ -56,9 +56,9 @@ function write_rdf(rdf, opts) {
|
||||
return o.join("");
|
||||
}
|
||||
/* TODO: pull properties */
|
||||
var write_meta_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
var write_meta_ods/*:{(wb:Workbook, opts:any):string}*/ = (function() {
|
||||
var payload = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink" office:version="1.2"><office:meta><meta:generator>Sheet' + 'JS ' + XLSX.version + '</meta:generator></office:meta></office:document-meta>';
|
||||
return function wmo(wb, opts) {
|
||||
return function wmo(wb/*:Workbook*/, opts) {
|
||||
return payload;
|
||||
};
|
||||
})();
|
||||
|
@ -108,7 +108,7 @@ function parse_VtVector(blob, cb) {
|
||||
}
|
||||
|
||||
/* [MS-OLEPS] 2.15 TypedPropertyValue */
|
||||
function parse_TypedPropertyValue(blob, type/*:number*/, _opts) {
|
||||
function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
|
||||
var t = blob.read_shift(2), ret, opts = _opts||{};
|
||||
blob.l += 2;
|
||||
if(type !== VT_VARIANT)
|
||||
@ -193,12 +193,12 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]>>>0 & 0xFFFF); break;
|
||||
set_cp(CodePage = (PropH[piddsi.n]>>>0) & 0xFFFF); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
} else {
|
||||
if(Props[i][0] === 0x1) {
|
||||
CodePage = PropH.CodePage = parse_TypedPropertyValue(blob, VT_I2);
|
||||
CodePage = PropH.CodePage = (parse_TypedPropertyValue(blob, VT_I2)/*:number*/);
|
||||
set_cp(CodePage);
|
||||
if(Dictionary !== -1) {
|
||||
var oldpos = blob.l;
|
||||
|
@ -201,7 +201,8 @@ function parse_WriteAccess(blob, length, opts) {
|
||||
return UserName;
|
||||
}
|
||||
function write_WriteAccess(s/*:string*/, opts) {
|
||||
var o = new_buf(112);
|
||||
var b8 = !opts || opts.biff == 8;
|
||||
var o = new_buf(b8 ? 112 : 54);
|
||||
o.write_shift(opts.biff == 8 ? 2 : 1, 7);
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(4, 0x33336853);
|
||||
@ -226,14 +227,15 @@ function parse_BoundSheet8(blob, length, opts) {
|
||||
return { pos:pos, hs:hidden, dt:dt, name:name };
|
||||
}
|
||||
function write_BoundSheet8(data, opts) {
|
||||
var o = new_buf(8 + 2 * data.name.length);
|
||||
var w = (!opts || opts.biff >= 8 ? 2 : 1);
|
||||
var o = new_buf(8 + w * data.name.length);
|
||||
o.write_shift(4, data.pos);
|
||||
o.write_shift(1, data.hs || 0);
|
||||
o.write_shift(1, data.dt);
|
||||
o.write_shift(1, data.name.length);
|
||||
o.write_shift(1, 1);
|
||||
o.write_shift(2 * data.name.length, data.name, 'utf16le');
|
||||
return o;
|
||||
if(opts.biff >= 8) o.write_shift(1, 1);
|
||||
o.write_shift(w * data.name.length, data.name, opts.biff < 8 ? 'sbcs' : 'utf16le');
|
||||
return o.slice(0, o.l);
|
||||
}
|
||||
|
||||
/* 2.4.265 TODO */
|
||||
@ -362,11 +364,12 @@ function parse_Label(blob, length, opts) {
|
||||
return cell;
|
||||
}
|
||||
function write_Label(R/*:number*/, C/*:number*/, v/*:string*/, opts) {
|
||||
var o = new_buf(6 + 3 + 2 * v.length);
|
||||
var b8 = !opts || opts.biff == 8;
|
||||
var o = new_buf(6 + 2 + (+b8) + (1 + b8) * v.length);
|
||||
write_XLSCell(R, C, 0, o);
|
||||
o.write_shift(2, v.length);
|
||||
o.write_shift(1, 1);
|
||||
o.write_shift(2 * v.length, v, 'utf16le');
|
||||
if(b8) o.write_shift(1, 1);
|
||||
o.write_shift((1 + b8) * v.length, v, b8 ? 'utf16le' : 'sbcs');
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -389,9 +392,10 @@ function parse_Dimensions(blob, length, opts) {
|
||||
return {s: {r:r, c:c}, e: {r:R, c:C}};
|
||||
}
|
||||
function write_Dimensions(range, opts) {
|
||||
var o = new_buf(14);
|
||||
o.write_shift(4, range.s.r);
|
||||
o.write_shift(4, range.e.r + 1);
|
||||
var w = opts.biff == 8 || !opts.biff ? 4 : 2;
|
||||
var o = new_buf(2*w + 6);
|
||||
o.write_shift(w, range.s.r);
|
||||
o.write_shift(w, range.e.r + 1);
|
||||
o.write_shift(2, range.s.c);
|
||||
o.write_shift(2, range.e.c + 1);
|
||||
o.write_shift(2, 0);
|
||||
@ -598,7 +602,7 @@ function parse_Lbl(blob, length, opts) {
|
||||
var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||
if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
|
||||
var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
|
||||
var rgce = target == blob.l || cce == 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
var rgce = target == blob.l || cce === 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
return {
|
||||
chKey: chKey,
|
||||
Name: name,
|
||||
|
@ -55,13 +55,14 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
/* header */
|
||||
var ft = d.read_shift(1);
|
||||
var memo = false;
|
||||
var vfp = false;
|
||||
var vfp = false, l7 = false;
|
||||
switch(ft) {
|
||||
case 0x02: case 0x03: break;
|
||||
case 0x30: vfp = true; memo = true; break;
|
||||
case 0x31: vfp = true; break;
|
||||
case 0x83: memo = true; break;
|
||||
case 0x8B: memo = true; break;
|
||||
case 0x8C: memo = true; l7 = true; break;
|
||||
case 0xF5: memo = true; break;
|
||||
default: throw new Error("DBF Unsupported Version: " + ft.toString(16));
|
||||
}
|
||||
@ -84,36 +85,42 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
|
||||
d.l+=2;
|
||||
}
|
||||
if(l7) d.l += 36;
|
||||
var fields = [], field = {};
|
||||
var hend = fpos - 10 - (vfp ? 264 : 0);
|
||||
var hend = fpos - 10 - (vfp ? 264 : 0), ww = l7 ? 32 : 11;
|
||||
while(ft == 0x02 ? d.l < d.length && d[d.l] != 0x0d: d.l < hend) {
|
||||
field = {};
|
||||
field.name = cptable.utils.decode(current_cp, d.slice(d.l, d.l+10)).replace(/[\u0000\r\n].*$/g,"");
|
||||
d.l += 11;
|
||||
field.name = cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)).replace(/[\u0000\r\n].*$/g,"");
|
||||
d.l += ww;
|
||||
field.type = String.fromCharCode(d.read_shift(1));
|
||||
if(ft != 0x02) field.offset = d.read_shift(4);
|
||||
if(ft != 0x02 && !l7) field.offset = d.read_shift(4);
|
||||
field.len = d.read_shift(1);
|
||||
if(ft == 0x02) field.offset = d.read_shift(2);
|
||||
field.dec = d.read_shift(1);
|
||||
if(field.name.length) fields.push(field);
|
||||
if(ft != 0x02) d.l += 14;
|
||||
if(ft != 0x02) d.l += l7 ? 13 : 14;
|
||||
switch(field.type) {
|
||||
// case 'B': break; // Binary
|
||||
case 'C': break; // character
|
||||
case 'D': break; // date
|
||||
case 'F': break; // floating point
|
||||
// case 'G': break; // General
|
||||
case 'I': break; // long
|
||||
case 'L': break; // boolean
|
||||
case 'M': break; // memo
|
||||
case 'N': break; // number
|
||||
// case 'O': break; // double
|
||||
// case 'P': break; // Picture
|
||||
case 'T': break; // datetime
|
||||
case 'Y': break; // currency
|
||||
case '0': break; // null ?
|
||||
case '+': break; // autoincrement
|
||||
case '@': break; // timestamp
|
||||
case 'B': // VFP Double
|
||||
if((!vfp || field.len != 8) && opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
|
||||
break;
|
||||
case 'G': // General
|
||||
case 'P': // Picture
|
||||
if(opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
|
||||
break;
|
||||
case 'C': // character
|
||||
case 'D': // date
|
||||
case 'F': // floating point
|
||||
case 'I': // long
|
||||
case 'L': // boolean
|
||||
case 'M': // memo
|
||||
case 'N': // number
|
||||
case 'O': // double
|
||||
case 'T': // datetime
|
||||
case 'Y': // currency
|
||||
case '0': // VFP _NullFlags
|
||||
case '@': // timestamp
|
||||
case '+': // autoincrement
|
||||
break;
|
||||
default: throw new Error('Unknown Field Type: ' + field.type);
|
||||
}
|
||||
}
|
||||
@ -145,7 +152,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
else out[R][C] = s;
|
||||
break;
|
||||
case 'F': out[R][C] = parseFloat(s.trim()); break;
|
||||
case 'I': out[R][C] = dd.read_shift(4, 'i'); break;
|
||||
case '+': case 'I': out[R][C] = l7 ? dd.read_shift(-4, 'i') ^ 0x80000000 : dd.read_shift(4, 'i'); break;
|
||||
case 'L': switch(s.toUpperCase()) {
|
||||
case 'Y': case 'T': out[R][C] = true; break;
|
||||
case 'N': case 'F': out[R][C] = false; break;
|
||||
@ -154,15 +161,16 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
} break;
|
||||
case 'M': /* TODO: handle memo files */
|
||||
if(!memo) throw new Error("DBF Unexpected MEMO for type " + ft.toString(16));
|
||||
out[R][C] = "##MEMO##" + dd.read_shift(4);
|
||||
out[R][C] = "##MEMO##" + (l7 ? parseInt(s.trim(), 10): dd.read_shift(4));
|
||||
break;
|
||||
case 'N': out[R][C] = +s.replace(/\u0000/g,"").trim(); break;
|
||||
case 'T':
|
||||
var day = dd.read_shift(4), ms = dd.read_shift(4);
|
||||
throw new Error(day + " | " + ms);
|
||||
//out[R][C] = new Date(); // TODO
|
||||
//break;
|
||||
case 'Y': out[R][C] = dd.read(4,'i')/1e4; break;
|
||||
case '@': out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400); break;
|
||||
case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break;
|
||||
case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4; break;
|
||||
case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break;
|
||||
case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; }
|
||||
/* falls through */
|
||||
case 'G': case 'P': dd.l += fields[C].len; break;
|
||||
case '0':
|
||||
if(fields[C].name === '_NullFlags') break;
|
||||
/* falls through */
|
||||
@ -269,7 +277,7 @@ var SYLK = (function() {
|
||||
cw = record[rj].substr(1).split(" ");
|
||||
for(j = parseInt(cw[0], 10); j <= parseInt(cw[1], 10); ++j) {
|
||||
Mval = parseInt(cw[2], 10);
|
||||
colinfo[j-1] = Mval == 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
|
||||
colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
|
||||
} break;
|
||||
case 'C': /* default column format */
|
||||
C = parseInt(record[rj].substr(1))-1;
|
||||
@ -279,7 +287,7 @@ var SYLK = (function() {
|
||||
R = parseInt(record[rj].substr(1))-1;
|
||||
if(!rowinfo[R]) rowinfo[R] = {};
|
||||
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
|
||||
else if(Mval == 0) rowinfo[R].hidden = true;
|
||||
else if(Mval === 0) rowinfo[R].hidden = true;
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
@ -514,16 +522,16 @@ var PRN = (function() {
|
||||
|
||||
// List of accepted CSV separators
|
||||
var guess_seps = {
|
||||
0x2C: ',',
|
||||
0x09: "\t",
|
||||
0x3B: ';'
|
||||
/*::[*/0x2C/*::]*/: ',',
|
||||
/*::[*/0x09/*::]*/: "\t",
|
||||
/*::[*/0x3B/*::]*/: ';'
|
||||
};
|
||||
|
||||
// CSV separator weights to be used in case of equal numbers
|
||||
var guess_sep_weights = {
|
||||
0x2C: 3,
|
||||
0x09: 2,
|
||||
0x3B: 1
|
||||
/*::[*/0x2C/*::]*/: 3,
|
||||
/*::[*/0x09/*::]*/: 2,
|
||||
/*::[*/0x3B/*::]*/: 1
|
||||
};
|
||||
|
||||
function guess_sep(str) {
|
||||
@ -567,9 +575,9 @@ var PRN = (function() {
|
||||
var s = str.slice(start, end);
|
||||
var cell = ({}/*:any*/);
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length == 0) cell.t = 'z';
|
||||
if(s.length === 0) cell.t = 'z';
|
||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length == 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length === 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.charCodeAt(0) == 0x3D) {
|
||||
if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
|
||||
else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
@ -642,7 +650,7 @@ var PRN = (function() {
|
||||
if(!cell || cell.v == null) { oo.push(" "); continue; }
|
||||
var w = (cell.w || (format_cell(cell), cell.w) || "").substr(0,10);
|
||||
while(w.length < 10) w += " ";
|
||||
oo.push(w + (C == 0 ? " " : ""));
|
||||
oo.push(w + (C === 0 ? " " : ""));
|
||||
}
|
||||
o.push(oo.join(""));
|
||||
}
|
||||
|
@ -127,9 +127,9 @@ function parse_EncryptionVerifier(blob, length/*:number*/) {
|
||||
function parse_EncryptionInfo(blob, length/*:?number*/) {
|
||||
var vers = parse_CRYPTOVersion(blob);
|
||||
switch(vers.Minor) {
|
||||
case 0x02: return parse_EncInfoStd(blob, vers);
|
||||
case 0x03: return parse_EncInfoExt(blob, vers);
|
||||
case 0x04: return parse_EncInfoAgl(blob, vers);
|
||||
case 0x02: return [vers.Minor, parse_EncInfoStd(blob, vers)];
|
||||
case 0x03: return [vers.Minor, parse_EncInfoExt(blob, vers)];
|
||||
case 0x04: return [vers.Minor, parse_EncInfoAgl(blob, vers)];
|
||||
}
|
||||
throw new Error("ECMA-376 Encrypted file unrecognized Version: " + vers.Minor);
|
||||
}
|
||||
@ -147,7 +147,10 @@ function parse_EncInfoStd(blob, vers) {
|
||||
/* [MS-OFFCRYPTO] 2.3.4.6 EncryptionInfo Stream (Extensible Encryption) */
|
||||
function parse_EncInfoExt(blob, vers) { throw new Error("File is password-protected: ECMA-376 Extensible"); }
|
||||
/* [MS-OFFCRYPTO] 2.3.4.10 EncryptionInfo Stream (Agile Encryption) */
|
||||
function parse_EncInfoAgl(blob, vers) { throw new Error("File is password-protected: ECMA-376 Agile"); }
|
||||
function parse_EncInfoAgl(blob, vers) {
|
||||
blob.l+=4;
|
||||
return blob.read_shift(blob.length - blob.l, 'utf8');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -282,7 +285,7 @@ function parse_XORObfuscation(blob, length, opts, out) {
|
||||
var o = ({ key: parseuint16(blob), verificationBytes: parseuint16(blob) }/*:any*/);
|
||||
if(opts.password) o.verifier = crypto_CreatePasswordVerifier_Method1(opts.password);
|
||||
out.valid = o.verificationBytes === o.verifier;
|
||||
if(out.valid) out.insitu_decrypt = crypto_MakeXorDecryptor(opts.password);
|
||||
if(out.valid) out.insitu = crypto_MakeXorDecryptor(opts.password);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
172
bits/62_fxls.js
172
bits/62_fxls.js
@ -53,6 +53,13 @@ function parse_RgceLoc_BIFF2(blob, length, opts) {
|
||||
return {r:r[0], c:c, cRel:r[1], rRel:r[2]};
|
||||
}
|
||||
|
||||
/* 2.5.198.107 , 2.5.47 */
|
||||
function parse_RgceElfLoc(blob, length, opts) {
|
||||
var r = blob.read_shift(2);
|
||||
var c = blob.read_shift(2);
|
||||
return {r:r, c:c & 0xFF, fQuoted:!!(c & 0x4000), cRel:c>>15, rRel:c>>15 };
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.198.111 TODO */
|
||||
/* [MS-XLSB] 2.5.97.92 TODO */
|
||||
function parse_RgceLocRel(blob, length, opts) {
|
||||
@ -446,6 +453,51 @@ var parse_PtgMemNoMem = parsenoop;
|
||||
/* 2.5.198.92 */
|
||||
var parse_PtgTbl = parsenoop;
|
||||
|
||||
function parse_PtgElfLoc(blob, length, opts) {
|
||||
blob.l += 2;
|
||||
return [parse_RgceElfLoc(blob, 4, opts)];
|
||||
}
|
||||
function parse_PtgElfNoop(blob, length, opts) {
|
||||
blob.l += 6;
|
||||
return [];
|
||||
}
|
||||
/* 2.5.198.46 */
|
||||
var parse_PtgElfCol = parse_PtgElfLoc;
|
||||
/* 2.5.198.47 */
|
||||
var parse_PtgElfColS = parse_PtgElfNoop;
|
||||
/* 2.5.198.48 */
|
||||
var parse_PtgElfColSV = parse_PtgElfNoop;
|
||||
/* 2.5.198.49 */
|
||||
var parse_PtgElfColV = parse_PtgElfLoc;
|
||||
/* 2.5.198.50 */
|
||||
function parse_PtgElfLel(blob, length, opts) {
|
||||
blob.l += 2;
|
||||
return [parseuint16(blob), blob.read_shift(2) & 0x01];
|
||||
}
|
||||
/* 2.5.198.51 */
|
||||
var parse_PtgElfRadical = parse_PtgElfLoc;
|
||||
/* 2.5.198.52 */
|
||||
var parse_PtgElfRadicalLel = parse_PtgElfLel;
|
||||
/* 2.5.198.53 */
|
||||
var parse_PtgElfRadicalS = parse_PtgElfNoop;
|
||||
/* 2.5.198.54 */
|
||||
var parse_PtgElfRw = parse_PtgElfLoc;
|
||||
/* 2.5.198.55 */
|
||||
var parse_PtgElfRwV = parse_PtgElfLoc;
|
||||
|
||||
/* [MS-XLSB] 2.5.97.52 */
|
||||
function parse_PtgList(blob, length, opts) {
|
||||
blob.l += 2;
|
||||
var ixti = blob.read_shift(2);
|
||||
blob.l += 10;
|
||||
return {};
|
||||
}
|
||||
/* 2.5.198.91 */
|
||||
function parse_PtgSxName(blob, length, opts) {
|
||||
blob.l += 2;
|
||||
return [blob.read_shift(4)];
|
||||
}
|
||||
|
||||
/* 2.5.198.25 */
|
||||
var PtgTypes = {
|
||||
/*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp },
|
||||
@ -521,8 +573,19 @@ var PtgDupes = {
|
||||
(function(){for(var y in PtgDupes) PtgTypes[y] = PtgTypes[PtgDupes[y]];})();
|
||||
|
||||
var Ptg18 = {
|
||||
// /*::[*/0x19/*::]*/: { n:'PtgList', f:parse_PtgList }, // TODO
|
||||
// /*::[*/0x1D/*::]*/: { n:'PtgSxName', f:parse_PtgSxName }, // TODO
|
||||
/*::[*/0x01/*::]*/: { n:'PtgElfLel', f:parse_PtgElfLel },
|
||||
/*::[*/0x02/*::]*/: { n:'PtgElfRw', f:parse_PtgElfRw },
|
||||
/*::[*/0x03/*::]*/: { n:'PtgElfCol', f:parse_PtgElfCol },
|
||||
/*::[*/0x06/*::]*/: { n:'PtgElfRwV', f:parse_PtgElfRwV },
|
||||
/*::[*/0x07/*::]*/: { n:'PtgElfColV', f:parse_PtgElfColV },
|
||||
/*::[*/0x0A/*::]*/: { n:'PtgElfRadical', f:parse_PtgElfRadical },
|
||||
/*::[*/0x0B/*::]*/: { n:'PtgElfRadicalS', f:parse_PtgElfRadicalS },
|
||||
/*::[*/0x0D/*::]*/: { n:'PtgElfColS', f:parse_PtgElfColS },
|
||||
/*::[*/0x0F/*::]*/: { n:'PtgElfColSV', f:parse_PtgElfColSV },
|
||||
/*::[*/0x10/*::]*/: { n:'PtgElfRadicalLel', f:parse_PtgElfRadicalLel },
|
||||
/*::[*/0x19/*::]*/: { n:'PtgList', f:parse_PtgList },
|
||||
/*::[*/0x1D/*::]*/: { n:'PtgSxName', f:parse_PtgSxName },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
};
|
||||
var Ptg19 = {
|
||||
/*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
|
||||
@ -536,36 +599,7 @@ var Ptg19 = {
|
||||
/*::[*/0x80/*::]*/: { n:'PtgAttrIfError', f:parse_PtgAttrIfError },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
};
|
||||
|
||||
/* 2.4.127 TODO */
|
||||
function parse_Formula(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var cell = parse_XLSCell(blob, 6);
|
||||
if(opts.biff == 2) ++blob.l;
|
||||
var val = parse_FormulaValue(blob,8);
|
||||
var flags = blob.read_shift(1);
|
||||
if(opts.biff != 2) {
|
||||
blob.read_shift(1);
|
||||
if(opts.biff >= 5) {
|
||||
var chn = blob.read_shift(4);
|
||||
}
|
||||
}
|
||||
var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
|
||||
return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
|
||||
}
|
||||
|
||||
/* 2.5.133 TODO: how to emit empty strings? */
|
||||
function parse_FormulaValue(blob/*::, length*/) {
|
||||
var b;
|
||||
if(__readUInt16LE(blob,blob.l + 6) !== 0xFFFF) return [parse_Xnum(blob),'n'];
|
||||
switch(blob[blob.l]) {
|
||||
case 0x00: blob.l += 8; return ["String", 's'];
|
||||
case 0x01: b = blob[blob.l+2] === 0x1; blob.l += 8; return [b,'b'];
|
||||
case 0x02: b = blob[blob.l+2]; blob.l += 8; return [b,'e'];
|
||||
case 0x03: blob.l += 8; return ["",'s'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
Ptg19[0x21] = Ptg19[0x20];
|
||||
|
||||
/* 2.5.198.103 */
|
||||
function parse_RgbExtra(blob, length, rgce, opts) {
|
||||
@ -587,6 +621,11 @@ function parse_RgbExtra(blob, length, rgce, opts) {
|
||||
rgce[i][1][1] = blob.read_shift(4);
|
||||
o.push(rgce[i][1]);
|
||||
} break;
|
||||
case 'PtgList': /* TODO: PtgList -> PtgExtraList */
|
||||
case 'PtgElfRadicalS': /* TODO: PtgElfRadicalS -> PtgExtraElf */
|
||||
case 'PtgElfColS': /* TODO: PtgElfColS -> PtgExtraElf */
|
||||
case 'PtgElfColSV': /* TODO: PtgElfColSV -> PtgExtraElf */
|
||||
throw "Unsupported " + rgce[i][0];
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -597,45 +636,6 @@ function parse_RgbExtra(blob, length, rgce, opts) {
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.5.198.21 */
|
||||
function parse_NameParsedFormula(blob, length, opts, cce) {
|
||||
var target = blob.l + length;
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
var rgcb;
|
||||
if(target !== blob.l) rgcb = parse_RgbExtra(blob, target - blob.l, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* 2.5.198.3 TODO */
|
||||
function parse_XLSCellParsedFormula(blob, length, opts) {
|
||||
var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
|
||||
var rgcb, cce = blob.read_shift(len); // length of rgce
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* 2.5.198.118 TODO */
|
||||
function parse_SharedParsedFormula(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var rgcb, cce = blob.read_shift(2); // length of rgce
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
if(length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* 2.5.198.1 TODO */
|
||||
function parse_ArrayParsedFormula(blob, length, opts, ref) {
|
||||
var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
|
||||
var rgcb, cce = blob.read_shift(len); // length of rgce
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* 2.5.198.104 */
|
||||
function parse_Rgce(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
@ -655,7 +655,7 @@ function parse_Rgce(blob, length, opts) {
|
||||
return ptgs;
|
||||
}
|
||||
|
||||
function stringify_array(f)/*:string*/ {
|
||||
function stringify_array(f/*:Array<Array<any>>*/)/*:string*/ {
|
||||
var o = [];
|
||||
for(var i = 0; i < f.length; ++i) {
|
||||
var x = f[i], r = [];
|
||||
@ -702,15 +702,12 @@ function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
|
||||
return formula_quote_sheet_name(get_ixti_raw(supbooks, ixti, opts));
|
||||
}
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts)/*:string*/ {
|
||||
//console.log(formula);
|
||||
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
|
||||
var stack/*:Array<string>*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname="";
|
||||
if(!formula[0] || !formula[0][0]) return "";
|
||||
var last_sp = -1, sp = "";
|
||||
//console.log("--",cell,formula[0])
|
||||
for(var ff = 0, fflen = formula[0].length; ff < fflen; ++ff) {
|
||||
var f = formula[0][ff];
|
||||
//console.log("++",f, stack)
|
||||
switch(f[0]) {
|
||||
case 'PtgUminus': /* 2.5.198.93 */
|
||||
stack.push("-" + stack.pop()); break;
|
||||
@ -791,7 +788,6 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
|
||||
case 'PtgFunc': /* 2.5.198.62 */
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc/*:number*/ = (f[1][0]/*:any*/), func/*:string*/ = (f[1][1]/*:any*/);
|
||||
if(!argc) argc = 0;
|
||||
@ -845,7 +841,6 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
/* f[1] = type, ixti, nameindex */
|
||||
var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook;
|
||||
/* TODO: Properly handle missing values */
|
||||
//console.log(bookidx, supbooks);
|
||||
if(opts.biff <= 5) {
|
||||
if(bookidx < 0) bookidx = -bookidx;
|
||||
if(supbooks[bookidx]) externbook = supbooks[bookidx][nameidx];
|
||||
@ -949,6 +944,27 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
|
||||
case 'PtgMemFunc': /* 2.5.198.72 TODO */
|
||||
break;
|
||||
case 'PtgMemNoMem': /* 2.5.198.73 TODO -- find a test case */
|
||||
throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
|
||||
case 'PtgElfCol': /* 2.5.198.46 */
|
||||
case 'PtgElfColS': /* 2.5.198.47 */
|
||||
case 'PtgElfColSV': /* 2.5.198.48 */
|
||||
case 'PtgElfColV': /* 2.5.198.49 */
|
||||
case 'PtgElfLel': /* 2.5.198.50 */
|
||||
case 'PtgElfRadical': /* 2.5.198.51 */
|
||||
case 'PtgElfRadicalLel': /* 2.5.198.52 */
|
||||
case 'PtgElfRadicalS': /* 2.5.198.53 */
|
||||
case 'PtgElfRw': /* 2.5.198.54 */
|
||||
case 'PtgElfRwV': /* 2.5.198.55 */
|
||||
throw new Error("Unsupported ELFs");
|
||||
|
||||
case 'PtgAttrBaxcel': /* 2.5.198.33 TODO -- find a test case*/
|
||||
throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
case 'PtgSxName': /* 2.5.198.91 TODO -- find a test case */
|
||||
throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
case 'PtgList': /* [MS-XLSB] 2.5.97.52 TODO -- find a test case */
|
||||
throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
|
||||
default: throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
}
|
||||
@ -976,9 +992,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
stack.push((_left ? sp : "") + stack.pop() + (_left ? "" : sp));
|
||||
last_sp = -1;
|
||||
}
|
||||
//console.log("::",f, stack)
|
||||
}
|
||||
//console.log("--",stack);
|
||||
if(stack.length > 1 && opts.WTF) throw new Error("bad formula stack");
|
||||
return stack[0];
|
||||
}
|
||||
|
@ -1,3 +1,72 @@
|
||||
/* [MS-XLS] 2.5.198.1 TODO */
|
||||
function parse_ArrayParsedFormula(blob, length, opts, ref) {
|
||||
var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
|
||||
var rgcb, cce = blob.read_shift(len); // length of rgce
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.198.3 TODO */
|
||||
function parse_XLSCellParsedFormula(blob, length, opts) {
|
||||
var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
|
||||
var rgcb, cce = blob.read_shift(len); // length of rgce
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.198.21 */
|
||||
function parse_NameParsedFormula(blob, length, opts, cce) {
|
||||
var target = blob.l + length;
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
var rgcb;
|
||||
if(target !== blob.l) rgcb = parse_RgbExtra(blob, target - blob.l, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.198.118 TODO */
|
||||
function parse_SharedParsedFormula(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var rgcb, cce = blob.read_shift(2); // length of rgce
|
||||
var rgce = parse_Rgce(blob, cce, opts);
|
||||
if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
|
||||
if(length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts);
|
||||
return [rgce, rgcb];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.133 TODO: how to emit empty strings? */
|
||||
function parse_FormulaValue(blob/*::, length*/) {
|
||||
var b;
|
||||
if(__readUInt16LE(blob,blob.l + 6) !== 0xFFFF) return [parse_Xnum(blob),'n'];
|
||||
switch(blob[blob.l]) {
|
||||
case 0x00: blob.l += 8; return ["String", 's'];
|
||||
case 0x01: b = blob[blob.l+2] === 0x1; blob.l += 8; return [b,'b'];
|
||||
case 0x02: b = blob[blob.l+2]; blob.l += 8; return [b,'e'];
|
||||
case 0x03: blob.l += 8; return ["",'s'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.4.127 TODO */
|
||||
function parse_Formula(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var cell = parse_XLSCell(blob, 6);
|
||||
if(opts.biff == 2) ++blob.l;
|
||||
var val = parse_FormulaValue(blob,8);
|
||||
var flags = blob.read_shift(1);
|
||||
if(opts.biff != 2) {
|
||||
blob.read_shift(1);
|
||||
if(opts.biff >= 5) {
|
||||
var chn = blob.read_shift(4);
|
||||
}
|
||||
}
|
||||
var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
|
||||
return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
|
||||
}
|
||||
|
||||
/* XLSB Parsed Formula records have the same shape */
|
||||
function parse_XLSBParsedFormula(data, length, opts) {
|
||||
var end = data.l + length;
|
||||
|
@ -81,7 +81,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh
|
||||
}
|
||||
|
||||
function write_ws_xml_merges(merges) {
|
||||
if(merges.length == 0) return "";
|
||||
if(merges.length === 0) return "";
|
||||
var o = '<mergeCells count="' + merges.length + '">';
|
||||
for(var i = 0; i != merges.length; ++i) o += '<mergeCell ref="' + encode_range(merges[i]) + '"/>';
|
||||
return o + '</mergeCells>';
|
||||
@ -196,6 +196,7 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
|
||||
case 'd':
|
||||
if(opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
|
||||
else {
|
||||
cell = dup(cell);
|
||||
cell.t = 'n';
|
||||
vv = ''+(cell.v = datenum(parseDate(cell.v)));
|
||||
}
|
||||
@ -384,6 +385,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R=0, C=0, rows = ws['!rows'];
|
||||
var dense = Array.isArray(ws);
|
||||
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
|
||||
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||
for(R = range.s.r; R <= range.e.r; ++R) {
|
||||
r = [];
|
||||
@ -395,11 +397,11 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
||||
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||
}
|
||||
if(r.length > 0 || rows && rows[R]) {
|
||||
var params = ({r:rr}/*:any*/);
|
||||
params = ({r:rr}/*:any*/);
|
||||
if(rows && rows[R]) {
|
||||
var row = rows[R];
|
||||
row = rows[R];
|
||||
if(row.hidden) params.hidden = 1;
|
||||
var height = -1;
|
||||
height = -1;
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
|
@ -261,7 +261,9 @@ function parse_BrtHLink(data, length, opts) {
|
||||
var tooltip = parse_XLWideString(data);
|
||||
var display = parse_XLWideString(data);
|
||||
data.l = end;
|
||||
return {rfx:rfx, relId:relId, loc:loc, Tooltip:tooltip, display:display};
|
||||
var o = ({rfx:rfx, relId:relId, loc:loc, display:display}/*:any*/);
|
||||
if(tooltip) o.Tooltip = tooltip;
|
||||
return o;
|
||||
}
|
||||
function write_BrtHLink(l, rId, o) {
|
||||
if(o == null) o = new_buf(50+4*l[1].Target.length);
|
||||
@ -319,25 +321,16 @@ function write_BrtColInfo(C/*:number*/, col, o) {
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.672 BrtMargins */
|
||||
function parse_BrtMargins(data, length, opts) {
|
||||
return {
|
||||
left: parse_Xnum(data, 8),
|
||||
right: parse_Xnum(data, 8),
|
||||
top: parse_Xnum(data, 8),
|
||||
bottom: parse_Xnum(data, 8),
|
||||
header: parse_Xnum(data, 8),
|
||||
footer: parse_Xnum(data, 8)
|
||||
};
|
||||
var BrtMarginKeys = ["left","right","top","bottom","header","footer"];
|
||||
function parse_BrtMargins(data, length, opts)/*:Margins*/ {
|
||||
var margins = ({}/*:any*/);
|
||||
BrtMarginKeys.forEach(function(k) { margins[k] = parse_Xnum(data, 8); });
|
||||
return margins;
|
||||
}
|
||||
function write_BrtMargins(margins, o) {
|
||||
function write_BrtMargins(margins/*:Margins*/, o) {
|
||||
if(o == null) o = new_buf(6*8);
|
||||
default_margins(margins);
|
||||
write_Xnum(margins.left, o);
|
||||
write_Xnum(margins.right, o);
|
||||
write_Xnum(margins.top, o);
|
||||
write_Xnum(margins.bottom, o);
|
||||
write_Xnum(margins.header, o);
|
||||
write_Xnum(margins.footer, o);
|
||||
BrtMarginKeys.forEach(function(k) { write_Xnum((margins/*:any*/)[k], o); });
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -641,13 +634,13 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
/* TODO: something useful -- this is a stub */
|
||||
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/) {
|
||||
if(cell.v === undefined) return "";
|
||||
var vv = ""; var olddate = null;
|
||||
var vv = "";
|
||||
switch(cell.t) {
|
||||
case 'b': vv = cell.v ? "1" : "0"; break;
|
||||
case 'd': // no BrtCellDate :(
|
||||
cell = dup(cell);
|
||||
cell.z = cell.z || SSF._table[14];
|
||||
olddate = cell.v;
|
||||
cell.v = datenum((cell.v/*:any*/)); cell.t = 'n';
|
||||
cell.v = datenum(parseDate(cell.v)); cell.t = 'n';
|
||||
break;
|
||||
/* falls through */
|
||||
case 'n': case 'e': vv = ''+cell.v; break;
|
||||
@ -673,7 +666,6 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
||||
/* TODO: determine threshold for Real vs RK */
|
||||
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) write_record(ba, "BrtCellRk", write_BrtCellRk(cell, o));
|
||||
else write_record(ba, "BrtCellReal", write_BrtCellReal(cell, o));
|
||||
if(olddate) { cell.t = 'd'; cell.v = olddate; }
|
||||
return;
|
||||
case 'b':
|
||||
o.t = "b";
|
||||
|
@ -196,7 +196,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
var comments = [], comment = {};
|
||||
var cstys = [], csty, seencol = false;
|
||||
var arrayf = [];
|
||||
var rowinfo = [], rowobj = {};
|
||||
var rowinfo = [], rowobj = {}, cc = 0, rr = 0;
|
||||
var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false} }/*:any*/), wsprops = {};
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"");
|
||||
@ -220,8 +220,8 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
delete cell.HRef; delete cell.HRefScreenTip;
|
||||
}
|
||||
if(cell.MergeAcross || cell.MergeDown) {
|
||||
var cc = c + (parseInt(cell.MergeAcross,10)|0);
|
||||
var rr = r + (parseInt(cell.MergeDown,10)|0);
|
||||
cc = c + (parseInt(cell.MergeAcross,10)|0);
|
||||
rr = r + (parseInt(cell.MergeDown,10)|0);
|
||||
mergecells.push({s:{c:c,r:r},e:{c:cc,r:rr}});
|
||||
}
|
||||
if(!opts.sheetStubs) { if(cell.MergeAcross) c = cc + 1; else ++c; }
|
||||
|
@ -38,11 +38,11 @@ function slurp(R, blob, length/*:number*/, opts) {
|
||||
var l = length;
|
||||
var bufs = [];
|
||||
var d = blob.slice(blob.l,blob.l+l);
|
||||
if(opts && opts.enc && opts.enc.insitu_decrypt) switch(R.n) {
|
||||
if(opts && opts.enc && opts.enc.insitu) switch(R.n) {
|
||||
case 'BOF': case 'FilePass': case 'FileLock': case 'InterfaceHdr': case 'RRDInfo': case 'RRDHead': case 'UsrExcl': break;
|
||||
default:
|
||||
if(d.length === 0) break;
|
||||
opts.enc.insitu_decrypt(d);
|
||||
opts.enc.insitu(d);
|
||||
}
|
||||
bufs.push(d);
|
||||
blob.l += l;
|
||||
|
@ -38,7 +38,7 @@ function write_BIFF2LABEL(r/*:number*/, c/*:number*/, val) {
|
||||
function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
||||
if(cell.v != null) switch(cell.t) {
|
||||
case 'd': case 'n':
|
||||
var v = cell.t == 'd' ? datenum(cell.v) : cell.v;
|
||||
var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
|
||||
if((v == (v|0)) && (v >= 0) && (v < 65536))
|
||||
write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v));
|
||||
else
|
||||
@ -88,7 +88,7 @@ function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
||||
if(cell.v != null) switch(cell.t) {
|
||||
case 'd': case 'n':
|
||||
var v = cell.t == 'd' ? datenum(cell.v) : cell.v;
|
||||
var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
|
||||
/* TODO: emit RK as appropriate */
|
||||
write_biff_rec(ba, "Number", write_Number(R, C, v, opts));
|
||||
return;
|
||||
@ -148,16 +148,16 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
|
||||
var A = buf_array();
|
||||
var b8 = opts.biff == 8, b5 = opts.biff == 5;
|
||||
write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts));
|
||||
write_biff_rec(A, "InterfaceHdr", writeuint16(0x04b0));
|
||||
write_biff_rec(A, "InterfaceHdr", b8 ? writeuint16(0x04b0) : null);
|
||||
write_biff_rec(A, "Mms", writezeroes(2));
|
||||
if(b5) write_biff_rec(A, "ToolbarHdr");
|
||||
if(b5) write_biff_rec(A, "ToolbarEnd");
|
||||
write_biff_rec(A, "InterfaceEnd");
|
||||
write_biff_rec(A, "WriteAccess", write_WriteAccess("SheetJS", opts));
|
||||
write_biff_rec(A, "CodePage", writeuint16(0x04b0));
|
||||
write_biff_rec(A, "CodePage", writeuint16(b8 ? 0x04b0 : 0x04E4));
|
||||
if(b8) write_biff_rec(A, "DSF", writeuint16(0));
|
||||
if(b8) write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length));
|
||||
if(b8) write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11));
|
||||
write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length));
|
||||
write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11));
|
||||
write_biff_rec(A, "WinProtect", writebool(false));
|
||||
write_biff_rec(A, "Protect", writebool(false));
|
||||
write_biff_rec(A, "Password", writeuint16(0));
|
||||
@ -168,21 +168,21 @@ function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
|
||||
write_biff_rec(A, "HideObj", writeuint16(0));
|
||||
write_biff_rec(A, "Date1904", writebool(safe1904(wb)=="true"));
|
||||
write_biff_rec(A, "CalcPrecision", writebool(true));
|
||||
write_biff_rec(A, "RefreshAll", writebool(false));
|
||||
if(b8) write_biff_rec(A, "RefreshAll", writebool(false));
|
||||
write_biff_rec(A, "BookBool", writeuint16(0));
|
||||
/* ... */
|
||||
write_biff_rec(A, "UsesELFs", writebool(false));
|
||||
if(b8) write_biff_rec(A, "UsesELFs", writebool(false));
|
||||
var a = A.end();
|
||||
|
||||
var C = buf_array();
|
||||
write_biff_rec(C, "Country", write_Country());
|
||||
if(b8) write_biff_rec(C, "Country", write_Country());
|
||||
/* BIFF8: [SST *Continue] ExtSST */
|
||||
write_biff_rec(C, "EOF");
|
||||
var c = C.end();
|
||||
|
||||
var B = buf_array();
|
||||
var blen = 0, j = 0;
|
||||
for(j = 0; j < wb.SheetNames.length; ++j) blen += 12 + (b8 ? 2 : 1) * wb.SheetNames[j].length;
|
||||
for(j = 0; j < wb.SheetNames.length; ++j) blen += (b8 ? 12 : 11) + (b8 ? 2 : 1) * wb.SheetNames[j].length;
|
||||
var start = a.length + blen + c.length;
|
||||
for(j = 0; j < wb.SheetNames.length; ++j) {
|
||||
write_biff_rec(B, "BoundSheet8", write_BoundSheet8({pos:start, hs:0, dt:0, name:wb.SheetNames[j]}, opts));
|
||||
|
@ -1,20 +1,31 @@
|
||||
/* OpenDocument */
|
||||
var parse_content_xml = (function() {
|
||||
|
||||
var parse_text_p = function(text, tag) {
|
||||
return unescapexml(text.replace(/<text:s\/>/g," ").replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1)+1).join(" "); }).replace(/<[^>]*>/g,""));
|
||||
/* 6.1.2 White Space Characters */
|
||||
var parse_text_p = function(text/*:string*/, tag)/*:string*/ {
|
||||
return unescapexml(text
|
||||
.replace(/[\t\r\n]/g, " ").trim().replace(/ +/g, " ")
|
||||
.replace(/<text:s\/>/g," ")
|
||||
.replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
|
||||
.replace(/<text:tab[^>]*\/>/g,"\t")
|
||||
.replace(/<text:line-break\/>/g,"\n")
|
||||
.replace(/<[^>]*>/g,"")
|
||||
);
|
||||
};
|
||||
|
||||
var number_formats = {
|
||||
/* ods name: [short ssf fmt, long ssf fmt] */
|
||||
day: ["d", "dd"],
|
||||
month: ["m", "mm"],
|
||||
year: ["y", "yy"],
|
||||
hours: ["h", "hh"],
|
||||
minutes: ["m", "mm"],
|
||||
seconds: ["s", "ss"],
|
||||
"am-pm": ["A/P", "AM/PM"],
|
||||
"day-of-week": ["ddd", "dddd"]
|
||||
day: ["d", "dd"],
|
||||
month: ["m", "mm"],
|
||||
year: ["y", "yy"],
|
||||
hours: ["h", "hh"],
|
||||
minutes: ["m", "mm"],
|
||||
seconds: ["s", "ss"],
|
||||
"am-pm": ["A/P", "AM/PM"],
|
||||
"day-of-week": ["ddd", "dddd"],
|
||||
era: ["e", "ee"],
|
||||
/* there is no native representation of LO "Q" format */
|
||||
quarter: ["\\Qm", "m\\\"th quarter\""]
|
||||
};
|
||||
|
||||
return function pcx(d/*:string*/, _opts)/*:Workbook*/ {
|
||||
@ -29,15 +40,17 @@ var parse_content_xml = (function() {
|
||||
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
|
||||
var ws = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
|
||||
var Rn, q/*:: = ({t:"", v:null, z:null, w:"",c:[]}:any)*/;
|
||||
var ctag = {value:""};
|
||||
var ctag = ({value:""}/*:any*/);
|
||||
var textp = "", textpidx = 0, textptag/*:: = {}*/;
|
||||
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
|
||||
var row_ol = 0;
|
||||
var number_format_map = {};
|
||||
var merges = [], mrange = {}, mR = 0, mC = 0;
|
||||
var rowinfo = [], rowpeat = 1, colpeat = 1;
|
||||
var arrayf = [];
|
||||
var comments = [], comment = {};
|
||||
var creator = "", creatoridx = 0;
|
||||
var rept = 1, isstub = false;
|
||||
var isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
@ -47,6 +60,7 @@ var parse_content_xml = (function() {
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
if(rowinfo.length) ws["!rows"] = rowinfo;
|
||||
sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
@ -56,13 +70,20 @@ var parse_content_xml = (function() {
|
||||
R = C = -1;
|
||||
range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0;
|
||||
ws = opts.dense ? ([]/*:any*/) : ({}/*:any*/); merges = [];
|
||||
rowinfo = [];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table-row-group': // 9.1.9 <table:table-row-group>
|
||||
if(Rn[1] === "/") --row_ol; else ++row_ol;
|
||||
break;
|
||||
case 'table-row': case '行': // 9.1.3 <table:table-row>
|
||||
if(Rn[1] === '/') break;
|
||||
if(Rn[1] === '/') { R+=rowpeat; rowpeat = 1; break; }
|
||||
rowtag = parsexmltag(Rn[0], false);
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else ++R;
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else if(R == -1) R = 0;
|
||||
rowpeat = +rowtag['number-rows-repeated'] || 1;
|
||||
/* TODO: remove magic */
|
||||
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
|
||||
C = -1; break;
|
||||
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
|
||||
++C;
|
||||
@ -73,13 +94,24 @@ var parse_content_xml = (function() {
|
||||
break; /* stub */
|
||||
case 'table-cell': case '数据':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
else ++C;
|
||||
}
|
||||
else if(Rn[1]!=='/') {
|
||||
++C;
|
||||
rept = 1;
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
|
||||
q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
|
||||
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
|
||||
if((ctag['数据类型'] || ctag['value-type']) == "string") {
|
||||
q.t = "s"; q.v = unescapexml(ctag['string-value'] || "");
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = q;
|
||||
} else {
|
||||
ws[encode_cell({r:R,c:C})] = q;
|
||||
}
|
||||
}
|
||||
C+= colpeat-1;
|
||||
} else if(Rn[1]!=='/') {
|
||||
++C;
|
||||
colpeat = 1;
|
||||
if(C > range.e.c) range.e.c = C;
|
||||
if(R > range.e.r) range.e.r = R;
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
@ -110,7 +142,7 @@ var parse_content_xml = (function() {
|
||||
}
|
||||
|
||||
/* 19.675.2 table:number-columns-repeated */
|
||||
if(ctag['number-columns-repeated']) rept = parseInt(ctag['number-columns-repeated'], 10);
|
||||
if(ctag['number-columns-repeated']) colpeat = parseInt(ctag['number-columns-repeated'], 10);
|
||||
|
||||
/* 19.385 office:value-type */
|
||||
switch(q.t) {
|
||||
@ -139,17 +171,22 @@ var parse_content_xml = (function() {
|
||||
if(textp && opts.cellText !== false) q.w = textp;
|
||||
if(!isstub || opts.sheetStubs) {
|
||||
if(!(opts.sheetRows && opts.sheetRows < R)) {
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = q;
|
||||
while(--rept > 0) ws[R][++C] = dup(q);
|
||||
} else {
|
||||
ws[encode_cell({r:R,c:C})] = q;
|
||||
while(--rept > 0) ws[encode_cell({r:R,c:++C})] = dup(q);
|
||||
for(var rpt = 0; rpt < rowpeat; ++rpt) {
|
||||
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
|
||||
if(opts.dense) {
|
||||
if(!ws[R + rpt]) ws[R + rpt] = [];
|
||||
ws[R + rpt][C] = rpt == 0 ? q : dup(q);
|
||||
while(--colpeat > 0) ws[R + rpt][C + colpeat] = dup(q);
|
||||
} else {
|
||||
ws[encode_cell({r:R + rpt,c:C})] = q;
|
||||
while(--colpeat > 0) ws[encode_cell({r:R + rpt,c:C + colpeat})] = dup(q);
|
||||
}
|
||||
if(range.e.c <= C) range.e.c = C;
|
||||
}
|
||||
if(range.e.c <= C) range.e.c = C;
|
||||
}
|
||||
} else { C += rept; rept = 0; }
|
||||
}
|
||||
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
|
||||
C += colpeat-1; colpeat = 0;
|
||||
q = {/*:: t:"", v:null, z:null, w:"",c:[]*/};
|
||||
textp = "";
|
||||
}
|
||||
@ -199,6 +236,7 @@ var parse_content_xml = (function() {
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'event-listeners': // TODO
|
||||
case 'chart': // TODO
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
textp = ""; textpidx = 0;
|
||||
@ -226,7 +264,7 @@ var parse_content_xml = (function() {
|
||||
case 'script': break; // 3.13 <office:script>
|
||||
case 'libraries': break; // TODO: <ooo:libraries>
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:master-styles>
|
||||
|
||||
case 'default-style': // TODO: <style:default-style>
|
||||
case 'page-layout': break; // TODO: <style:page-layout>
|
||||
@ -284,16 +322,18 @@ var parse_content_xml = (function() {
|
||||
break;
|
||||
case 'text-content': break; // 16.27.27 <number:text-content>
|
||||
case 'text-properties': break; // 16.27.27 <style:text-properties>
|
||||
case 'embedded-text': break; // 16.27.4 <number:embedded-text>
|
||||
|
||||
case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
case 'table-header-rows': break; // 9.1.7 <table:table-header-rows>
|
||||
case 'table-rows': break; // 9.1.12 <table:table-rows>
|
||||
/* TODO: outline levels */
|
||||
case 'table-row-group': break; // 9.1.9 <table:table-row-group>
|
||||
case 'table-column-group': break; // 9.1.10 <table:table-column-group>
|
||||
case 'table-header-columns': break; // 9.1.11 <table:table-header-columns>
|
||||
case 'table-columns': break; // 9.1.12 <table:table-columns>
|
||||
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
@ -312,9 +352,10 @@ var parse_content_xml = (function() {
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'span': break; // 6.1.7 <text:span>
|
||||
case 'p': case '文本串': // 5.1.3 <text:p>
|
||||
if(Rn[1]==='/') textp = (textp.length > 0 ? textp + "\n" : "") + parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
if(Rn[1]==='/' && (!ctag || !ctag['string-value'])) textp = (textp.length > 0 ? textp + "\n" : "") + parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
case 's': break; // <text:s>
|
||||
|
||||
case 'database-range': // 9.4.15 <table:database-range>
|
||||
if(Rn[1]==='/') break;
|
||||
@ -324,12 +365,12 @@ var parse_content_xml = (function() {
|
||||
} catch(e) {/* empty */}
|
||||
break;
|
||||
|
||||
case 's': break; // <text:s>
|
||||
case 'date': break; // <*:date>
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': case '标题': break; // <*:title> OR <uof:标题>
|
||||
case 'desc': break; // <*:desc>
|
||||
case 'binary-data': break; // 10.4.5 TODO: b64 blob
|
||||
|
||||
/* 9.2 Advanced Tables */
|
||||
case 'table-source': break; // 9.2.6
|
||||
@ -379,9 +420,12 @@ var parse_content_xml = (function() {
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creation-date':
|
||||
case 'print-date':
|
||||
case 'generator':
|
||||
case 'document-statistic':
|
||||
case 'user-defined':
|
||||
case 'editing-duration':
|
||||
case 'editing-cycles':
|
||||
break;
|
||||
|
||||
/* TODO: FODS Config */
|
||||
@ -438,27 +482,33 @@ var parse_content_xml = (function() {
|
||||
case 'table-protection': break;
|
||||
case 'data-pilot-grand-total': break; // <table:
|
||||
case 'office-document-common-attrs': break; // bare
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'style:') break; // TODO: styles
|
||||
if(Rn[2] === 'form:') break; // TODO: forms
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'loext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw new Error(Rn);
|
||||
default: switch(Rn[2]) {
|
||||
case 'dc:': // TODO: properties
|
||||
case 'calcext:': // ignore undocumented extensions
|
||||
case 'loext:': // ignore undocumented extensions
|
||||
case 'ooo:': // ignore undocumented extensions
|
||||
case 'chartooo:': // ignore undocumented extensions
|
||||
case 'draw:': // TODO: drawing
|
||||
case 'style:': // TODO: styles
|
||||
case 'chart:': // TODO: charts
|
||||
case 'form:': // TODO: forms
|
||||
case 'uof:': // TODO: uof
|
||||
case '表:': // TODO: uof
|
||||
case '字:': // TODO: uof
|
||||
break;
|
||||
default: if(opts.WTF) throw new Error(Rn);
|
||||
}
|
||||
}
|
||||
var out = {
|
||||
Sheets: Sheets,
|
||||
SheetNames: SheetNames
|
||||
};
|
||||
if(opts.bookSheets) delete out.Sheets;
|
||||
return out;
|
||||
};
|
||||
})();
|
||||
|
||||
function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
opts = opts || ({}/*:any*/);
|
||||
var ods = !!safegetzipfile(zip, 'objectdata');
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
@ -468,7 +518,7 @@ function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
|
||||
return wb;
|
||||
}
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/) {
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
return parse_content_xml(data, opts);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,36 @@
|
||||
/* OpenDocument */
|
||||
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
var payload = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><office:document-styles xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" office:version="1.2"></office:document-styles>';
|
||||
var payload = '<office:document-styles ' + wxt_helper({
|
||||
'xmlns:office': "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
|
||||
'xmlns:table': "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
|
||||
'xmlns:style': "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
|
||||
'xmlns:text': "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
|
||||
'xmlns:draw': "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
|
||||
'xmlns:fo': "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
|
||||
'xmlns:xlink': "http://www.w3.org/1999/xlink",
|
||||
'xmlns:dc': "http://purl.org/dc/elements/1.1/",
|
||||
'xmlns:number': "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
|
||||
'xmlns:svg': "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
|
||||
'xmlns:of': "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
|
||||
'office:version': "1.2"
|
||||
}) + '></office:document-styles>';
|
||||
return function wso(wb, opts) {
|
||||
return payload;
|
||||
return XML_HEADER + payload;
|
||||
};
|
||||
})();
|
||||
var write_content_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
/* 6.1.2 White Space Characters */
|
||||
var write_text_p = function(text/*:string*/)/*:string*/ {
|
||||
return escapexml(text)
|
||||
.replace(/ +/g, function($$){return '<text:s text:c="'+$$.length+'"/>';})
|
||||
.replace(/\t/g, "<text:tab/>")
|
||||
.replace(/\n/g, "<text:line-break/>")
|
||||
.replace(/^ /, "<text:s/>").replace(/ $/, "<text:s/>");
|
||||
};
|
||||
|
||||
var null_cell_xml = ' <table:table-cell />\n';
|
||||
var covered_cell_xml = ' <table:covered-table-cell/>\n';
|
||||
var write_ws = function(ws, wb, i/*:number*/, opts)/*:string*/ {
|
||||
var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts)/*:string*/ {
|
||||
/* Section 9 Tables */
|
||||
var o = [];
|
||||
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '">\n');
|
||||
@ -56,7 +78,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
ct['office:value'] = (cell.v||0);
|
||||
break;
|
||||
case 's': case 'str':
|
||||
textp = escapexml(cell.v);
|
||||
textp = cell.v;
|
||||
ct['office:value-type'] = "string";
|
||||
break;
|
||||
case 'd':
|
||||
@ -68,7 +90,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
//case 'e':
|
||||
default: o.push(null_cell_xml); continue;
|
||||
}
|
||||
o.push(' ' + writextag('table:table-cell', writextag('text:p', textp, {}), ct) + '\n');
|
||||
o.push(' ' + writextag('table:table-cell', writextag('text:p', write_text_p(textp), {}), ct) + '\n');
|
||||
}
|
||||
o.push(' </table:table-row>\n');
|
||||
}
|
||||
@ -133,8 +155,8 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
});
|
||||
|
||||
var fods = wxt_helper({
|
||||
'xmlns:config':"urn:oasis:names:tc:opendocument:xmlns:config:1.0",
|
||||
'office:mimetype':"application/vnd.oasis.opendocument.spreadsheet"
|
||||
'xmlns:config': "urn:oasis:names:tc:opendocument:xmlns:config:1.0",
|
||||
'office:mimetype': "application/vnd.oasis.opendocument.spreadsheet"
|
||||
});
|
||||
|
||||
if(opts.bookType == "fods") o.push('<office:document' + attr + fods + '>\n');
|
||||
@ -161,7 +183,7 @@ function write_ods(wb/*:any*/, opts/*:any*/) {
|
||||
var manifest/*:Array<Array<string> >*/ = [];
|
||||
var rdf = [];
|
||||
|
||||
/* 3:3.3 and 2:2.2.4 */
|
||||
/* Part 3 Section 3.3 MIME Media Type */
|
||||
f = "mimetype";
|
||||
zip.file(f, "application/vnd.oasis.opendocument.spreadsheet");
|
||||
|
||||
@ -177,17 +199,17 @@ function write_ods(wb/*:any*/, opts/*:any*/) {
|
||||
manifest.push([f, "text/xml"]);
|
||||
rdf.push([f, "StylesFile"]);
|
||||
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
f = "manifest.rdf";
|
||||
zip.file(f, write_rdf(rdf, opts));
|
||||
manifest.push([f, "application/rdf+xml"]);
|
||||
|
||||
/* TODO: this is hard-coded to satiate excel */
|
||||
f = "meta.xml";
|
||||
zip.file(f, write_meta_ods(wb, opts));
|
||||
manifest.push([f, "text/xml"]);
|
||||
rdf.push([f, "MetadataFile"]);
|
||||
|
||||
/* Part 3 Section 6 Metadata Manifest File */
|
||||
f = "manifest.rdf";
|
||||
zip.file(f, write_rdf(rdf, opts));
|
||||
manifest.push([f, "application/rdf+xml"]);
|
||||
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
f = "META-INF/manifest.xml";
|
||||
zip.file(f, write_manifest(manifest, opts));
|
||||
|
@ -49,6 +49,8 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
|
||||
/* UOC */
|
||||
if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
|
||||
/* Numbers */
|
||||
if(safegetzipfile(zip, 'Index/Document.iwa')) throw new Error('Unsupported NUMBERS file');
|
||||
|
||||
var entries = keys(zip.files).filter(nodirs).sort();
|
||||
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/), opts);
|
||||
@ -186,7 +188,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
data = CFB.find(cfb, f);
|
||||
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
|
||||
var dsm = parse_DataSpaceMap(data.content);
|
||||
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
|
||||
if(dsm.length !== 1 || dsm[0].comps.length !== 1 || dsm[0].comps[0].t !== 0 || dsm[0].name !== "StrongEncryptionDataSpace" || dsm[0].comps[0].v !== "EncryptedPackage")
|
||||
throw new Error("ECMA-376 Encrypted file bad " + f);
|
||||
|
||||
f = 'StrongEncryptionDataSpace';
|
||||
@ -207,6 +209,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
|
||||
var einfo = parse_EncryptionInfo(data.content);
|
||||
|
||||
if(einfo[0] == 0x04) throw new Error("File is password-protected: ECMA-376 Agile");
|
||||
throw new Error("File is password-protected");
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ function read_prn(data, d, o, str) {
|
||||
}
|
||||
|
||||
function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var zip, d = data, n=[0], str = false;
|
||||
var zip, d = data, n = [0,0,0,0], str = false;
|
||||
var o = opts||{};
|
||||
_ssfopts = {};
|
||||
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
|
||||
@ -81,14 +81,14 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
case 0xD0: return read_cfb(CFB.read(d, o), o);
|
||||
case 0x09: return parse_xlscfb(d, o);
|
||||
case 0x3C: return parse_xlml(d, o);
|
||||
case 0x49: if(n[1] == 0x44) return read_wb_ID(d, o); break;
|
||||
case 0x54: if(n[1] == 0x41 && n[2] == 0x42 && n[3] == 0x4C) return DIF.to_workbook(d, o); break;
|
||||
case 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
|
||||
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
|
||||
case 0x49: if(n[1] === 0x44) return read_wb_ID(d, o); break;
|
||||
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
|
||||
case 0x50: if(n[1] === 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] === 0xFE) { return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] === 0x00 && n[2] >= 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: case 0x8C: return DBF.to_workbook(d, o);
|
||||
case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break;
|
||||
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
|
||||
}
|
||||
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
|
||||
|
@ -175,10 +175,10 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/);
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
for(var R = 0; R != js.length; ++R) {
|
||||
Object.keys(js[R]).filter(function(x) { return js[R].hasOwnProperty(x); }).forEach(function(k) {
|
||||
js.forEach(function (JS, R) {
|
||||
keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = js[R][k];
|
||||
var v = JS[k];
|
||||
var t = 'z';
|
||||
var z = "";
|
||||
if(typeof v == 'number') t = 'n';
|
||||
@ -192,7 +192,7 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v}/*:any*/);
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
}
|
||||
});
|
||||
range.e.c = hdr.length - 1;
|
||||
for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]};
|
||||
ws['!ref'] = encode_range(range);
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
<!-- ui-grid -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.0/ui-grid.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.0/ui-grid.css"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.0/ui-grid.css"/>
|
||||
|
||||
<!-- FileSaver shim for exporting files -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
|
||||
|
28
dist/xlsx.core.min.js
vendored
28
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
25
dist/xlsx.full.min.js
vendored
25
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
836
dist/xlsx.js
vendored
836
dist/xlsx.js
vendored
File diff suppressed because it is too large
Load Diff
24
dist/xlsx.min.js
vendored
24
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
@ -36,76 +36,3 @@ With [bower](http://bower.io/search/?q=js-xlsx):
|
||||
$ bower install js-xlsx
|
||||
```
|
||||
|
||||
### JS Ecosystem Demos
|
||||
|
||||
The [`demos` directory](demos/) includes sample projects for:
|
||||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](demos/angular/)
|
||||
- [`angular 2.x / 4.x`](demos/angular2/)
|
||||
- [`meteor`](demos/meteor/)
|
||||
- [`react and react-native`](demos/react/)
|
||||
- [`vue 2.x and weex`](demos/vue/)
|
||||
- [`XMLHttpRequest and fetch`](demos/xhr/)
|
||||
- [`nodejs server`](demos/server/)
|
||||
|
||||
**Bundlers and Tooling**
|
||||
- [`browserify`](demos/browserify/)
|
||||
- [`requirejs`](demos/requirejs/)
|
||||
- [`rollup`](demos/rollup/)
|
||||
- [`systemjs`](demos/systemjs/)
|
||||
- [`webpack 2.x`](demos/webpack/)
|
||||
|
||||
**Platforms and Integrations**
|
||||
- [`electron application`](demos/electron/)
|
||||
- [`nw.js application`](demos/nwjs/)
|
||||
- [`Adobe ExtendScript`](demos/extendscript/)
|
||||
- [`Headless Browsers`](demos/headless/)
|
||||
- [`canvas-datagrid`](demos/datagrid/)
|
||||
- [`Swift JSC and other engines`](demos/altjs/)
|
||||
|
||||
### Optional Modules
|
||||
|
||||
<details>
|
||||
<summary><b>Optional features</b> (click to show)</summary>
|
||||
|
||||
The node version automatically requires modules for additional features. Some
|
||||
of these modules are rather large in size and are only needed in special
|
||||
circumstances, so they do not ship with the core. For browser use, they must
|
||||
be included directly:
|
||||
|
||||
```html
|
||||
<!-- international support from js-codepage -->
|
||||
<script src="dist/cpexcel.js"></script>
|
||||
```
|
||||
|
||||
An appropriate version for each dependency is included in the dist/ directory.
|
||||
|
||||
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
||||
|
||||
Webpack and Browserify builds include optional modules by default. Webpack can
|
||||
be configured to remove support with `resolve.alias`:
|
||||
|
||||
```js
|
||||
/* uncomment the lines below to remove support */
|
||||
resolve: {
|
||||
alias: { "./dist/cpexcel.js": "" } // <-- omit international support
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### ECMAScript 5 Compatibility
|
||||
|
||||
Since the library uses functions like `Array#forEach`, older browsers require
|
||||
[shims to provide missing functions](http://oss.sheetjs.com/js-xlsx/shim.js).
|
||||
|
||||
To use the shim, add the shim before the script tag that loads `xlsx.js`:
|
||||
|
||||
```html
|
||||
<!-- add the shim first -->
|
||||
<script type="text/javascript" src="shim.js"></script>
|
||||
<!-- after the shim is referenced, add the library -->
|
||||
<script type="text/javascript" src="xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
|
28
docbits/11_demos.md
Normal file
28
docbits/11_demos.md
Normal file
@ -0,0 +1,28 @@
|
||||
### JS Ecosystem Demos
|
||||
|
||||
The [`demos` directory](demos/) includes sample projects for:
|
||||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](demos/angular/)
|
||||
- [`angular 2.x / 4.x`](demos/angular2/)
|
||||
- [`meteor`](demos/meteor/)
|
||||
- [`react and react-native`](demos/react/)
|
||||
- [`vue 2.x and weex`](demos/vue/)
|
||||
- [`XMLHttpRequest and fetch`](demos/xhr/)
|
||||
- [`nodejs server`](demos/server/)
|
||||
|
||||
**Bundlers and Tooling**
|
||||
- [`browserify`](demos/browserify/)
|
||||
- [`requirejs`](demos/requirejs/)
|
||||
- [`rollup`](demos/rollup/)
|
||||
- [`systemjs`](demos/systemjs/)
|
||||
- [`webpack 2.x`](demos/webpack/)
|
||||
|
||||
**Platforms and Integrations**
|
||||
- [`electron application`](demos/electron/)
|
||||
- [`nw.js application`](demos/nwjs/)
|
||||
- [`Adobe ExtendScript`](demos/extendscript/)
|
||||
- [`Headless Browsers`](demos/headless/)
|
||||
- [`canvas-datagrid`](demos/datagrid/)
|
||||
- [`Swift JSC and other engines`](demos/altjs/)
|
||||
|
45
docbits/12_optional.md
Normal file
45
docbits/12_optional.md
Normal file
@ -0,0 +1,45 @@
|
||||
### Optional Modules
|
||||
|
||||
<details>
|
||||
<summary><b>Optional features</b> (click to show)</summary>
|
||||
|
||||
The node version automatically requires modules for additional features. Some
|
||||
of these modules are rather large in size and are only needed in special
|
||||
circumstances, so they do not ship with the core. For browser use, they must
|
||||
be included directly:
|
||||
|
||||
```html
|
||||
<!-- international support from js-codepage -->
|
||||
<script src="dist/cpexcel.js"></script>
|
||||
```
|
||||
|
||||
An appropriate version for each dependency is included in the dist/ directory.
|
||||
|
||||
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
||||
|
||||
Webpack and Browserify builds include optional modules by default. Webpack can
|
||||
be configured to remove support with `resolve.alias`:
|
||||
|
||||
```js
|
||||
/* uncomment the lines below to remove support */
|
||||
resolve: {
|
||||
alias: { "./dist/cpexcel.js": "" } // <-- omit international support
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### ECMAScript 5 Compatibility
|
||||
|
||||
Since the library uses functions like `Array#forEach`, older browsers require
|
||||
[shims to provide missing functions](http://oss.sheetjs.com/js-xlsx/shim.js).
|
||||
|
||||
To use the shim, add the shim before the script tag that loads `xlsx.js`:
|
||||
|
||||
```html
|
||||
<!-- add the shim first -->
|
||||
<script type="text/javascript" src="shim.js"></script>
|
||||
<!-- after the shim is referenced, add the library -->
|
||||
<script type="text/javascript" src="xlsx.full.min.js"></script>
|
||||
```
|
||||
|
@ -97,8 +97,9 @@ Plain text format guessing follows the priority order:
|
||||
| XML | starts with `<` |
|
||||
| RTF | starts with `{\rt` |
|
||||
| DSV | starts with `/sep=.$/`, separator is the specified character |
|
||||
| CSV | more unquoted `","` characters than `"\t"` chars in the first 1024 |
|
||||
| TSV | one of the first 1024 characters is a tab char `"\t"` |
|
||||
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
|
||||
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
|
||||
| CSV | one of the first 1024 characters is a comma `","` |
|
||||
| PRN | (default) |
|
||||
|
||||
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`
|
||||
|
@ -36,6 +36,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
@ -45,7 +46,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
|
@ -9,7 +9,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | :o: |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | :o: | :o: |
|
||||
@ -28,7 +28,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
|
@ -40,6 +40,7 @@ digraph G {
|
||||
xlsb -> csf
|
||||
csf -> xlml
|
||||
xlml -> csf
|
||||
csf -> xls5
|
||||
xls5 -> csf
|
||||
csf -> xls8
|
||||
xls8 -> csf
|
||||
|
BIN
formats.png
BIN
formats.png
Binary file not shown.
Before Width: | Height: | Size: 179 KiB After Width: | Height: | Size: 181 KiB |
@ -54,7 +54,7 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
|
||||
<script>
|
||||
/*jshint browser:true */
|
||||
/* eslint-env browser */
|
||||
/*global Uint8Array, Uint16Array, ArrayBuffer */
|
||||
/*global Uint8Array, console */
|
||||
/*global XLSX */
|
||||
var X = XLSX;
|
||||
var XW = {
|
||||
|
@ -1437,8 +1437,9 @@ Plain text format guessing follows the priority order:
|
||||
| XML | starts with `<` |
|
||||
| RTF | starts with `{\rt` |
|
||||
| DSV | starts with `/sep=.$/`, separator is the specified character |
|
||||
| CSV | more unquoted `","` characters than `"\t"` chars in the first 1024 |
|
||||
| TSV | one of the first 1024 characters is a tab char `"\t"` |
|
||||
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
|
||||
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
|
||||
| CSV | one of the first 1024 characters is a comma `","` |
|
||||
| PRN | (default) |
|
||||
|
||||
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`
|
||||
@ -1497,6 +1498,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff5` | `.xls` | CFB | multi | Excel 5.0/95 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
@ -1506,7 +1508,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `sylk` | `.sylk` | none | single | Symbolic Link (SYLK) |
|
||||
| `html` | `.html` | none | single | HTML Document |
|
||||
| `dif` | `.dif` | none | single | Data Interchange Format (DIF) |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format |
|
||||
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
|
||||
| `prn` | `.prn` | none | single | Lotus Formatted Text |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
@ -1804,7 +1806,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | :o: |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | :o: | :o: |
|
||||
@ -1823,7 +1825,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Quattro Pro Spreadsheet (WQ1/WQ2/WB1/WB2/WB3/QPW) | :o: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | :o: |
|
||||
| RTF Tables | | :o: |
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
|
@ -2,25 +2,26 @@
|
||||
# vim: set ts=4:
|
||||
# Format: <basename> <ext> <ext> [ext..]
|
||||
# yes-formula
|
||||
# note: Excel ODS converter does not support spaces in Sheet Names
|
||||
AutoFilter .xls .xlsb .xlsx .xml
|
||||
# note: XLML only supports sheets, ods does not support dialog
|
||||
BlankSheetTypes .xls .xlsb .xlsm
|
||||
NumberFormatCondition .xls .xlsb .xlsm .xml
|
||||
RkNumber .xls .xlsb .xlsx .xls.xml
|
||||
#calendar_stress_test .xls .xlsb .xlsx .xml
|
||||
cell_style_simple .xls .xlsb .xlsx .xml
|
||||
cell_style_simple .xls .xlsb .xlsx .xml .ods
|
||||
# no-csv (newline character \r vs \n)
|
||||
comments_stress_test .xls .xlsb .xlsx .xls.xml
|
||||
comments_stress_test .xls .xlsb .xlsx .xls.xml .ods
|
||||
# yes-csv
|
||||
custom_properties .xls .xlsb .xlsx .xls.xml
|
||||
defined_names_simple .xls .xlsb .xlsx .xml
|
||||
# no-csv (randbetween) note: ODS does not support many XLSX functions
|
||||
# no-csv (randbetween) note: ODS does not support many XLSX functions
|
||||
formula_stress_test .xls .xlsb .xlsx .xls.xml
|
||||
# yes-csv
|
||||
formulae_test_simple .xls .xlsb .xlsx .xml
|
||||
hyperlink_stress_test_2011 .xls .xlsb .xlsx .xml
|
||||
#large_strings .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml
|
||||
merge_cells .xls .xlsb .xlsx .xls.xml
|
||||
merge_cells .xls .xlsb .xlsx .xls.xml .ods
|
||||
# no-formula (filename-references in XLSX encoding as [0])
|
||||
named_ranges_2011 .xls .xlsb .xlsx .xls.xml
|
||||
# yes-formula
|
||||
@ -34,7 +35,7 @@ pivot_table_named_range .xls .xlsb .xlsx .xml
|
||||
pivot_table_test .xls .xlsb .xlsm
|
||||
rich_text_stress .xls .xlsb .xlsx .xls.xml
|
||||
smart_tags_2007 .xls .xlsb .xlsx .xml
|
||||
sushi .xls .xlsb .xlsx .xml
|
||||
sushi .xls .xlsb .xlsx .xml .ods
|
||||
text_and_numbers .xls .xlsb .xlsx .xml
|
||||
#time_stress_test_1 .xls .xlsb .xlsx .xml
|
||||
# no-formula (rounding issue in IE8)
|
||||
|
28
package.json
28
package.json
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.11.5",
|
||||
"version": "0.11.6",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLS/XML) ODS and other spreadsheet format (CSV/DIF/DBF/SYLK) parser and writer",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "csv", "dbf", "dif", "sylk", "office", "spreadsheet" ],
|
||||
"bin": {
|
||||
"xlsx": "./bin/xlsx.njs"
|
||||
@ -17,20 +17,20 @@
|
||||
"fs": false
|
||||
},
|
||||
"dependencies": {
|
||||
"exit-on-epipe":"~1.0.1",
|
||||
"ssf":"~0.10.1",
|
||||
"codepage":"~1.11.0",
|
||||
"cfb":"~0.13.1",
|
||||
"crc-32":"~1.1.1",
|
||||
"adler-32":"~1.1.0",
|
||||
"commander":"~2.11.0"
|
||||
"exit-on-epipe": "~1.0.1",
|
||||
"ssf": "~0.10.1",
|
||||
"codepage": "~1.11.0",
|
||||
"cfb": "~0.13.1",
|
||||
"crc-32": "~1.1.1",
|
||||
"adler-32": "~1.1.0",
|
||||
"commander": "~2.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha":"~2.5.3",
|
||||
"mocha": "~2.5.3",
|
||||
"blanket": "~1.2.3",
|
||||
"@sheetjs/uglify-js":"~2.7.3",
|
||||
"@types/node":"^8.0.7",
|
||||
"@types/commander":"^2.9.0",
|
||||
"@sheetjs/uglify-js": "~2.7.3",
|
||||
"@types/node": "^8.0.7",
|
||||
"@types/commander": "^2.9.0",
|
||||
"jsdom": "~11.1.0",
|
||||
"dtslint": "^0.1.2",
|
||||
"typescript": "2.2.0"
|
||||
@ -39,6 +39,8 @@
|
||||
"scripts": {
|
||||
"pretest": "git submodule init && git submodule update",
|
||||
"test": "make travis",
|
||||
"build": "make",
|
||||
"lint": "make fullint",
|
||||
"dtslint": "dtslint types"
|
||||
},
|
||||
"config": {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 936478fc713e5ee59c35a49bce4f61ea397284e5
|
||||
Subproject commit e16abc3908a12be7c7293518e5fed1e31e374605
|
@ -1441,3 +1441,5 @@ artifacts/wps/write.et
|
||||
# artifacts/wps/write.xls ## bad sheet name
|
||||
artifacts/wps/write.xlsx
|
||||
artifacts/wps/write.xml
|
||||
dbf/d11.dbf
|
||||
dbf/vfp3.dbf
|
||||
|
797
tests/core.js
797
tests/core.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -39,6 +39,7 @@
|
||||
./test_files/custom_properties.xlsb
|
||||
./test_files/cell_style_simple.xls
|
||||
./test_files/cell_style_simple.xml
|
||||
./test_files/cell_style_simple.ods
|
||||
./test_files/cell_style_simple.xlsx
|
||||
./test_files/cell_style_simple.xlsb
|
||||
./test_files/comments_stress_test.xls
|
||||
@ -106,3 +107,5 @@
|
||||
./test_files/apachepoi_SimpleWithComments.xlsx
|
||||
./test_files/2013/apachepoi_SimpleWithComments.xlsx.xlsb
|
||||
./test_files/password_2002_40_xor.xls
|
||||
./test_files/dbf/d11.dbf
|
||||
./test_files/dbf/vfp3.dbf
|
||||
|
@ -5,7 +5,7 @@
|
||||
var data = [
|
||||
[1, 2, 3],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["foo bar", "baz", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["baz", null, "\u0BEE", 3.14159],
|
||||
["hidden"],
|
||||
["visible"]
|
||||
@ -162,8 +162,9 @@ var filenames = [
|
||||
['sheetjs.xlsx', {bookSST:true}],
|
||||
['sheetjs.xlsm'],
|
||||
['sheetjs.xlsb'],
|
||||
['sheetjs.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff2', {bookType:'biff2'}],
|
||||
['sheetjs.biff8.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff5.xls', {bookType:'biff5'}],
|
||||
['sheetjs.biff2.xls', {bookType:'biff2'}],
|
||||
['sheetjs.xml.xls', {bookType:'xlml'}],
|
||||
['sheetjs.ods'],
|
||||
['sheetjs.fods'],
|
||||
|
2
types/index.d.ts
vendored
2
types/index.d.ts
vendored
@ -477,7 +477,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
|
||||
* Type of generated workbook
|
||||
* @default 'xlsx'
|
||||
*/
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn';
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn';
|
||||
|
||||
/** Comment element */
|
||||
export interface Comment {
|
||||
|
@ -5,7 +5,7 @@
|
||||
let data: any[][] = [
|
||||
[1, 2, 3],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["foo bar", "baz", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["baz", null, "qux", 3.14159],
|
||||
["hidden"],
|
||||
["visible"]
|
||||
@ -150,8 +150,9 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [
|
||||
['sheetjs.xlsx', {bookSST:true}],
|
||||
['sheetjs.xlsm'],
|
||||
['sheetjs.xlsb'],
|
||||
['sheetjs.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff2', {bookType:'biff2'}],
|
||||
['sheetjs.biff8.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff5.xls', {bookType:'biff5'}],
|
||||
['sheetjs.biff2.xls', {bookType:'biff2'}],
|
||||
['sheetjs.xml.xls', {bookType:'xlml'}],
|
||||
['sheetjs.ods'],
|
||||
['sheetjs.fods'],
|
||||
@ -160,6 +161,7 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [
|
||||
['sheetjs.slk'],
|
||||
['sheetjs.htm'],
|
||||
['sheetjs.dif'],
|
||||
['sheetjs.rtf'],
|
||||
['sheetjs.prn']
|
||||
];
|
||||
|
||||
|
@ -10,9 +10,7 @@ const otherworkbook: XLSX.WorkBook = XLSX.readFile('test.xlsx', {type: 'file'});
|
||||
const author: string = workbook.Props.Author;
|
||||
|
||||
const firstsheet: string = workbook.SheetNames[0];
|
||||
|
||||
const firstworksheet: XLSX.WorkSheet = workbook.Sheets[firstsheet];
|
||||
|
||||
const WB1A1: XLSX.CellObject = (firstworksheet["A1"]);
|
||||
|
||||
interface Tester {
|
||||
@ -41,3 +39,8 @@ const WBSheet0 = WBSheets[0];
|
||||
console.log(WBSheet0.Hidden);
|
||||
|
||||
const fmt14 = XLSX.SSF._table[14];
|
||||
|
||||
const newwb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(newwb, aoa2, "AOA");
|
||||
XLSX.utils.book_append_sheet(newwb, js2ws, "JSON");
|
||||
const bstrxlsx: string = XLSX.write(newwb, {type: "binary", bookType: "xlsx" });
|
||||
|
788
xlsx.flow.js
788
xlsx.flow.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user