version bump 0.11.16: refresh
- HTML whitespace (fixes #849 h/t @laurentauthier) - XLML number format write (fixes #904 h/t @james-boswell) - XLAM/XLA write - 'array' write type - XLSX/XLSB/XLS/XLML RTL read/write - XLS merge cells write - demo and typing refresh
This commit is contained in:
parent
33f96fc6ae
commit
f277ebe140
@ -14,8 +14,8 @@ tmp
|
||||
*.[pP][rR][nN]
|
||||
*.[sS][lL][kK]
|
||||
*.socialcalc
|
||||
*.[xX][lL][sSwWcC]
|
||||
*.[xX][lL][sS][xXmMbB]
|
||||
*.[xX][lL][sSwWcCaAtT]
|
||||
*.[xX][lL][sSaAtT][xXmMbB]
|
||||
*.[oO][dD][sS]
|
||||
*.[fF][oO][dD][sS]
|
||||
*.[xX][mM][lL]
|
||||
|
@ -53,6 +53,7 @@ weex
|
||||
|
||||
# Other terms
|
||||
APIs
|
||||
ArrayBuffer
|
||||
Base64
|
||||
Booleans
|
||||
JS
|
||||
|
@ -4,6 +4,11 @@ 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.16 (2017-12-30)
|
||||
|
||||
* XLS ANSI/CP separation
|
||||
* 'array' write type and ArrayBuffer processing
|
||||
|
||||
## 0.11.6 (2017-10-16)
|
||||
|
||||
* Semicolon-delimited files are detected
|
||||
|
21
README.md
21
README.md
@ -84,6 +84,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
+ [Workbook File Properties](#workbook-file-properties)
|
||||
* [Workbook-Level Attributes](#workbook-level-attributes)
|
||||
+ [Defined Names](#defined-names)
|
||||
+ [Workbook Views](#workbook-views)
|
||||
+ [Miscellaneous Workbook Properties](#miscellaneous-workbook-properties)
|
||||
* [Document Features](#document-features)
|
||||
+ [Formulae](#formulae)
|
||||
@ -621,19 +622,12 @@ example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
|
||||
|
||||
```js
|
||||
/* bookType can be any supported output type */
|
||||
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
|
||||
var wopts = { bookType:'xlsx', bookSST:false, type:'array' };
|
||||
|
||||
var wbout = XLSX.write(workbook,wopts);
|
||||
|
||||
function s2ab(s) {
|
||||
var buf = new ArrayBuffer(s.length);
|
||||
var view = new Uint8Array(buf);
|
||||
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* the saveAs call downloads a file on the local machine */
|
||||
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
|
||||
saveAs(new Blob([wbout],{type:"application/octet-stream"}), "test.xlsx");
|
||||
```
|
||||
|
||||
</details>
|
||||
@ -1081,6 +1075,14 @@ Excel allows two sheet-scoped defined names to share the same name. However, a
|
||||
sheet-scoped name cannot collide with a workbook-scope name. Workbook writers
|
||||
may not enforce this constraint.
|
||||
|
||||
#### Workbook Views
|
||||
|
||||
`wb.Workbook.Views` is an array of workbook view objects which have the keys:
|
||||
|
||||
| Key | Description |
|
||||
|:----------------|:----------------------------------------------------|
|
||||
| `RTL` | If true, display right-to-left |
|
||||
|
||||
#### Miscellaneous Workbook Properties
|
||||
|
||||
`wb.Workbook.WBProps` holds other workbook properties:
|
||||
@ -1693,6 +1695,7 @@ The `type` argument for `write` mirrors the `type` argument for `read`:
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | ArrayBuffer, fallback array of 8-bit unsigned int |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
|
||||
## Utility Functions
|
||||
|
@ -19,12 +19,14 @@ program
|
||||
.option('-B, --xlsb', 'emit XLSB to <sheetname> or <file>.xlsb')
|
||||
.option('-M, --xlsm', 'emit XLSM to <sheetname> or <file>.xlsm')
|
||||
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
|
||||
.option('-I, --xlam', 'emit XLAM to <sheetname> or <file>.xlam')
|
||||
.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('-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)')
|
||||
.option('-i, --xla', 'emit XLA to <sheetname> or <file>.xla')
|
||||
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
|
||||
|
||||
@ -65,8 +67,10 @@ program.on('--help', function() {
|
||||
var workbook_formats = [
|
||||
['xlsx', 'xlsx', 'xlsx'],
|
||||
['xlsm', 'xlsm', 'xlsm'],
|
||||
['xlam', 'xlam', 'xlam'],
|
||||
['xlsb', 'xlsb', 'xlsb'],
|
||||
['xls', 'xls', 'xls'],
|
||||
['xla', 'xla', 'xla'],
|
||||
['biff5', 'biff5', 'xls'],
|
||||
['ods', 'ods', 'ods'],
|
||||
['fods', 'fods', 'fods']
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.11.15';
|
||||
XLSX.version = '0.11.16';
|
||||
|
@ -1,21 +1,51 @@
|
||||
var current_codepage = 1200;
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js');
|
||||
}
|
||||
function reset_cp() { set_cp(1200); }
|
||||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
|
||||
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950 ];
|
||||
for(var i = 0; i <= 8; ++i) VALID_ANSI.push(1250 + i);
|
||||
/* ECMA-376 Part I 18.4.1 charset to codepage mapping */
|
||||
var CS2CP = ({
|
||||
/*::[*/0/*::]*/: 1252, /* ANSI */
|
||||
/*::[*/1/*::]*/: 65001, /* DEFAULT */
|
||||
/*::[*/2/*::]*/: 65001, /* SYMBOL */
|
||||
/*::[*/77/*::]*/: 10000, /* MAC */
|
||||
/*::[*/128/*::]*/: 932, /* SHIFTJIS */
|
||||
/*::[*/129/*::]*/: 949, /* HANGUL */
|
||||
/*::[*/130/*::]*/: 1361, /* JOHAB */
|
||||
/*::[*/134/*::]*/: 936, /* GB2312 */
|
||||
/*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
|
||||
/*::[*/161/*::]*/: 1253, /* GREEK */
|
||||
/*::[*/162/*::]*/: 1254, /* TURKISH */
|
||||
/*::[*/163/*::]*/: 1258, /* VIETNAMESE */
|
||||
/*::[*/177/*::]*/: 1255, /* HEBREW */
|
||||
/*::[*/178/*::]*/: 1256, /* ARABIC */
|
||||
/*::[*/186/*::]*/: 1257, /* BALTIC */
|
||||
/*::[*/204/*::]*/: 1251, /* RUSSIAN */
|
||||
/*::[*/222/*::]*/: 874, /* THAI */
|
||||
/*::[*/238/*::]*/: 1250, /* EASTEUROPE */
|
||||
/*::[*/255/*::]*/: 1252, /* OEM */
|
||||
/*::[*/69/*::]*/: 6969 /* MISC */
|
||||
}/*:any*/);
|
||||
|
||||
var set_ansi = function(cp/*:number*/) { if(VALID_ANSI.indexOf(cp) == -1) return; current_ansi = CS2CP[0] = cp; };
|
||||
function reset_ansi() { set_ansi(1252); }
|
||||
|
||||
var set_cp = function(cp/*:number*/) { current_codepage = cp; set_ansi(cp); };
|
||||
function reset_cp() { set_cp(1200); reset_ansi(); }
|
||||
|
||||
function char_codes(data/*:string*/)/*:Array<number>*/ { var o/*:Array<number>*/ = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
|
||||
function utf16leread(data/*:string*/)/*:string*/ {
|
||||
var o = [];
|
||||
var o/*:Array<string>*/ = [];
|
||||
for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i) + (data.charCodeAt(2*i+1)<<8));
|
||||
return o.join("");
|
||||
}
|
||||
function utf16beread(data/*:string*/)/*:string*/ {
|
||||
var o = [];
|
||||
var o/*:Array<string>*/ = [];
|
||||
for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i+1) + (data.charCodeAt(2*i)<<8));
|
||||
return o.join("");
|
||||
}
|
||||
|
@ -12,6 +12,18 @@ function s2a(s/*:string*/) {
|
||||
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
|
||||
}
|
||||
|
||||
function s2ab(s/*:string*/) {
|
||||
if(typeof ArrayBuffer === 'undefined') return s2a(s);
|
||||
var buf = new ArrayBuffer(s.length), view = new Uint8Array(buf);
|
||||
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
|
||||
return buf;
|
||||
}
|
||||
|
||||
function arr2str(data/*:any*/)/*:string*/ {
|
||||
if(Array.isArray(data)) return data.map(_chr).join("");
|
||||
var o/*:Array<string>*/ = []; for(var i = 0; i < data.length; ++i) o[i] = _chr(data[i]); return o.join("");
|
||||
}
|
||||
|
||||
var bconcat = function(bufs) { return [].concat.apply([], bufs); };
|
||||
|
||||
var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;
|
||||
|
@ -1,5 +1,3 @@
|
||||
function isval(x/*:?any*/)/*:boolean*/ { return x !== undefined && x !== null; }
|
||||
|
||||
function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); }
|
||||
|
||||
function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ {
|
||||
@ -99,12 +97,6 @@ function cc2str(arr/*:Array<number>*/)/*:string*/ {
|
||||
return o;
|
||||
}
|
||||
|
||||
function str2cc(str) {
|
||||
var o = [];
|
||||
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o/*:any*/)/*:any*/ {
|
||||
if(typeof JSON != 'undefined' && !Array.isArray(o)) return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || o == null) return o;
|
||||
|
@ -13,7 +13,7 @@ function getdatabin(data) {
|
||||
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
|
||||
if(data._data && data._data.getContent) {
|
||||
var o = data._data.getContent();
|
||||
if(typeof o == "string") return str2cc(o);
|
||||
if(typeof o == "string") return char_codes(o);
|
||||
return Array.prototype.slice.call(o);
|
||||
}
|
||||
return null;
|
||||
|
@ -1,6 +1,6 @@
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
var attregexg=/([^"\s?>\/]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+=(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
|
||||
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
|
||||
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
|
||||
@ -13,7 +13,8 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
|
||||
if(m) for(i = 0; i != m.length; ++i) {
|
||||
cc = m[i];
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
q = cc.substr(0,c);
|
||||
q = cc.substr(0,c).trim();
|
||||
while(cc.charCodeAt(c+1) == 32) ++c;
|
||||
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
|
||||
v = cc.substring(c+1+quot, cc.length-quot);
|
||||
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
|
||||
@ -84,7 +85,7 @@ function parsexmlbool(value/*:any*/, tag/*:?string*/)/*:boolean*/ {
|
||||
}
|
||||
}
|
||||
|
||||
var utf8read/*:StringConv*/ = function utf8reada(orig) {
|
||||
var utf8read/*:StringConv*/ = function utf8reada(orig/*:string*/)/*:string*/ {
|
||||
var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0;
|
||||
while (i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
@ -101,7 +102,7 @@ var utf8read/*:StringConv*/ = function utf8reada(orig) {
|
||||
return out;
|
||||
};
|
||||
|
||||
var utf8write/*:StringConv*/ = function(orig) {
|
||||
var utf8write/*:StringConv*/ = function(orig/*:string*/)/*:string*/ {
|
||||
var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
@ -156,18 +157,18 @@ if(has_buf) {
|
||||
// matches <foo>...</foo> extracts content
|
||||
var matchtag = (function() {
|
||||
var mtcache/*:{[k:string]:RegExp}*/ = ({}/*:any*/);
|
||||
return function matchtag(f,g/*:?string*/)/*:RegExp*/ {
|
||||
return function matchtag(f/*:string*/,g/*:?string*/)/*:RegExp*/ {
|
||||
var t = f+"|"+(g||"");
|
||||
if(mtcache[t]) return mtcache[t];
|
||||
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?'+f+'>',((g||"")/*:any*/)));
|
||||
};
|
||||
})();
|
||||
|
||||
var htmldecode = (function() {
|
||||
var entities = [
|
||||
var htmldecode/*:{(s:string):string}*/ = (function() {
|
||||
var entities/*:Array<[RegExp, string]>*/ = [
|
||||
['nbsp', ' '], ['middot', '·'],
|
||||
['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']
|
||||
].map(function(x) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
|
||||
].map(function(x/*:[string, string]*/) { return [new RegExp('&' + x[0] + ';', "g"), x[1]]; });
|
||||
return function htmldecode(str/*:string*/)/*:string*/ {
|
||||
var o = str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?>/g,"\n").replace(/<[^>]*>/g,"");
|
||||
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
|
||||
@ -181,27 +182,27 @@ var vtregex = (function(){ var vt_cache = {};
|
||||
return (vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g') );
|
||||
};})();
|
||||
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
|
||||
function parseVector(data, opts) {
|
||||
function parseVector(data/*:string*/, opts)/*:Array<{v:string,t:string}>*/ {
|
||||
var h = parsexmltag(data);
|
||||
|
||||
var matches = data.match(vtregex(h.baseType))||[];
|
||||
var res = [];
|
||||
var matches/*:Array<string>*/ = data.match(vtregex(h.baseType))||[];
|
||||
var res/*:Array<any>*/ = [];
|
||||
if(matches.length != h.size) {
|
||||
if(opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
|
||||
return res;
|
||||
}
|
||||
matches.forEach(function(x) {
|
||||
matches.forEach(function(x/*:string*/) {
|
||||
var v = x.replace(vtvregex,"").match(vtmregex);
|
||||
res.push({v:utf8read(v[2]), t:v[1]});
|
||||
if(v) res.push({v:utf8read(v[2]), t:v[1]});
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
var wtregex = /(^\s|\s$|\n)/;
|
||||
function writetag(f,g) {return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>';}
|
||||
function writetag(f/*:string*/,g/*:string*/)/*:string*/ { return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>'; }
|
||||
|
||||
function wxt_helper(h)/*:string*/ { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); }
|
||||
function writextag(f,g,h) { return '<' + f + (isval(h) /*:: && h */? wxt_helper(h) : "") + (isval(g) /*:: && g */? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
|
||||
function writextag(f/*:string*/,g/*:?string*/,h) { return '<' + f + ((h != null) ? wxt_helper(h) : "") + ((g != null) ? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
|
||||
|
||||
function write_w3cdtf(d/*:Date*/, t/*:?boolean*/)/*:string*/ { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } return ""; }
|
||||
|
||||
|
@ -35,6 +35,8 @@ var __utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { var ss=
|
||||
var ___utf8 = __utf8;
|
||||
var __lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpstr = __lpstr;
|
||||
var __cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___cpstr = __cpstr;
|
||||
var __lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpwstr = __lpwstr;
|
||||
var __lpp4, ___lpp4;
|
||||
@ -49,6 +51,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; };
|
||||
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__cpstr = function cpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___cpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
@ -63,7 +66,8 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
|
||||
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_ansi, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
|
||||
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
|
||||
@ -98,9 +102,10 @@ function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
|
||||
size = 2 * size; break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
case 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
|
||||
case 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
|
||||
/* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */
|
||||
case 'lpwstr': o = __lpwstr(this, this.l); size = 5 + o.length; if(o[o.length-1] == '\u0000') size += 2; break;
|
||||
case 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break;
|
||||
/* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */
|
||||
case 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break;
|
||||
/* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */
|
||||
@ -222,9 +227,6 @@ function prep_blob(blob, pos/*:number*/)/*:void*/ {
|
||||
}
|
||||
|
||||
function parsenoop(blob, length/*:: :number, opts?:any */) { blob.l += length; }
|
||||
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||
|
||||
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
||||
|
||||
function new_buf(sz/*:number*/)/*:Block*/ {
|
||||
var o = new_raw_buf(sz);
|
||||
|
@ -20,14 +20,14 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
|
||||
|
||||
/* control buffer usage for fixed-length buffers */
|
||||
function buf_array()/*:BufArray*/ {
|
||||
var bufs = [], blksz = has_buf ? 256 : 2048;
|
||||
var newblk = function ba_newblk(sz) {
|
||||
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
|
||||
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
|
||||
var o/*:Block*/ = (new_buf(sz)/*:any*/);
|
||||
prep_blob(o, 0);
|
||||
return o;
|
||||
};
|
||||
|
||||
var curbuf = newblk(blksz);
|
||||
var curbuf/*:Block*/ = newblk(blksz);
|
||||
|
||||
var endbuf = function ba_endbuf() {
|
||||
if(!curbuf) return;
|
||||
@ -36,7 +36,7 @@ function buf_array()/*:BufArray*/ {
|
||||
curbuf = null;
|
||||
};
|
||||
|
||||
var next = function ba_next(sz) {
|
||||
var next = function ba_next(sz/*:number*/)/*:Block*/ {
|
||||
if(curbuf && sz < curbuf.length - curbuf.l) return curbuf;
|
||||
endbuf();
|
||||
return (curbuf = newblk(Math.max(sz+1, blksz)));
|
||||
@ -56,7 +56,7 @@ function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?numbe
|
||||
var t/*:number*/ = +XLSBRE[type], l;
|
||||
if(isNaN(t)) return; // TODO: throw something here?
|
||||
if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0;
|
||||
l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length;
|
||||
l = 1 + (t >= 0x80 ? 1 : 0) + 1/* + length*/;
|
||||
if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;
|
||||
var o = ba.next(l);
|
||||
if(t <= 0x7F) o.write_shift(1, t);
|
||||
|
@ -265,3 +265,19 @@ function write_FontFlags(font, o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-OLEDS] 2.3.1 and 2.3.2 */
|
||||
function parse_ClipboardFormatOrString(o, w/*:number*/)/*:string*/ {
|
||||
// $FlowIgnore
|
||||
var ClipFmt = {2:"BITMAP",3:"METAFILEPICT",8:"DIB",14:"ENHMETAFILE"};
|
||||
var m/*:number*/ = o.read_shift(4);
|
||||
switch(m) {
|
||||
case 0x00000000: return "";
|
||||
case 0xffffffff: case 0xfffffffe: return ClipFmt[o.read_shift(4)]||"";
|
||||
}
|
||||
if(m > 0x190) throw new Error("Unsupported Clipboard: " + m.toString(16));
|
||||
o.l -= 4;
|
||||
return o.read_shift(0, w == 1 ? "lpstr" : "lpwstr");
|
||||
}
|
||||
function parse_ClipboardFormatOrAnsiString(o) { return parse_ClipboardFormatOrString(o, 1); }
|
||||
function parse_ClipboardFormatOrUnicodeString(o) { return parse_ClipboardFormatOrString(o, 2); }
|
||||
|
||||
|
@ -87,7 +87,7 @@ var SummaryPIDSI = {
|
||||
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
|
||||
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
|
||||
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
|
||||
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_LPSTR },
|
||||
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_STRING },
|
||||
/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
};
|
||||
|
@ -180,7 +180,7 @@ var CT_LIST = (function(){
|
||||
xlsb: "application/vnd.ms-excel.styles"
|
||||
}
|
||||
};
|
||||
keys(o).forEach(function(k) { if(!o[k].xlsm) o[k].xlsm = o[k].xlsx; });
|
||||
keys(o).forEach(function(k) { ["xlsm", "xlam"].forEach(function(v) { if(!o[k][v]) o[k][v] = o[k].xlsx; }); });
|
||||
keys(o).forEach(function(k){ keys(o[k]).forEach(function(v) { ct2type[o[k][v]] = k; }); });
|
||||
return o;
|
||||
})();
|
||||
|
@ -84,7 +84,7 @@ var EXT_PROPS_XML_ROOT = writextag('Properties', null, {
|
||||
});
|
||||
|
||||
function write_ext_props(cp, opts)/*:string*/ {
|
||||
var o = [], p = {}, W = writextag;
|
||||
var o/*:Array<string>*/ = [], p = {}, W = writextag;
|
||||
if(!cp) cp = {};
|
||||
cp.Application = "SheetJS";
|
||||
o[o.length] = (XML_HEADER);
|
||||
|
@ -39,7 +39,7 @@ function xlml_set_prop(Props, tag/*:string*/, val) {
|
||||
}
|
||||
|
||||
function xlml_write_docprops(Props, opts) {
|
||||
var o = [];
|
||||
var o/*:Array<string>*/ = [];
|
||||
keys(XLMLDocPropsMap).map(function(m) {
|
||||
for(var i = 0; i < CORE_PROPS.length; ++i) if(CORE_PROPS[i][1] == m) return CORE_PROPS[i];
|
||||
for(i = 0; i < EXT_PROPS.length; ++i) if(EXT_PROPS[i][1] == m) return EXT_PROPS[i];
|
||||
@ -60,7 +60,7 @@ function xlml_write_docprops(Props, opts) {
|
||||
function xlml_write_custprops(Props, Custprops, opts) {
|
||||
var BLACKLIST = ["Worksheets","SheetNames"];
|
||||
var T = 'CustomDocumentProperties';
|
||||
var o = [];
|
||||
var o/*:Array<string>*/ = [];
|
||||
if(Props) keys(Props).forEach(function(k) {
|
||||
/*:: if(!Props) return; */
|
||||
if(!Props.hasOwnProperty(k)) return;
|
||||
|
@ -8,8 +8,9 @@ function parse_FILETIME(blob) {
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
|
||||
function parse_lpstr(blob, type, pad/*:?number*/) {
|
||||
var str = blob.read_shift(0, 'lpstr');
|
||||
if(pad) blob.l += (4 - ((str.length+1) & 3)) & 3;
|
||||
var start = blob.l;
|
||||
var str = blob.read_shift(0, 'lpstr-cp');
|
||||
if(pad) while((blob.l - start) & 3) ++blob.l;
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -32,15 +33,15 @@ function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtS
|
||||
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
|
||||
function parse_VtVecUnalignedLpstrValue(blob) {
|
||||
function parse_VtVecUnalignedLpstrValue(blob)/*:Array<string>*/ {
|
||||
var length = blob.read_shift(4);
|
||||
var ret = [];
|
||||
for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr');
|
||||
var ret/*:Array<string>*/ = [];
|
||||
for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr-cp').replace(chr0,'');
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.10 VtVecUnalignedLpstr */
|
||||
function parse_VtVecUnalignedLpstr(blob) {
|
||||
function parse_VtVecUnalignedLpstr(blob)/*:Array<string>*/ {
|
||||
return parse_VtVecUnalignedLpstrValue(blob);
|
||||
}
|
||||
|
||||
@ -155,16 +156,17 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
var Offset = blob.read_shift(4);
|
||||
Props[i] = [PropID, Offset + start_addr];
|
||||
}
|
||||
Props.sort(function(x,y) { return x[1] - y[1]; });
|
||||
var PropH = {};
|
||||
for(i = 0; i != NumProps; ++i) {
|
||||
if(blob.l !== Props[i][1]) {
|
||||
var fail = true;
|
||||
if(i>0 && PIDSI) switch(PIDSI[Props[i-1][0]].t) {
|
||||
case 0x02 /*VT_I2*/: if(blob.l +2 === Props[i][1]) { blob.l+=2; fail = false; } break;
|
||||
case 0x02 /*VT_I2*/: if(blob.l+2 === Props[i][1]) { blob.l+=2; fail = false; } break;
|
||||
case 0x50 /*VT_STRING*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
|
||||
case 0x100C /*VT_VECTOR|VT_VARIANT*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
|
||||
}
|
||||
if(!PIDSI && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; }
|
||||
if((!PIDSI||i==0) && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; }
|
||||
if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
|
||||
}
|
||||
if(PIDSI) {
|
||||
@ -326,7 +328,7 @@ function parse_XLUnicodeRichExtendedString(blob) {
|
||||
var z = {};
|
||||
if(fRichSt) cRun = blob.read_shift(2);
|
||||
if(fExtSt) cbExtRst = blob.read_shift(4);
|
||||
var encoding = (flags & 0x1) ? 'dbcs-cont' : 'sbcs-cont';
|
||||
var encoding = width == 2 ? 'dbcs-cont' : 'sbcs-cont';
|
||||
var msg = cch === 0 ? "" : blob.read_shift(cch, encoding);
|
||||
if(fRichSt) blob.l += 4 * cRun; //TODO: parse this
|
||||
if(fExtSt) blob.l += cbExtRst; //TODO: parse this
|
||||
@ -398,15 +400,14 @@ function parse_URLMoniker(blob/*::, length, opts*/) {
|
||||
/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */
|
||||
function parse_FileMoniker(blob, length) {
|
||||
var cAnti = blob.read_shift(2);
|
||||
var ansiLength = blob.read_shift(4);
|
||||
var ansiPath = blob.read_shift(ansiLength, 'cstr');
|
||||
var ansiPath = blob.read_shift(0, 'lpstr-ansi');
|
||||
var endServer = blob.read_shift(2);
|
||||
var versionNumber = blob.read_shift(2);
|
||||
var cbUnicodePathSize = blob.read_shift(4);
|
||||
if(cbUnicodePathSize === 0) return ansiPath.replace(/\\/g,"/");
|
||||
var cbUnicodePathBytes = blob.read_shift(4);
|
||||
var usKeyValue = blob.read_shift(2);
|
||||
var unicodePath = blob.read_shift(cbUnicodePathBytes>>1, 'utf16le').replace(chr0,"");
|
||||
if(blob.read_shift(2) != 0xDEAD) throw new Error("Bad FileMoniker");
|
||||
var sz = blob.read_shift(4);
|
||||
if(sz === 0) return ansiPath.replace(/\\/g,"/");
|
||||
var bytes = blob.read_shift(4);
|
||||
if(blob.read_shift(2) != 3) throw new Error("Bad FileMoniker");
|
||||
var unicodePath = blob.read_shift(bytes>>1, 'utf16le').replace(chr0,"");
|
||||
return unicodePath;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,14 @@ function parse_Ref8U(blob, length) {
|
||||
var colLast = blob.read_shift(2);
|
||||
return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}};
|
||||
}
|
||||
function write_Ref8U(r/*:Range*/, o) {
|
||||
if(!o) o = new_buf(8);
|
||||
o.write_shift(2, r.s.r);
|
||||
o.write_shift(2, r.e.r);
|
||||
o.write_shift(2, r.s.c);
|
||||
o.write_shift(2, r.e.c);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.5.211 */
|
||||
function parse_RefU(blob, length) {
|
||||
@ -165,6 +173,7 @@ function write_BOF(wb/*:Workbook*/, t/*:number*/, o) {
|
||||
case 'biff4': h = 0x0004; w = 6; break;
|
||||
case 'biff3': h = 0x0003; w = 6; break;
|
||||
case 'biff2': h = 0x0002; w = 4; break;
|
||||
case 'xla': break;
|
||||
default: throw new Error("unsupported BIFF version");
|
||||
}
|
||||
var out = new_buf(w);
|
||||
@ -337,6 +346,22 @@ function write_Window1(opts) {
|
||||
o.write_shift(2, 0x01f4);
|
||||
return o;
|
||||
}
|
||||
/* 2.4.346 TODO */
|
||||
function parse_Window2(blob, length, opts) {
|
||||
if(opts && opts.biff >= 2 && opts.biff < 8) return {};
|
||||
var f = blob.read_shift(2);
|
||||
return { RTL: f & 0x40 };
|
||||
}
|
||||
function write_Window2(view) {
|
||||
var o = new_buf(18), f = 0x6b6;
|
||||
if(view && view.RTL) f |= 0x40;
|
||||
o.write_shift(2, f);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(4, 64);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(4, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.122 TODO */
|
||||
function parse_Font(blob, length, opts) {
|
||||
@ -624,7 +649,6 @@ function parse_ExternSheet(blob, length, opts) {
|
||||
var o = [], target = blob.l + length, len = blob.read_shift(opts.biff > 8 ? 4 : 2);
|
||||
while(len-- !== 0) o.push(parse_XTI(blob, opts.biff > 8 ? 12 : 6, opts));
|
||||
// [iSupBook, itabFirst, itabLast];
|
||||
var oo = [];
|
||||
return o;
|
||||
}
|
||||
function parse_BIFF5ExternSheet(blob, length, opts) {
|
||||
@ -689,12 +713,18 @@ function parse_Note(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.4.168 */
|
||||
function parse_MergeCells(blob, length) {
|
||||
var merges = [];
|
||||
function parse_MergeCells(blob, length)/*:Array<Range>*/ {
|
||||
var merges/*:Array<Range>*/ = [];
|
||||
var cmcs = blob.read_shift(2);
|
||||
while (cmcs--) merges.push(parse_Ref8U(blob,length));
|
||||
return merges;
|
||||
}
|
||||
function write_MergeCells(merges/*:Array<Range>*/) {
|
||||
var o = new_buf(2 + merges.length * 8);
|
||||
o.write_shift(2, merges.length);
|
||||
for(var i = 0; i < merges.length; ++i) write_Ref8U(merges[i], o);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.181 TODO: parse all the things! */
|
||||
function parse_Obj(blob, length, opts) {
|
||||
@ -821,8 +851,8 @@ function write_HLinkTooltip(hl) {
|
||||
}
|
||||
|
||||
/* 2.4.63 */
|
||||
function parse_Country(blob, length) {
|
||||
var o = [], d;
|
||||
function parse_Country(blob, length)/*:[string|number, string|number]*/ {
|
||||
var o = [0,0], d;
|
||||
d = blob.read_shift(2); o[0] = CountryEnum[d] || d;
|
||||
d = blob.read_shift(2); o[1] = CountryEnum[d] || d;
|
||||
return o;
|
||||
|
@ -86,10 +86,11 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
d.l+=2;
|
||||
}
|
||||
if(l7) d.l += 36;
|
||||
var fields = [], field = {};
|
||||
/*:: type DBFField = { name:string; len:number; type:string; } */
|
||||
var fields/*:Array<DBFField>*/ = [], field/*:DBFField*/ = ({}/*:any*/);
|
||||
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 = ({}/*:any*/);
|
||||
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));
|
||||
@ -210,7 +211,7 @@ function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
|
||||
if(headers.indexOf(headers[i] + "_" + j) == -1) { headers[i] += "_" + j; break; }
|
||||
}
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
var coltypes = [];
|
||||
var coltypes/*:Array<string>*/ = [];
|
||||
for(i = 0; i <= range.e.c - range.s.c; ++i) {
|
||||
var col/*:Array<any>*/ = [];
|
||||
for(j=0; j < data.length; ++j) {
|
||||
@ -307,10 +308,10 @@ var SYLK = (function() {
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ {
|
||||
var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = [];
|
||||
var formats = [];
|
||||
var next_cell_format = null;
|
||||
var sht = {}, rowinfo = [], colinfo = [], cw = [];
|
||||
var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr/*:AOA*/ = [];
|
||||
var formats/*:Array<string>*/ = [];
|
||||
var next_cell_format/*:string|null*/ = null;
|
||||
var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
|
||||
var Mval = 0, j;
|
||||
for (; ri !== records.length; ++ri) {
|
||||
Mval = 0;
|
||||
@ -484,7 +485,7 @@ var DIF = (function() {
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
function dif_to_aoa_str(str/*:string*/, opts)/*:AOA*/ {
|
||||
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
|
||||
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
|
||||
for (; ri !== records.length; ++ri) {
|
||||
if (records[ri].trim() === 'BOT') { arr[++R] = []; C = 0; continue; }
|
||||
if (R < 0) continue;
|
||||
@ -585,7 +586,7 @@ var ETH = (function() {
|
||||
function encode(s/*:string*/)/*:string*/ { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
|
||||
|
||||
function eth_to_aoa(str/*:string*/, opts)/*:AOA*/ {
|
||||
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
|
||||
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
|
||||
for (; ri !== records.length; ++ri) {
|
||||
var record = records[ri].trim().split(":");
|
||||
if(record[0] !== 'cell') continue;
|
||||
@ -632,7 +633,7 @@ var ETH = (function() {
|
||||
|
||||
function sheet_to_eth_data(ws/*:Worksheet*/)/*:string*/ {
|
||||
if(!ws || !ws['!ref']) return "";
|
||||
var o = [], oo = [], cell, coord;
|
||||
var o/*:Array<string>*/ = [], oo/*:Array<string>*/ = [], cell, coord = "";
|
||||
var r = decode_range(ws['!ref']);
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
@ -648,12 +649,12 @@ var ETH = (function() {
|
||||
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
|
||||
break;
|
||||
case 'b':
|
||||
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
|
||||
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
|
||||
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
|
||||
break;
|
||||
case 'd':
|
||||
var t = datenum(parseDate(cell.v));
|
||||
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
|
||||
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
|
||||
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
|
||||
break;
|
||||
case 'e': continue;
|
||||
@ -840,7 +841,7 @@ var PRN = (function() {
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var oo = [];
|
||||
var oo/*:Array<string>*/ = [];
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C] : ws[coord];
|
||||
|
@ -1,27 +1,3 @@
|
||||
/* 18.4.1 charset to codepage mapping */
|
||||
var CS2CP = ({
|
||||
/*::[*/0/*::]*/: 1252, /* ANSI */
|
||||
/*::[*/1/*::]*/: 65001, /* DEFAULT */
|
||||
/*::[*/2/*::]*/: 65001, /* SYMBOL */
|
||||
/*::[*/77/*::]*/: 10000, /* MAC */
|
||||
/*::[*/128/*::]*/: 932, /* SHIFTJIS */
|
||||
/*::[*/129/*::]*/: 949, /* HANGUL */
|
||||
/*::[*/130/*::]*/: 1361, /* JOHAB */
|
||||
/*::[*/134/*::]*/: 936, /* GB2312 */
|
||||
/*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
|
||||
/*::[*/161/*::]*/: 1253, /* GREEK */
|
||||
/*::[*/162/*::]*/: 1254, /* TURKISH */
|
||||
/*::[*/163/*::]*/: 1258, /* VIETNAMESE */
|
||||
/*::[*/177/*::]*/: 1255, /* HEBREW */
|
||||
/*::[*/178/*::]*/: 1256, /* ARABIC */
|
||||
/*::[*/186/*::]*/: 1257, /* BALTIC */
|
||||
/*::[*/204/*::]*/: 1251, /* RUSSIAN */
|
||||
/*::[*/222/*::]*/: 874, /* THAI */
|
||||
/*::[*/238/*::]*/: 1250, /* EASTEUROPE */
|
||||
/*::[*/255/*::]*/: 1252, /* OEM */
|
||||
/*::[*/69/*::]*/: 6969 /* MISC */
|
||||
}/*:any*/);
|
||||
|
||||
/* Parse a list of <r> tags */
|
||||
var parse_rs = (function parse_rs_factory() {
|
||||
var tregex = matchtag("t"), rpregex = matchtag("rPr"), rregex = /<(?:\w+:)?r>/g, rend = /<\/(?:\w+:)?r>/, nlregex = /\r\n/g;
|
||||
@ -122,7 +98,7 @@ var parse_rs = (function parse_rs_factory() {
|
||||
if(y[0].charCodeAt(1) !== 47) throw 'Unrecognized rich format ' + y[0];
|
||||
}
|
||||
}
|
||||
var style = [];
|
||||
var style/*:Array<string>*/ = [];
|
||||
|
||||
if(font.u) style.push("text-decoration: underline;");
|
||||
if(font.uval) style.push("text-underline-style:" + font.uval + ";");
|
||||
@ -145,14 +121,14 @@ var parse_rs = (function parse_rs_factory() {
|
||||
|
||||
/* 18.4.4 r CT_RElt */
|
||||
function parse_r(r) {
|
||||
var terms = [[],"",[]];
|
||||
var terms/*:[Array<string>, string, Array<string>]*/ = [[],"",[]];
|
||||
/* 18.4.12 t ST_Xstring */
|
||||
var t = r.match(tregex), cp = 65001;
|
||||
if(!isval(t)/*:: || !t*/) return "";
|
||||
if(!t) return "";
|
||||
terms[1] = t[1];
|
||||
|
||||
var rpr = r.match(rpregex);
|
||||
if(isval(rpr)/*:: && rpr*/) cp = parse_rpr(rpr[1], terms[0], terms[2]);
|
||||
if(rpr) cp = parse_rpr(rpr[1], terms[0], terms[2]);
|
||||
|
||||
return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
|
||||
}
|
||||
@ -196,7 +172,7 @@ function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
|
||||
if(!data) return s;
|
||||
/* 18.4.9 sst CT_Sst */
|
||||
var sst = data.match(sstr0);
|
||||
if(isval(sst)/*:: && sst*/) {
|
||||
if(sst) {
|
||||
ss = sst[2].replace(sstr1,"").split(sstr2);
|
||||
for(var i = 0; i != ss.length; ++i) {
|
||||
var o = parse_si(ss[i].trim(), opts);
|
||||
|
@ -1,6 +1,6 @@
|
||||
function _JS2ANSI(str/*:string*/)/*:Array<number>*/ {
|
||||
if(typeof cptable !== 'undefined') return cptable.utils.encode(1252, str);
|
||||
var o = [], oo = str.split("");
|
||||
if(typeof cptable !== 'undefined') return cptable.utils.encode(current_ansi, str);
|
||||
var o/*:Array<number>*/ = [], oo = str.split("");
|
||||
for(var i = 0; i < oo.length; ++i) o[i] = oo[i].charCodeAt(0);
|
||||
return o;
|
||||
}
|
||||
@ -31,14 +31,9 @@ function parse_DataSpaceMapEntry(blob) {
|
||||
var end = blob.l + len - 4;
|
||||
var o = {};
|
||||
var cnt = blob.read_shift(4);
|
||||
var comps = [];
|
||||
while(cnt-- > 0) {
|
||||
/* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
|
||||
var rc = {};
|
||||
rc.t = blob.read_shift(4);
|
||||
rc.v = blob.read_shift(0, 'lpp4');
|
||||
comps.push(rc);
|
||||
}
|
||||
var comps/*:Array<{t:number, v:string}>*/ = [];
|
||||
/* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
|
||||
while(cnt-- > 0) comps.push({ t: blob.read_shift(4), v: blob.read_shift(0, 'lpp4') });
|
||||
o.name = blob.read_shift(0, 'lpp4');
|
||||
o.comps = comps;
|
||||
if(blob.l != end) throw new Error("Bad DataSpaceMapEntry: " + blob.l + " != " + end);
|
||||
@ -55,8 +50,8 @@ function parse_DataSpaceMap(blob, length) {
|
||||
}
|
||||
|
||||
/* [MS-OFFCRYPTO] 2.1.7 DataSpaceDefinition */
|
||||
function parse_DataSpaceDefinition(blob, length) {
|
||||
var o = [];
|
||||
function parse_DataSpaceDefinition(blob, length)/*:Array<string>*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
blob.l += 4; // must be 0x8
|
||||
var cnt = blob.read_shift(4);
|
||||
while(cnt-- > 0) o.push(blob.read_shift(0, 'lpp4'));
|
||||
|
@ -321,7 +321,7 @@ function parse_cellXfs(t, styles, opts) {
|
||||
}
|
||||
|
||||
function write_cellXfs(cellXfs)/*:string*/ {
|
||||
var o = [];
|
||||
var o/*:Array<string>*/ = [];
|
||||
o[o.length] = (writextag('cellXfs',null));
|
||||
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
|
||||
o[o.length] = ("</cellXfs>");
|
||||
|
@ -206,7 +206,7 @@ function parse_sty_bin(data, themes, opts) {
|
||||
|
||||
styles.CellXf = [];
|
||||
styles.Fonts = [];
|
||||
var state = [];
|
||||
var state/*:Array<string>*/ = [];
|
||||
var pass = false;
|
||||
recordhopper(data, function hopper_sty(val, R_n, RT) {
|
||||
switch(RT) {
|
||||
|
@ -1,8 +1,15 @@
|
||||
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
|
||||
function parse_Theme(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var dwThemeVersion = blob.read_shift(4);
|
||||
if(dwThemeVersion === 124226) return;
|
||||
blob.l += length-4;
|
||||
if(!opts.cellStyles || !jszip) { blob.l = end; return; }
|
||||
var data = blob.slice(blob.l);
|
||||
blob.l = end;
|
||||
var zip; try { zip = new jszip(data); } catch(e) { return; }
|
||||
var themeXML = getzipstr(zip, "theme/theme/theme1.xml", true);
|
||||
if(!themeXML) return;
|
||||
return parse_theme_xml(themeXML, opts);
|
||||
}
|
||||
|
||||
/* 2.5.49 */
|
||||
@ -35,7 +42,7 @@ function parse_XFExtGradient(blob, length) {
|
||||
}
|
||||
|
||||
/* 2.5.108 */
|
||||
function parse_ExtProp(blob, length) {
|
||||
function parse_ExtProp(blob, length)/*:Array<any>*/ {
|
||||
var extType = blob.read_shift(2);
|
||||
var cb = blob.read_shift(2);
|
||||
var o = [extType];
|
||||
@ -57,7 +64,7 @@ function parse_XFExt(blob, length) {
|
||||
var ixfe = blob.read_shift(2);
|
||||
blob.l += 2;
|
||||
var cexts = blob.read_shift(2);
|
||||
var ext = [];
|
||||
var ext/*:AOA*/ = [];
|
||||
while(cexts-- > 0) ext.push(parse_ExtProp(blob, end-blob.l));
|
||||
return {ixfe:ixfe, ext:ext};
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
function insertCommentsIntoSheet(sheetName, sheet, comments) {
|
||||
function insertCommentsIntoSheet(sheetName, sheet, comments/*:Array<RawComment>*/) {
|
||||
var dense = Array.isArray(sheet);
|
||||
var cell, r;
|
||||
var cell/*:Cell*/, r;
|
||||
comments.forEach(function(comment) {
|
||||
if(dense) {
|
||||
r = decode_cell(comment.ref);
|
||||
@ -42,7 +42,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments) {
|
||||
}
|
||||
|
||||
if (!cell.c) cell.c = [];
|
||||
var o = ({a: comment.author, t: comment.t, r: comment.r}/*:any*/);
|
||||
var o/*:Comment*/ = ({a: comment.author, t: comment.t, r: comment.r});
|
||||
if(comment.h) o.h = comment.h;
|
||||
cell.c.push(o);
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
/* 18.7 Comments */
|
||||
function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
|
||||
function parse_comments_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
|
||||
/* 18.7.6 CT_Comments */
|
||||
if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
|
||||
var authors = [];
|
||||
var commentList = [];
|
||||
var authors/*:Array<string>*/ = [];
|
||||
var commentList/*:Array<RawComment>*/ = [];
|
||||
var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
|
||||
if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
|
||||
if(x === "" || x.trim() === "") return;
|
||||
@ -16,7 +16,7 @@ function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
|
||||
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
|
||||
if(!cm) return;
|
||||
var y = parsexmltag(cm[0]);
|
||||
var comment/*:Comment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
|
||||
var comment/*:RawComment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
|
||||
var cell = decode_cell(y.ref);
|
||||
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
|
||||
var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
|
||||
@ -34,7 +34,7 @@ var CMNT_XML_ROOT = writextag('comments', null, { 'xmlns': XMLNS.main[0] });
|
||||
function write_comments_xml(data, opts) {
|
||||
var o = [XML_HEADER, CMNT_XML_ROOT];
|
||||
|
||||
var iauthor = [];
|
||||
var iauthor/*:Array<string>*/ = [];
|
||||
o.push("<authors>");
|
||||
data.map(function(x) { return x[1]; }).forEach(function(comment) {
|
||||
comment.map(function(x) { return escapexml(x.a); }).forEach(function(a) {
|
||||
|
@ -24,9 +24,9 @@ var parse_BrtCommentAuthor = parse_XLWideString;
|
||||
function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); }
|
||||
|
||||
/* [MS-XLSB] 2.1.7.8 Comments */
|
||||
function parse_comments_bin(data, opts) {
|
||||
var out = [];
|
||||
var authors = [];
|
||||
function parse_comments_bin(data, opts)/*:Array<RawComment>*/ {
|
||||
var out/*:Array<RawComment>*/ = [];
|
||||
var authors/*:Array<string>*/ = [];
|
||||
var c = {};
|
||||
var pass = false;
|
||||
recordhopper(data, function hopper_cmnt(val, R_n, RT) {
|
||||
@ -65,33 +65,32 @@ function parse_comments_bin(data, opts) {
|
||||
|
||||
function write_comments_bin(data, opts) {
|
||||
var ba = buf_array();
|
||||
var iauthor = [];
|
||||
var iauthor/*:Array<string>*/ = [];
|
||||
write_record(ba, "BrtBeginComments");
|
||||
{ /* COMMENTAUTHORS */
|
||||
write_record(ba, "BrtBeginCommentAuthors");
|
||||
data.forEach(function(comment) {
|
||||
comment[1].forEach(function(c) {
|
||||
if(iauthor.indexOf(c.a) > -1) return;
|
||||
iauthor.push(c.a.slice(0,54));
|
||||
write_record(ba, "BrtCommentAuthor", write_BrtCommentAuthor(c.a));
|
||||
});
|
||||