1
Fork 0

version bump 0.8.3: BIFF2 read/write

- basic support for parsing BIFF2-4
- basic support for writing BIFF2
- cleaned up some bad substr uses for IE6 compatibility
- added flow type annotations for xlsx.flow.js
- added numerous null guards (fixes #255 h/t @martinheidegger)
- README cleanup (fixes #539 h/t @oliversalzburg)
- pin jszip to local version (closes #408 h/t @limouri)

bower issues:

|  id  | author            | comment                                   |
|-----:|:------------------|:------------------------------------------|
| #254 | @kkirsche         | fixes #254 by removing version from json  |
| #165 | @vincentcialdella | fixes #165 by changing default script     |
| #180 | @owencraig        | fixes #180 by using xlsx.core.min.js      |

format issues:

|  id  | author            | comment                                   |
|-----:|:------------------|:------------------------------------------|
| #271 | @morstaine        | fixes #271 by reworking related parse fns |
| #504 | @JanSchuermannPH  | fixes #504 detect FullPaths h/t @Mithgol  |
| #508 | @basma-emad       | fixes #508 offending file used `x:` NS    |
This commit is contained in:
SheetJS 2017-02-10 11:23:01 -08:00
parent 06670ae181
commit ab2ecebac9
79 changed files with 12655 additions and 10956 deletions

View File

@ -19,17 +19,20 @@
.*/xlsxworker2.js
.*/jszip.js
.*/tests/.*
.*/demos/.*
.*/xlsx.flow.js
#.*/xlsx.flow.js
[include]
xlsxworker.flow.js
xlsxworker1.flow.js
xlsxworker2.flow.js
xlsx.flow.js
ods.flow.js
.*/bin/.*.njs
.*/demo/browser.flow.js
[libs]
bits/09_types.js
misc/flow.js
misc/flowdeps.js
@ -37,3 +40,4 @@ misc/flowdeps.js
module.file_ext=.js
module.file_ext=.njs
module.ignore_non_literal_requires=true
suppress_comment= \\(.\\|\n\\)*\\$FlowIgnore

View File

@ -10,6 +10,7 @@ tmp
*.prn
*.slk
*.socialcalc
*.XLS
*.xls
*.xlsb
*.xlsm
@ -32,6 +33,7 @@ test.js
.gitmodules
.travis.yml
.flowconfig
*.flow.js
bits/
odsbits/
tests/

View File

@ -10,7 +10,7 @@ node_js:
- "0.8"
before_install:
- "npm install -g npm@next"
- "npm install -g mocha voc"
- "npm install -g mocha@2.x voc"
- "npm install blanket"
- "npm install xlsjs"
- "npm install coveralls mocha-lcov-reporter"

View File

@ -14,6 +14,7 @@ FLOWTARGET=$(LIB).flow.js
FLOWAUX=$(patsubst %.js,%.flow.js,$(AUXTARGETS))
AUXSCPTS=xlsxworker1.js xlsxworker2.js xlsxworker.js
FLOWTGTS=$(TARGET) $(AUXTARGETS) $(AUXSCPTS)
UGLIFYOPTS=--support-ie8
## Main Targets
@ -34,7 +35,7 @@ bits/18_cfb.js: node_modules/cfb/dist/xlscfb.js
.PHONY: clean
clean: ## Remove targets and build artifacts
rm -f $(TARGET)
rm -f $(TARGET) $(FLOWTARGET)
.PHONY: clean-data
clean-data:
@ -52,11 +53,11 @@ init: ## Initial setup for development
dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
cp $(TARGET) dist/
cp LICENSE dist/
uglifyjs $(TARGET) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(UGLIFYOPTS) $(TARGET) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).min.js
uglifyjs $(REQS) $(TARGET) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(UGLIFYOPTS) $(REQS) $(TARGET) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).core.min.js
uglifyjs $(REQS) $(ADDONS) $(TARGET) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(UGLIFYOPTS) $(REQS) $(ADDONS) $(TARGET) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).full.min.js
.PHONY: dist-deps
@ -64,12 +65,9 @@ dist-deps: ods.js ## Copy dependencies for distribution
cp node_modules/codepage/dist/cpexcel.full.js dist/cpexcel.js
cp jszip.js dist/jszip.js
cp ods.js dist/ods.js
uglifyjs ods.js -o dist/ods.min.js --source-map dist/ods.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(UGLIFYOPTS) ods.js -o dist/ods.min.js --source-map dist/ods.min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/ods.min.js
bower.json: misc/_bower.json package.json
cat $< | sed 's/_VERSION_/'`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`'/' > $@
.PHONY: aux
aux: $(AUXTARGETS)
@ -108,7 +106,7 @@ lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
flow: lint ## Run flow checker
@flow check --all --show-all-errors
.PHONY: cov cov-spin
.PHONY: cov
cov: misc/coverage.html ## Run coverage test
#* To run coverage tests for one format, make cov_<fmt>
@ -120,7 +118,7 @@ $(COVFMT): cov_%:
misc/coverage.html: $(TARGET) test.js
mocha --require blanket -R html-cov -t 20000 > $@
.PHONY: coveralls coveralls-spin
.PHONY: coveralls
coveralls: ## Coverage Test + Send to coveralls.io
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js

View File

@ -6,16 +6,18 @@ implementation from official specifications and related documents.
Supported read formats:
- Excel 2007+ XML Formats (XLSX/XLSM)
- Excel 2007+ Binary Format (XLSB)
- Excel 2007+ Binary Format (XLSB BIFF12)
- Excel 2003-2004 XML Format (XML "SpreadsheetML")
- Excel 97-2004 (XLS BIFF8)
- Excel 5.0/95 (XLS BIFF5)
- Excel 2.0/3.0/4.0 (XLS BIFF2/BIFF3/BIFF4)
- OpenDocument Spreadsheet (ODS)
Supported write formats:
- Excel 2007+ XML Formats (XLSX/XLSM)
- Excel 2007+ Binary Format (XLSB) nodejs only
- Excel 2.0 (XLS BIFF2, compatible with *every version* of Excel)
- Excel 2007+ XML Formats (XLSX/XLSM, compatible with Excel 2007+)
- Excel 2007+ Binary Format (XLSB, compatible with Excel 2007+)
- CSV (and general DSV)
- JSON and JS objects (various styles)
- OpenDocument Spreadsheet (ODS)
@ -26,6 +28,7 @@ Source: <http://git.io/xlsx>
Paid support available through the [reinforcements program](http://sheetjs.com/reinforcements)
## Installation
With [npm](https://www.npmjs.org/package/xlsx):
@ -198,11 +201,6 @@ function handleFile(e) {
input_dom_element.addEventListener('change', handleFile, false);
```
The readAsArrayBuffer form requires some preprocessing:
```js
```
## Working with the Workbook
The full object format is described later in this README.
@ -277,10 +275,11 @@ XLSX.writeFile(workbook, 'out.xlsx');
/* at this point, out.xlsx is a file that you can distribute */
```
- write to binary string (using FileSaver.js):
- browser generate binary blob and "download" to client
(using [FileSaver.js](https://github.com/eligrey/FileSaver.js/) for download):
```js
/* bookType can be 'xlsx' or 'xlsm' or 'xlsb' */
/* bookType can be 'xlsx' or 'xlsm' or 'xlsb' or 'ods' */
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
var wbout = XLSX.write(workbook,wopts);
@ -508,28 +507,43 @@ The defaults are enumerated in bits/84\_defaults.js
The exported `write` and `writeFile` functions accept an options argument:
| Option Name | Default | Description |
| :---------- | ------: | :--------------------------------------------------- |
| cellDates | `false` | Store dates as type `d` (default is `n`) |
| bookSST | `false` | Generate Shared String Table ** |
| bookType | 'xlsx' | Type of Workbook ("xlsx" or "xlsm" or "xlsb") |
| compression | `false` | Use file compression for formats with ZIP containers |
| Option Name | Default | Description |
| :---------- | -------: | :-------------------------------------------------- |
| cellDates | `false` | Store dates as type `d` (default is `n`) |
| bookSST | `false` | Generate Shared String Table ** |
| bookType | `"xlsx"` | Type of Workbook (see below for supported formats) |
| sheet | `""` | Name of Worksheet for single-sheet formats ** |
| compression | `false` | Use ZIP compression for ZIP-based formats ** |
- `bookSST` is slower and more memory intensive, but has better compatibility
with older versions of iOS Numbers
- `bookType = 'xlsb'` is stubbed and far from complete
- The raw data is the only thing guaranteed to be saved. Formulae, formatting,
and other niceties may not be serialized (pending CSF standardization)
- `cellDates` only applies to XLSX output and is not guaranteed to work with
third-party readers. Excel itself does not usually write cells with type `d`
so non-Excel tools may ignore the data or blow up in the presence of dates.
Supported output formats (`bookType`):
| bookType | file ext | container | sheets | Description |
| :------- | -------: | :-------: | :----- |:---------------------------- |
| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format |
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
- `compression` only applies to formats with ZIP containers.
- Formats that only support a single sheet require a `sheet` option specifying
the worksheet. If the string is empty, the first worksheet is used.
## Tested Environments
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
- IE 6/7/8/9/10/11 using Base64 mode (IE10/11 using HTML5 mode)
- FF 18 using Base64 or HTML5 mode
- Chrome 24 using Base64 or HTML5 mode
- IE 6/7/8/9/10/11 (IE6-9 browsers require shims for interacting with client)
- Chrome 24+
- Safari 6+
- FF 18+
Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:

View File

@ -16,13 +16,16 @@ 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('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
.option('-S, --formulae', 'print formulae')
.option('-j, --json', 'emit formatted JSON (all fields text)')
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
.option('--sst', 'generate sst')
.option('--sst', 'generate shared string table for XLS* formats')
.option('--compress', 'use compression when writing XLSX/M/B and ODS')
.option('--perf', 'do not generate output')
.option('--all', 'parse everything; XLS[XMB] write as much as possible')
.option('--dev', 'development mode')
@ -104,11 +107,14 @@ if(program.listSheets) {
process.exit(0);
}
var wopts = {WTF:opts.WTF, bookSST:program.sst};
var wopts = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
if(program.compress) wopts.compression = true;
if(program.xlsx) { X.writeFile(wb, sheetname || (filename + ".xlsx"), wopts); process.exit(0); }
if(program.xlsm) { X.writeFile(wb, sheetname || (filename + ".xlsm"), wopts); process.exit(0); }
if(program.xlsb) { X.writeFile(wb, sheetname || (filename + ".xlsb"), wopts); process.exit(0); }
/* full workbook formats */
['xlsx', 'xlsm', 'xlsb', 'ods'].forEach(function(m) { if(program[m]) {
X.writeFile(wb, sheetname || ((filename || "") + "." + m), wopts);
process.exit(0);
} });
var target_sheet = sheetname || '';
if(target_sheet === '') target_sheet = wb.SheetNames[0];
@ -124,6 +130,13 @@ try {
if(program.perf) process.exit(0);
/* single worksheet XLS formats */
['biff2'].forEach(function(m) { if(program[m]) {
wopts.bookType = m;
X.writeFile(wb, sheetname || ((filename || "") + ".xls"), wopts);
process.exit(0);
} });
var oo = "";
if(!program.quiet) console.error(target_sheet);
if(program.formulae) oo = X.utils.get_formulae(ws).join("\n");

View File

@ -1 +1 @@
XLSX.version = '0.8.2';
XLSX.version = '0.8.3';

View File

@ -1,12 +1,12 @@
var has_buf = (typeof Buffer !== 'undefined');
function new_raw_buf(len) {
function new_raw_buf(len/*:number*/) {
/* jshint -W056 */
return new (has_buf ? Buffer : Array)(len);
/* jshint +W056 */
}
function s2a(s) {
function s2a(s/*:string*/) {
if(has_buf) return new Buffer(s, "binary");
return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; });
}

View File

@ -1,8 +1,17 @@
/*::
declare type Block = any;
declare type BufArray = {
newblk(sz:number):Block;
next(sz:number):Block;
end():any;
push(buf:Block):void;
};
type RecordHopperCB = {(d:any, R:any, RT:number):?boolean;};
type EvertType = {[string]:string};
type EvertNumType = {[string]:number};
type EvertArrType = {[string]:Array<string>};
type StringConv = {(string):string};
*/

View File

@ -1,5 +1,5 @@
/* map from xlml named formats to SSF TODO: localize */
var XLMLFormatMap = {
var XLMLFormatMap/*{[string]:string}*/ = ({
"General Number": "General",
"General Date": SSF._table[22],
"Long Date": "dddd, mmmm dd, yyyy",
@ -16,5 +16,5 @@ var XLMLFormatMap = {
"Yes/No": '"Yes";"Yes";"No";@',
"True/False": '"True";"True";"False";@',
"On/Off": '"Yes";"Yes";"No";@'
};
}/*:any*/);

View File

@ -1,27 +1,27 @@
function isval(x/*:?any*/)/*:boolean*/ { return x !== undefined && x !== null; }
function keys(o) { return Object.keys(o); }
function keys(o/*:any*/)/*:Array<any>*/ { return Object.keys(o); }
function evert_key(obj, key) {
var o = [], K = keys(obj);
function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ {
var o = ([]/*:any*/), K = keys(obj);
for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i];
return o;
}
function evert(obj) {
var o = [], K = keys(obj);
function evert(obj/*:any*/)/*:EvertType*/ {
var o = ([]/*:any*/), K = keys(obj);
for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i];
return o;
}
function evert_num(obj) {
var o = [], K = keys(obj);
function evert_num(obj/*:any*/)/*:EvertNumType*/ {
var o = ([]/*:any*/), K = keys(obj);
for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i],10);
return o;
}
function evert_arr(obj) {
var o = [], K = keys(obj);
function evert_arr(obj/*:any*/)/*:EvertArrType*/ {
var o/*:EvertArrType*/ = ([]/*:any*/), K = keys(obj);
for(var i = 0; i !== K.length; ++i) {
if(o[obj[K[i]]] == null) o[obj[K[i]]] = [];
o[obj[K[i]]].push(K[i]);
@ -30,7 +30,7 @@ function evert_arr(obj) {
}
/* TODO: date1904 logic */
function datenum(v, date1904) {
function datenum(v/*:number*/, date1904/*:?boolean*/)/*:number*/ {
if(date1904) v+=1462;
var epoch = Date.parse(v);
return (epoch + 2209161600000) / (24 * 60 * 60 * 1000);

View File

@ -1,44 +1,53 @@
function getdata(data) {
function getdatastr(data)/*:?string*/ {
if(!data) return null;
if(data.name.substr(-4) === ".bin") {
if(data.data) return char_codes(data.data);
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
} else {
if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data);
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom_xml(data.asBinary());
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
}
if(data.data) return debom_xml(data.data);
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom_xml(data.asBinary());
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
return null;
}
function safegetzipfile(zip, file) {
function getdatabin(data) {
if(!data) return null;
if(data.data) return char_codes(data.data);
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
return null;
}
function getdata(data) { return (data && data.name.substr(data.name.length-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
function safegetzipfile(zip, file/*:string*/) {
var f = file; if(zip.files[f]) return zip.files[f];
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
return null;
}
function getzipfile(zip, file) {
function getzipfile(zip, file/*:string*/) {
var o = safegetzipfile(zip, file);
if(o == null) throw new Error("Cannot find file " + file + " in zip");
return o;
}
function getzipdata(zip, file, safe/*:?boolean*/) {
function getzipdata(zip, file/*:string*/, safe/*:?boolean*/) {
if(!safe) return getdata(getzipfile(zip, file));
if(!file) return null;
try { return getzipdata(zip, file); } catch(e) { return null; }
}
/*:: declare var JSZip:any; */
function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ {
if(!safe) return getdatastr(getzipfile(zip, file));
if(!file) return null;
try { return getzipstr(zip, file); } catch(e) { return null; }
}
var _fs, jszip;
/*:: declare var JSZip:any; */
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
if(typeof jszip === 'undefined') jszip = require('./js'+'zip');
_fs = require('f'+'s');
}
}

View File

@ -1,8 +1,8 @@
var attregexg=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var tagregex=/<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag, skip_root) {
var z = [];
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
var z = ([]/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.substr(0, eq);
@ -18,7 +18,7 @@ function parsexmltag(tag, skip_root) {
}
return z;
}
function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {
'&quot;': '"',
@ -31,28 +31,28 @@ var rencoding = evert(encodings);
var rencstr = "&<>'\"".split("");
// TODO: CP remap (need to read file version to determine OS)
var unescapexml = (function() {
var unescapexml/*:StringConv*/ = (function() {
var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g;
return function unescapexml(text){
return function unescapexml(text/*:string*/)/*:string*/ {
var s = text + '';
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
};
})();
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
function escapexml(text){
function escapexml(text/*:string*/)/*:string*/{
var s = text + '';
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
}
/* TODO: handle codepages */
var xlml_fixstr = (function() {
var xlml_fixstr/*:StringConv*/ = (function() {
var entregex = /&#(\d+);/g;
function entrepl($$,$1) { return String.fromCharCode(parseInt($1,10)); }
return function xlml_fixstr(str) { return str.replace(entregex,entrepl); };
function entrepl($$/*:string*/,$1/*:string*/)/*:string*/ { return String.fromCharCode(parseInt($1,10)); }
return function xlml_fixstr(str/*:string*/)/*:string*/ { return str.replace(entregex,entrepl); };
})();
function parsexmlbool(value, tag) {
function parsexmlbool(value/*:any*/, tag/*:?string*/)/*:boolean*/ {
switch(value) {
case '1': case 'true': case 'TRUE': return true;
/* case '0': case 'false': case 'FALSE':*/
@ -60,7 +60,7 @@ function parsexmlbool(value, tag) {
}
}
var utf8read = function utf8reada(orig) {
var utf8read/*:StringConv*/ = function utf8reada(orig) {
var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0;
while (i < orig.length) {
c = orig.charCodeAt(i++);
@ -106,7 +106,7 @@ if(has_buf) {
var matchtag = (function() {
var mtcache = {};
return function matchtag(f,g) {
var t = f+"|"+g;
var t = f+"|"+(g||"");
if(mtcache[t] !== undefined) return mtcache[t];
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")));
};
@ -122,7 +122,7 @@ function parseVector(data) {
var h = parsexmltag(data);
var matches = data.match(vtregex(h.baseType))||[];
if(matches.length != h.size) throw "unexpected vector length " + matches.length + " != " + h.size;
if(matches.length != h.size) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
var res = [];
matches.forEach(function(x) {
var v = x.replace(vtvregex,"").match(vtmregex);
@ -134,10 +134,10 @@ function parseVector(data) {
var wtregex = /(^\s|\s$|\n)/;
function writetag(f,g) {return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>';}
function wxt_helper(h) { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); }
function writextag(f,g,h) { return '<' + f + (isval(h) ? wxt_helper(h) : "") + (isval(g) ? (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 write_w3cdtf(d, t) { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } }
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) {
switch(typeof s) {
@ -150,7 +150,7 @@ function write_vt(s) {
}
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var XMLNS = {
var XMLNS = ({
'dc': 'http://purl.org/dc/elements/1.1/',
'dcterms': 'http://purl.org/dc/terms/',
'dcmitype': 'http://purl.org/dc/dcmitype/',
@ -160,7 +160,7 @@ var XMLNS = {
'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xsd': 'http://www.w3.org/2001/XMLSchema'
};
}/*:any*/);
XMLNS.main = [
'http://schemas.openxmlformats.org/spreadsheetml/2006/main',

View File

@ -1,19 +1,27 @@
function readIEEE754(buf, idx, isLE, nl, ml) {
if(isLE === undefined) isLE = true;
if(!nl) nl = 8;
if(!ml && nl === 8) ml = 52;
var e, m, el = nl * 8 - ml - 1, eMax = (1 << el) - 1, eBias = eMax >> 1;
var bits = -7, d = isLE ? -1 : 1, i = isLE ? (nl - 1) : 0, s = buf[idx + i];
function read_double_le(b, idx/*:number*/)/*:number*/ {
var s = 1 - 2 * (b[idx + 7] >>> 7);
var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
var m = (b[idx+6]&0x0f);
for(var i = 5; i >= 0; --i) m = m * 256 + b[idx + i];
if(e == 0x7ff) return m == 0 ? s * Infinity : NaN;
if(e == 0) e = -1022;
else { e -= 1023; m += Math.pow(2,52); }
return s * Math.pow(2, e - 52) * m;
}
i += d;
e = s & ((1 << (-bits)) - 1); s >>>= (-bits); bits += el;
for (; bits > 0; e = e * 256 + buf[idx + i], i += d, bits -= 8);
m = e & ((1 << (-bits)) - 1); e >>>= (-bits); bits += ml;
for (; bits > 0; m = m * 256 + buf[idx + i], i += d, bits -= 8);
if (e === eMax) return m ? NaN : ((s ? -1 : 1) * Infinity);
else if (e === 0) e = 1 - eBias;
else { m = m + Math.pow(2, ml); e = e - eBias; }
return (s ? -1 : 1) * m * Math.pow(2, e - ml);
function write_double_le(b, v/*:number*/, idx/*:number*/) {
var bs = ((v < 0 || 1/v == -Infinity) ? 1 : 0) << 7, e = 0, m = 0;
var av = bs ? -v : v;
if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }
else {
e = Math.floor(Math.log(av) * Math.LOG2E);
m = v * Math.pow(2, 52 - e);
if(e <= -1023 && (!isFinite(m) || m < Math.pow(2,52))) { e = -1022; }
else { m -= Math.pow(2,52); e+=1023; }
}
for(var i = 0; i <= 5; ++i, m/=256) b[idx + i] = m & 0xff;
b[idx + 6] = ((e & 0x0f) << 4) | m & 0xf;
b[idx + 7] = (e >> 4) | bs;
}
var __toBuffer, ___toBuffer;
@ -29,18 +37,18 @@ __lpstr = ___lpstr = function lpstr_(b,i) { var len = __readUInt32LE(b,i); retur
var __lpwstr, ___lpwstr;
__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
var __double, ___double;
__double = ___double = function(b, idx) { return readIEEE754(b, idx);};
__double = ___double = function(b, idx) { return read_double_le(b, idx);};
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
if(has_buf) {
if(has_buf/*:: && typeof Buffer != 'undefined'*/) {
__utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
__lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
__lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
__utf8 = function utf8_b(s,e) { return this.toString('utf8',s,e); };
__utf8 = function utf8_b(b, s,e) { return b.toString('utf8',s,e); };
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); };
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
__double = function double_(b,i) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
}
@ -125,20 +133,27 @@ function ReadShift(size, t) {
this.l+=size; return o;
}
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
function WriteShift(t, val, f) {
var size, i;
if(f === 'dbcs') {
for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i);
for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
size = 2 * val.length;
} else if(f === 'sbcs') {
for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
size = val.length;
} else switch(t) {
case 1: size = 1; this[this.l] = val&255; break;
case 2: size = 2; this[this.l] = val&255; val >>>= 8; this[this.l+1] = val&255; break;
case 3: size = 3; this[this.l] = val&255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l+2] = val&255; break;
case 4: size = 4; this.writeUInt32LE(val, this.l); break;
case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
case 1: size = 1; this[this.l] = val&0xFF; break;
case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;
case 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break;
case 4: size = 4; __writeUInt32LE(this, val, this.l); break;
case 8: size = 8; if(f === 'f') { write_double_le(this, val, this.l); break; }
/* falls through */
case 16: break;
case -4: size = 4; this.writeInt32LE(val, this.l); break;
case -4: size = 4; __writeInt32LE(this, val, this.l); break;
}
this.l += size; return this;
}

View File

@ -1,5 +1,6 @@
/* [MS-XLSB] 2.1.4 Record */
function recordhopper(data, cb, opts) {
function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
if(!data) return;
var tmpbyte, cntbyte, length;
prep_blob(data, data.l || 0);
while(data.l < data.length) {
@ -15,7 +16,7 @@ function recordhopper(data, cb, opts) {
}
/* control buffer usage for fixed-length buffers */
function buf_array() {
function buf_array()/*:BufArray*/ {
var bufs = [], blksz = 2048;
var newblk = function ba_newblk(sz) {
var o = new_buf(sz);
@ -26,13 +27,14 @@ function buf_array() {
var curbuf = newblk(blksz);
var endbuf = function ba_endbuf() {
if(!curbuf) return;
if(curbuf.length > curbuf.l) curbuf = curbuf.slice(0, curbuf.l);
if(curbuf.length > 0) bufs.push(curbuf);
curbuf = null;
};
var next = function ba_next(sz) {
if(sz < curbuf.length - curbuf.l) return curbuf;
if(curbuf && sz < curbuf.length - curbuf.l) return curbuf;
endbuf();
return (curbuf = newblk(Math.max(sz+1, blksz)));
};
@ -44,11 +46,12 @@ function buf_array() {
var push = function ba_push(buf) { endbuf(); curbuf = buf; next(blksz); };
return { next:next, push:push, end:end, _bufs:bufs };
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?number*/) {
var t = evert_RE[type], l;
var t/*:number*/ = Number(evert_RE[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;
if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;

View File

@ -25,11 +25,10 @@ var make_offcrypto = function(O, _crypto) {
return out;
};
if(crypto) {
O.md5 = function(hex) { return crypto.createHash('md5').update(hex).digest('hex'); };
} else {
O.md5 = function(hex) { throw "unimplemented"; };
}
O.md5 = function(hex) {
if(!crypto) throw new Error("Unsupported crypto");
return crypto.createHash('md5').update(hex).digest('hex');
};
};
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);

View File

@ -1,16 +1,16 @@
/* [MS-XLSB] 2.5.143 */
function parse_StrRun(data, length) {
function parse_StrRun(data, length/*:?number*/) {
return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
}
/* [MS-XLSB] 2.1.7.121 */
function parse_RichStr(data, length) {
function parse_RichStr(data, length/*:number*/) {
var start = data.l;
var flags = data.read_shift(1);
var str = parse_XLWideString(data);
var rgsStrRun = [];
var z = { t: str, h: str };
var z = ({ t: str, h: str }/*:any*/);
if((flags & 1) !== 0) { /* fRichStr */
/* TODO: formatted string */
var dwSizeStrRun = data.read_shift(4);
@ -43,7 +43,7 @@ function parse_XLSBCell(data) {
function write_XLSBCell(cell, o) {
if(o == null) o = new_buf(8);
o.write_shift(-4, cell.c);
o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s);
o.write_shift(3, cell.iStyleRef || cell.s);
o.write_shift(1, 0); /* fPhShow */
return o;
}
@ -53,11 +53,11 @@ function write_XLSBCell(cell, o) {
function parse_XLSBCodeName (data, length) { return parse_XLWideString(data, length); }
/* [MS-XLSB] 2.5.166 */
function parse_XLNullableWideString(data) {
function parse_XLNullableWideString(data)/*:string*/ {
var cchCharacters = data.read_shift(4);
return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLNullableWideString(data, o) {
function write_XLNullableWideString(data/*:string*/, o) {
if(!o) o = new_buf(127);
o.write_shift(4, data.length > 0 ? data.length : 0xFFFFFFFF);
if(data.length > 0) o.write_shift(0, data, 'dbcs');
@ -65,11 +65,11 @@ function write_XLNullableWideString(data, o) {
}
/* [MS-XLSB] 2.5.168 */
function parse_XLWideString(data) {
function parse_XLWideString(data)/*:string*/ {
var cchCharacters = data.read_shift(4);
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLWideString(data, o) {
function write_XLWideString(data/*:string*/, o) {
if(o == null) o = new_buf(4+2*data.length);
o.write_shift(4, data.length);
if(data.length > 0) o.write_shift(0, data, 'dbcs');
@ -83,7 +83,7 @@ var write_RelID = write_XLNullableWideString;
/* [MS-XLSB] 2.5.122 */
/* [MS-XLS] 2.5.217 */
function parse_RkNumber(data) {
function parse_RkNumber(data)/*:number*/ {
var b = data.slice(data.l, data.l+4);
var fX100 = b[0] & 1, fInt = b[0] & 2;
data.l+=4;
@ -102,8 +102,8 @@ function write_RkNumber(data/*:number*/, o) {
/* [MS-XLSB] 2.5.153 */
function parse_UncheckedRfX(data) {
var cell = {s: {}, e: {}};
function parse_UncheckedRfX(data)/*:Range*/ {
var cell/*:Range*/ = ({s: {}, e: {}}/*:any*/);
cell.s.r = data.read_shift(4);
cell.e.r = data.read_shift(4);
cell.s.c = data.read_shift(4);
@ -111,7 +111,7 @@ function parse_UncheckedRfX(data) {
return cell;
}
function write_UncheckedRfX(r, o) {
function write_UncheckedRfX(r/*:Range*/, o) {
if(!o) o = new_buf(16);
o.write_shift(4, r.s.r);
o.write_shift(4, r.e.r);
@ -123,25 +123,25 @@ function write_UncheckedRfX(r, o) {
/* [MS-XLSB] 2.5.171 */
/* [MS-XLS] 2.5.342 */
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
function parse_Xnum(data, length) { return data.read_shift(8, 'f'); }
function parse_Xnum(data, length/*:?number*/) { return data.read_shift(8, 'f'); }
function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, data, 'f'); }
/* [MS-XLSB] 2.5.198.2 */
var BErr = {
0x00: "#NULL!",
0x07: "#DIV/0!",
0x0F: "#VALUE!",
0x17: "#REF!",
0x1D: "#NAME?",
0x24: "#NUM!",
0x2A: "#N/A",
0x2B: "#GETTING_DATA",
0xFF: "#WTF?"
/*::[*/0x00/*::]*/: "#NULL!",
/*::[*/0x07/*::]*/: "#DIV/0!",
/*::[*/0x0F/*::]*/: "#VALUE!",
/*::[*/0x17/*::]*/: "#REF!",
/*::[*/0x1D/*::]*/: "#NAME?",
/*::[*/0x24/*::]*/: "#NUM!",
/*::[*/0x2A/*::]*/: "#N/A",
/*::[*/0x2B/*::]*/: "#GETTING_DATA",
/*::[*/0xFF/*::]*/: "#WTF?"
};
var RBErr = evert_num(BErr);
/* [MS-XLSB] 2.4.321 BrtColor */
function parse_BrtColor(data, length) {
function parse_BrtColor(data, length/*:number*/) {
var out = {};
var d = data.read_shift(1);
out.fValidRGB = d & 1;
@ -155,7 +155,7 @@ function parse_BrtColor(data, length) {
}
/* [MS-XLSB] 2.5.52 */
function parse_FontFlags(data, length) {
function parse_FontFlags(data, length/*:number*/) {
var d = data.read_shift(1);
data.l++;
var out = {

View File

@ -43,62 +43,62 @@
/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */
var DocSummaryPIDDSI = {
0x01: { n: 'CodePage', t: VT_I2 },
0x02: { n: 'Category', t: VT_STRING },
0x03: { n: 'PresentationFormat', t: VT_STRING },
0x04: { n: 'ByteCount', t: VT_I4 },
0x05: { n: 'LineCount', t: VT_I4 },
0x06: { n: 'ParagraphCount', t: VT_I4 },
0x07: { n: 'SlideCount', t: VT_I4 },
0x08: { n: 'NoteCount', t: VT_I4 },
0x09: { n: 'HiddenCount', t: VT_I4 },
0x0a: { n: 'MultimediaClipCount', t: VT_I4 },
0x0b: { n: 'Scale', t: VT_BOOL },
0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
0x0e: { n: 'Manager', t: VT_STRING },
0x0f: { n: 'Company', t: VT_STRING },
0x10: { n: 'LinksDirty', t: VT_BOOL },
0x11: { n: 'CharacterCount', t: VT_I4 },
0x13: { n: 'SharedDoc', t: VT_BOOL },
0x16: { n: 'HLinksChanged', t: VT_BOOL },
0x17: { n: 'AppVersion', t: VT_I4, p: 'version' },
0x1A: { n: 'ContentType', t: VT_STRING },
0x1B: { n: 'ContentStatus', t: VT_STRING },
0x1C: { n: 'Language', t: VT_STRING },
0x1D: { n: 'Version', t: VT_STRING },
0xFF: {}
/*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
/*::[*/0x02/*::]*/: { n: 'Category', t: VT_STRING },
/*::[*/0x03/*::]*/: { n: 'PresentationFormat', t: VT_STRING },
/*::[*/0x04/*::]*/: { n: 'ByteCount', t: VT_I4 },
/*::[*/0x05/*::]*/: { n: 'LineCount', t: VT_I4 },
/*::[*/0x06/*::]*/: { n: 'ParagraphCount', t: VT_I4 },
/*::[*/0x07/*::]*/: { n: 'SlideCount', t: VT_I4 },
/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 },
/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 },
/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 },
/*::[*/0x0b/*::]*/: { n: 'Scale', t: VT_BOOL },
/*::[*/0x0c/*::]*/: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT },
/*::[*/0x0d/*::]*/: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR },
/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING },
/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING },
/*::[*/0x10/*::]*/: { n: 'LinksDirty', t: VT_BOOL },
/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 },
/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL },
/*::[*/0x16/*::]*/: { n: 'HLinksChanged', t: VT_BOOL },
/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' },
/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING },
/*::[*/0x1B/*::]*/: { n: 'ContentStatus', t: VT_STRING },
/*::[*/0x1C/*::]*/: { n: 'Language', t: VT_STRING },
/*::[*/0x1D/*::]*/: { n: 'Version', t: VT_STRING },
/*::[*/0xFF/*::]*/: {}
};
/* [MS-OSHARED] 2.3.3.2.1.1 Summary Information Property Set PIDSI */
var SummaryPIDSI = {
0x01: { n: 'CodePage', t: VT_I2 },
0x02: { n: 'Title', t: VT_STRING },
0x03: { n: 'Subject', t: VT_STRING },
0x04: { n: 'Author', t: VT_STRING },
0x05: { n: 'Keywords', t: VT_STRING },
0x06: { n: 'Comments', t: VT_STRING },
0x07: { n: 'Template', t: VT_STRING },
0x08: { n: 'LastAuthor', t: VT_STRING },
0x09: { n: 'RevNumber', t: VT_STRING },
0x0A: { n: 'EditTime', t: VT_FILETIME },
0x0B: { n: 'LastPrinted', t: VT_FILETIME },
0x0C: { n: 'CreatedDate', t: VT_FILETIME },
0x0D: { n: 'ModifiedDate', t: VT_FILETIME },
0x0E: { n: 'PageCount', t: VT_I4 },
0x0F: { n: 'WordCount', t: VT_I4 },
0x10: { n: 'CharCount', t: VT_I4 },
0x11: { n: 'Thumbnail', t: VT_CF },
0x12: { n: 'ApplicationName', t: VT_LPSTR },
0x13: { n: 'DocumentSecurity', t: VT_I4 },
0xFF: {}
/*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
/*::[*/0x02/*::]*/: { n: 'Title', t: VT_STRING },
/*::[*/0x03/*::]*/: { n: 'Subject', t: VT_STRING },
/*::[*/0x04/*::]*/: { n: 'Author', t: VT_STRING },
/*::[*/0x05/*::]*/: { n: 'Keywords', t: VT_STRING },
/*::[*/0x06/*::]*/: { n: 'Comments', t: VT_STRING },
/*::[*/0x07/*::]*/: { n: 'Template', t: VT_STRING },
/*::[*/0x08/*::]*/: { n: 'LastAuthor', t: VT_STRING },
/*::[*/0x09/*::]*/: { n: 'RevNumber', t: VT_STRING },
/*::[*/0x0A/*::]*/: { n: 'EditTime', t: VT_FILETIME },
/*::[*/0x0B/*::]*/: { n: 'LastPrinted', t: VT_FILETIME },
/*::[*/0x0C/*::]*/: { n: 'CreatedDate', t: VT_FILETIME },
/*::[*/0x0D/*::]*/: { n: 'ModifiedDate', t: VT_FILETIME },
/*::[*/0x0E/*::]*/: { n: 'PageCount', t: VT_I4 },
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
/*::[*/0x12/*::]*/: { n: 'ApplicationName', t: VT_LPSTR },
/*::[*/0x13/*::]*/: { n: 'DocumentSecurity', t: VT_I4 },
/*::[*/0xFF/*::]*/: {}
};
/* [MS-OLEPS] 2.18 */
var SpecialProperties = {
0x80000000: { n: 'Locale', t: VT_UI4 },
0x80000003: { n: 'Behavior', t: VT_UI4 },
0x72627262: {}
/*::[*/0x80000000/*::]*/: { n: 'Locale', t: VT_UI4 },
/*::[*/0x80000003/*::]*/: { n: 'Behavior', t: VT_UI4 },
/*::[*/0x72627262/*::]*/: {}
};
(function() {
@ -108,56 +108,56 @@ var SpecialProperties = {
/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
0x0001: "US", // United States
0x0002: "CA", // Canada
0x0003: "", // Latin America (except Brazil)
0x0007: "RU", // Russia
0x0014: "EG", // Egypt
0x001E: "GR", // Greece
0x001F: "NL", // Netherlands
0x0020: "BE", // Belgium
0x0021: "FR", // France
0x0022: "ES", // Spain
0x0024: "HU", // Hungary
0x0027: "IT", // Italy
0x0029: "CH", // Switzerland
0x002B: "AT", // Austria
0x002C: "GB", // United Kingdom
0x002D: "DK", // Denmark
0x002E: "SE", // Sweden
0x002F: "NO", // Norway
0x0030: "PL", // Poland
0x0031: "DE", // Germany
0x0034: "MX", // Mexico
0x0037: "BR", // Brazil
0x003d: "AU", // Australia
0x0040: "NZ", // New Zealand
0x0042: "TH", // Thailand
0x0051: "JP", // Japan
0x0052: "KR", // Korea
0x0054: "VN", // Viet Nam
0x0056: "CN", // China
0x005A: "TR", // Turkey
0x0069: "JS", // Ramastan
0x00D5: "DZ", // Algeria
0x00D8: "MA", // Morocco
0x00DA: "LY", // Libya
0x015F: "PT", // Portugal
0x0162: "IS", // Iceland
0x0166: "FI", // Finland
0x01A4: "CZ", // Czech Republic
0x0376: "TW", // Taiwan
0x03C1: "LB", // Lebanon
0x03C2: "JO", // Jordan
0x03C3: "SY", // Syria
0x03C4: "IQ", // Iraq
0x03C5: "KW", // Kuwait
0x03C6: "SA", // Saudi Arabia
0x03CB: "AE", // United Arab Emirates
0x03CC: "IL", // Israel
0x03CE: "QA", // Qatar
0x03D5: "IR", // Iran
0xFFFF: "US" // United States
/*::[*/0x0001/*::]*/: "US", // United States
/*::[*/0x0002/*::]*/: "CA", // Canada
/*::[*/0x0003/*::]*/: "", // Latin America (except Brazil)
/*::[*/0x0007/*::]*/: "RU", // Russia
/*::[*/0x0014/*::]*/: "EG", // Egypt
/*::[*/0x001E/*::]*/: "GR", // Greece
/*::[*/0x001F/*::]*/: "NL", // Netherlands
/*::[*/0x0020/*::]*/: "BE", // Belgium
/*::[*/0x0021/*::]*/: "FR", // France
/*::[*/0x0022/*::]*/: "ES", // Spain
/*::[*/0x0024/*::]*/: "HU", // Hungary
/*::[*/0x0027/*::]*/: "IT", // Italy
/*::[*/0x0029/*::]*/: "CH", // Switzerland
/*::[*/0x002B/*::]*/: "AT", // Austria
/*::[*/0x002C/*::]*/: "GB", // United Kingdom
/*::[*/0x002D/*::]*/: "DK", // Denmark
/*::[*/0x002E/*::]*/: "SE", // Sweden
/*::[*/0x002F/*::]*/: "NO", // Norway
/*::[*/0x0030/*::]*/: "PL", // Poland
/*::[*/0x0031/*::]*/: "DE", // Germany
/*::[*/0x0034/*::]*/: "MX", // Mexico
/*::[*/0x0037/*::]*/: "BR", // Brazil
/*::[*/0x003d/*::]*/: "AU", // Australia
/*::[*/0x0040/*::]*/: "NZ", // New Zealand
/*::[*/0x0042/*::]*/: "TH", // Thailand
/*::[*/0x0051/*::]*/: "JP", // Japan
/*::[*/0x0052/*::]*/: "KR", // Korea
/*::[*/0x0054/*::]*/: "VN", // Viet Nam
/*::[*/0x0056/*::]*/: "CN", // China
/*::[*/0x005A/*::]*/: "TR", // Turkey
/*::[*/0x0069/*::]*/: "JS", // Ramastan
/*::[*/0x00D5/*::]*/: "DZ", // Algeria
/*::[*/0x00D8/*::]*/: "MA", // Morocco
/*::[*/0x00DA/*::]*/: "LY", // Libya
/*::[*/0x015F/*::]*/: "PT", // Portugal
/*::[*/0x0162/*::]*/: "IS", // Iceland
/*::[*/0x0166/*::]*/: "FI", // Finland
/*::[*/0x01A4/*::]*/: "CZ", // Czech Republic
/*::[*/0x0376/*::]*/: "TW", // Taiwan
/*::[*/0x03C1/*::]*/: "LB", // Lebanon
/*::[*/0x03C2/*::]*/: "JO", // Jordan
/*::[*/0x03C3/*::]*/: "SY", // Syria
/*::[*/0x03C4/*::]*/: "IQ", // Iraq
/*::[*/0x03C5/*::]*/: "KW", // Kuwait
/*::[*/0x03C6/*::]*/: "SA", // Saudi Arabia
/*::[*/0x03CB/*::]*/: "AE", // United Arab Emirates
/*::[*/0x03CC/*::]*/: "IL", // Israel
/*::[*/0x03CE/*::]*/: "QA", // Qatar
/*::[*/0x03D5/*::]*/: "IR", // Iran
/*::[*/0xFFFF/*::]*/: "US" // United States
};
/* [MS-XLS] 2.5.127 */

View File

@ -3,7 +3,7 @@
/* 14.2 Part Summary <DrawingML> */
/* [MS-XLSX] 2.1 Part Enumerations */
/* [MS-XLSB] 2.1.7 Part Enumeration */
var ct2type = {
var ct2type/*{[string]:string}*/ = ({
/* Workbook */
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",
@ -141,7 +141,7 @@ var ct2type = {
"application/vnd.openxmlformats-officedocument.oleObject": "TODO",
"sheet": "js"
};
}/*:any*/);
var CT_LIST = (function(){
var o = {
@ -169,16 +169,16 @@ var CT_LIST = (function(){
return o;
})();
var type2ct = evert_arr(ct2type);
var type2ct/*{[string]:Array<string>}*/ = evert_arr(ct2type);
XMLNS.CT = 'http://schemas.openxmlformats.org/package/2006/content-types';
function parse_ct(data, opts) {
var ctext = {};
if(!data || !data.match) return data;
var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [],
function parse_ct(data/*:?string*/, opts) {
var ct = ({ workbooks: [], sheets: [], calcchains: [], themes: [], styles: [],
coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [],
TODO:[], rels:[], xmlns: "" };
TODO:[], rels:[], xmlns: "" }/*:any*/);
if(!data || !data.match) return ct;
var ctext = {};
(data.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0].replace(nsregex,"<")) {
@ -214,8 +214,8 @@ var CTYPE_DEFAULTS = [
return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]});
});
function write_ct(ct, opts) {
var o = [], v;
function write_ct(ct, opts)/*:string*/ {
var o/*:Array<string>*/ = [], v;
o[o.length] = (XML_HEADER);
o[o.length] = (CTYPE_XML_ROOT);
o = o.concat(CTYPE_DEFAULTS);

View File

@ -1,10 +1,10 @@
/* 9.3.2 OPC Relationships Markup */
var RELS = {
var RELS = ({
WB: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
};
}/*:any*/);
function parse_rels(data, currentFilePath) {
function parse_rels(data/*:?string*/, currentFilePath/*:string*/) {
if (!data) return data;
if (currentFilePath.charAt(0) !== '/') {
currentFilePath = '/'+currentFilePath;
@ -27,7 +27,7 @@ function parse_rels(data, currentFilePath) {
return toksFrom.join('/');
};
data.match(tagregex).forEach(function(x) {
(data.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
/* 9.3.2.2 OPC_Relationships */
if (y[0] === '<Relationship') {
@ -49,7 +49,7 @@ var RELS_ROOT = writextag('Relationships', null, {
});
/* TODO */
function write_rels(rels) {
function write_rels(rels)/*:string*/ {
var o = [];
o[o.length] = (XML_HEADER);
o[o.length] = (RELS_ROOT);

View File

@ -1,6 +1,6 @@
/* ECMA-376 Part II 11.1 Core Properties Part */
/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
var CORE_PROPS = [
var CORE_PROPS/*:Array<Array<string> >*/ = [
["cp:category", "Category"],
["cp:contentStatus", "ContentStatus"],
["cp:keywords", "Keywords"],
@ -21,7 +21,7 @@ var CORE_PROPS = [
XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
var CORE_PROPS_REGEX = (function() {
var CORE_PROPS_REGEX/*:Array<RegEx>*/ = (function() {
var r = new Array(CORE_PROPS.length);
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];

View File

@ -1,6 +1,6 @@
/* 15.2.12.3 Extended File Properties Part */
/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
var EXT_PROPS = [
var EXT_PROPS/*:Array<Array<string> >*/ = [
["Application", "Application", "string"],
["AppVersion", "AppVersion", "string"],
["Company", "Company", "string"],
@ -51,7 +51,7 @@ var EXT_PROPS_XML_ROOT = writextag('Properties', null, {
'xmlns:vt': XMLNS.vt
});
function write_ext_props(cp, opts) {
function write_ext_props(cp, opts)/*:string*/ {
var o = [], p = {}, W = writextag;
if(!cp) cp = {};
cp.Application = "SheetJS";

View File

@ -3,8 +3,8 @@ XMLNS.CUST_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/custom
RELS.CUST_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties';
var custregex = /<[^>]+>[^<]*/g;
function parse_cust_props(data, opts) {
var p = {}, name;
function parse_cust_props(data/*:string*/, opts) {
var p = {}, name = "";
var m = data.match(custregex);
if(m) for(var i = 0; i != m.length; ++i) {
var x = m[i], y = parsexmltag(x);
@ -54,7 +54,7 @@ var CUST_PROPS_XML_ROOT = writextag('Properties', null, {
'xmlns:vt': XMLNS.vt
});
function write_cust_props(cp, opts) {
function write_cust_props(cp, opts)/*:string*/ {
var o = [XML_HEADER, CUST_PROPS_XML_ROOT];
if(!cp) return o.join("");
var pid = 1;

View File

@ -1,4 +1,4 @@
function xlml_set_prop(Props, tag, val) {
function xlml_set_prop(Props, tag/*:string*/, val) {
/* TODO: Normalize the properties */
switch(tag) {
case 'Description': tag = 'Comments'; break;

View File

@ -68,7 +68,7 @@ function parse_VtVecHeadingPair(blob) {
/* [MS-OLEPS] 2.18.1 Dictionary (uses 2.17, 2.16) */
function parse_dictionary(blob,CodePage) {
var cnt = blob.read_shift(4);
var dict = {};
var dict/*{[number]:string}*/ = ({}/*:any*/);
for(var j = 0; j != cnt; ++j) {
var pid = blob.read_shift(4);
var len = blob.read_shift(4);
@ -82,7 +82,7 @@ function parse_dictionary(blob,CodePage) {
function parse_BLOB(blob) {
var size = blob.read_shift(4);
var bytes = blob.slice(blob.l,blob.l+size);
if(size & 3 > 0) blob.l += (4 - (size & 3)) & 3;
if((size & 3) > 0) blob.l += (4 - (size & 3)) & 3;
return bytes;
}
@ -149,7 +149,7 @@ function parse_PropertySet(blob, PIDSI) {
var NumProps = blob.read_shift(4);
var Props = [], i = 0;
var CodePage = 0;
var Dictionary = -1, DictObj;
var Dictionary = -1, DictObj/*{[number]:string}*/ = ({}/*:any*/);
for(i = 0; i != NumProps; ++i) {
var PropID = blob.read_shift(4);
var Offset = blob.read_shift(4);
@ -240,7 +240,7 @@ function parse_PropertySetStream(file, PIDSI) {
var blob = file.content;
prep_blob(blob, 0);
var NumSets, FMTID0, FMTID1, Offset0, Offset1;
var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
blob.chk('feff', 'Byte Order: ');
var vers = blob.read_shift(2); // TODO: check version
@ -254,13 +254,13 @@ function parse_PropertySetStream(file, PIDSI) {
else if(NumSets === 2) { FMTID1 = blob.read_shift(16); Offset1 = blob.read_shift(4); }
var PSet0 = parse_PropertySet(blob, PIDSI);
var rval = { SystemIdentifier: SystemIdentifier };
var rval = ({ SystemIdentifier: SystemIdentifier }/*:any*/);
for(var y in PSet0) rval[y] = PSet0[y];
//rval.blob = blob;
rval.FMTID = FMTID0;
//rval.PSet0 = PSet0;
if(NumSets === 1) return rval;
if(blob.l !== Offset1) throw "Length mismatch 2: " + blob.l + " !== " + Offset1;
if(blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
var PSet1;
try { PSet1 = parse_PropertySet(blob, null); } catch(e) { }
for(y in PSet1) rval[y] = PSet1[y];
@ -323,7 +323,7 @@ function parse_XLUnicodeRichExtendedString(blob) {
var cch = blob.read_shift(2), flags = blob.read_shift(1);
var fHighByte = flags & 0x1, fExtSt = flags & 0x4, fRichSt = flags & 0x8;
var width = 1 + (flags & 0x1); // 0x0 -> utf8, 0x1 -> dbcs
var cRun, cbExtRst;
var cRun = 0, cbExtRst;
var z = {};
if(fRichSt) cRun = blob.read_shift(2);
if(fExtSt) cbExtRst = blob.read_shift(4);
@ -354,7 +354,7 @@ function parse_XLUnicodeString(blob, length, opts) {
}
/* BIFF5 override */
function parse_XLUnicodeString2(blob, length, opts) {
if(opts.biff !== 5 && opts.biff !== 2) return parse_XLUnicodeString(blob, length, opts);
if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');

View File

@ -1,11 +1,11 @@
/* --- MS-XLS --- */
/* 2.5.19 */
function parse_XLSCell(blob, length) {
function parse_XLSCell(blob, length)/*:Cell*/ {
var rw = blob.read_shift(2); // 0-indexed
var col = blob.read_shift(2);
var ixfe = blob.read_shift(2);
return {r:rw, c:col, ixfe:ixfe};
return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
}
/* 2.5.134 */
@ -101,22 +101,22 @@ function parse_FtCf(blob, length) {
/* 2.5.140 - 2.5.154 and friends */
var FtTab = {
0x15: parse_FtCmo,
0x13: parsenoop, /* FtLbsData */
0x12: function(blob, length) { blob.l += 12; }, /* FtCblsData */
0x11: function(blob, length) { blob.l += 8; }, /* FtRboData */
0x10: parsenoop, /* FtEdoData */
0x0F: parsenoop, /* FtGboData */
0x0D: parse_FtNts, /* FtNts */
0x0C: function(blob, length) { blob.l += 24; }, /* FtSbs */
0x0B: function(blob, length) { blob.l += 10; }, /* FtRbo */
0x0A: function(blob, length) { blob.l += 16; }, /* FtCbls */
0x09: parsenoop, /* FtPictFmla */
0x08: function(blob, length) { blob.l += 6; }, /* FtPioGrbit */
0x07: parse_FtCf, /* FtCf */
0x06: function(blob, length) { blob.l += 6; }, /* FtGmo */
0x04: parsenoop, /* FtMacro */
0x00: function(blob, length) { blob.l += 4; } /* FtEnding */
/*::[*/0x15/*::]*/: parse_FtCmo,
/*::[*/0x13/*::]*/: parsenoop, /* FtLbsData */
/*::[*/0x12/*::]*/: function(blob, length) { blob.l += 12; }, /* FtCblsData */
/*::[*/0x11/*::]*/: function(blob, length) { blob.l += 8; }, /* FtRboData */
/*::[*/0x10/*::]*/: parsenoop, /* FtEdoData */
/*::[*/0x0F/*::]*/: parsenoop, /* FtGboData */
/*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
/*::[*/0x0C/*::]*/: function(blob, length) { blob.l += 24; }, /* FtSbs */
/*::[*/0x0B/*::]*/: function(blob, length) { blob.l += 10; }, /* FtRbo */
/*::[*/0x0A/*::]*/: function(blob, length) { blob.l += 16; }, /* FtCbls */
/*::[*/0x09/*::]*/: parsenoop, /* FtPictFmla */
/*::[*/0x08/*::]*/: function(blob, length) { blob.l += 6; }, /* FtPioGrbit */
/*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
/*::[*/0x06/*::]*/: function(blob, length) { blob.l += 6; }, /* FtGmo */
/*::[*/0x04/*::]*/: parsenoop, /* FtMacro */
/*::[*/0x00/*::]*/: function(blob, length) { blob.l += 4; } /* FtEnding */
};
function parse_FtArray(blob, length, ot) {
var s = blob.l;
@ -146,7 +146,7 @@ function parse_BOF(blob, length) {
case 0x0500: /* BIFF5 */
case 0x0002: case 0x0007: /* BIFF2 */
break;
default: throw "Unexpected BIFF Ver " + o.BIFFVer;
default: if(length > 6) throw new Error("Unexpected BIFF Ver " + o.BIFFVer);
}
blob.read_shift(length);
return o;
@ -175,7 +175,7 @@ function parse_WriteAccess(blob, length, opts) {
/* 2.4.28 */
function parse_BoundSheet8(blob, length, opts) {
var pos = blob.read_shift(4);
var hidden = blob.read_shift(1) >> 6;
var hidden = blob.read_shift(1) & 0x03;
var dt = blob.read_shift(1);
switch(dt) {
case 0: dt = 'Worksheet'; break;
@ -241,7 +241,7 @@ function parse_RecalcId(blob, length) {
/* 2.4.87 */
function parse_DefaultRowHeight (blob, length) {
var f = blob.read_shift(2), miyRw;
var f = length == 4 ? blob.read_shift(2) : 0, miyRw;
miyRw = blob.read_shift(2); // flags & 0x02 -> hidden, else empty
var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
return [fl, miyRw];
@ -284,6 +284,7 @@ function parse_Format(blob, length, opts) {
var fmtstr = parse_XLUnicodeString2(blob, 0, opts);
return [ifmt, fmtstr];
}
var parse_BIFF2Format = parse_XLUnicodeString2;
/* 2.4.90 */
function parse_Dimensions(blob, length) {
@ -342,13 +343,14 @@ function parse_Guts(blob, length) {
var out = [blob.read_shift(2), blob.read_shift(2)];
if(out[0] !== 0) out[0]--;
if(out[1] !== 0) out[1]--;
if(out[0] > 7 || out[1] > 7) throw "Bad Gutters: " + out;
if(out[0] > 7 || out[1] > 7) throw "Bad Gutters: " + out.join("|");
return out;
}
/* 2.4.24 */
function parse_BoolErr(blob, length) {
function parse_BoolErr(blob, length, opts) {
var cell = parse_XLSCell(blob, 6);
if(opts.biff == 2) ++blob.l;
var val = parse_Bes(blob, 2);
cell.val = val;
cell.t = (val === true || val === false) ? 'b' : 'e';
@ -381,7 +383,7 @@ function parse_SupBook(blob, length, opts) {
function parse_ExternName(blob, length, opts) {
var flags = blob.read_shift(2);
var body;
var o = {
var o = ({
fBuiltIn: flags & 0x01,
fWantAdvise: (flags >>> 1) & 0x01,
fWantPict: (flags >>> 2) & 0x01,
@ -389,7 +391,7 @@ function parse_ExternName(blob, length, opts) {
fOleLink: (flags >>> 4) & 0x01,
cf: (flags >>> 5) & 0x3FF,
fIcon: flags >>> 15 & 0x01
};
}/*:any*/);
if(opts.sbcch === 0x3A01) body = parse_AddinUdf(blob, length-2);
//else throw new Error("unsupported SupBook cch: " + opts.sbcch);
o.body = body || blob.read_shift(length-2);
@ -398,7 +400,6 @@ function parse_ExternName(blob, length, opts) {
/* 2.4.150 TODO */
function parse_Lbl(blob, length, opts) {
if(opts.biff < 8) return parse_Label(blob, length, opts);
var target = blob.l + length;
var flags = blob.read_shift(2);
var chKey = blob.read_shift(1);
@ -486,6 +487,7 @@ function parse_Obj(blob, length) {
/* 2.4.329 TODO: parse properly */
function parse_TxO(blob, length, opts) {
var s = blob.l;
var texts = "";
try {
blob.l += 4;
var ot = (opts.lastobj||{cmo:[0,0]}).cmo[1];
@ -499,7 +501,6 @@ try {
blob.l += len;
//var fmla = parse_ObjFmla(blob, s + length - blob.l);
var texts = "";
for(var i = 1; i < blob.lens.length-1; ++i) {
if(blob.l-s != blob.lens[i]) throw "TxO: bad continue record";
var hdr = blob[blob.l];
@ -520,7 +521,7 @@ try {
// blob.l += 6;
// if(s + length != blob.l) throw "TxO " + (s + length) + ", at " + blob.l;
return { t: texts };
} catch(e) { blob.l = s + length; return { t: texts||"" }; }
} catch(e) { blob.l = s + length; return { t: texts }; }
}
/* 2.4.140 */
@ -915,3 +916,26 @@ function parse_BIFF2NUM(blob, length, opts) {
return cell;
}
function parse_BIFF2INT(blob, length) {
var cell = parse_XLSCell(blob, 6);
++blob.l;
var num = blob.read_shift(2);
cell.val = num;
return cell;
}
function parse_BIFF2STRING(blob, length) {
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');
}
/* TODO: convert to BIFF8 font struct */
function parse_BIFF2FONTXTRA(blob, length) {
blob.l += 6; // unknown
blob.l += 2; // font weight "bls"
blob.l += 1; // charset
blob.l += 3; // unknown
blob.l += 1; // font family
blob.l += length - 9;
}

View File

@ -1,30 +1,30 @@
/* 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 */
};
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 = /<r>/g, rend = /<\/r>/, nlregex = /\r\n/g;
var tregex = matchtag("t"), rpregex = matchtag("rPr"), rregex = /<(?:\w+:)?r>/g, rend = /<\/(?:\w+:)?r>/, nlregex = /\r\n/g;
/* 18.4.7 rPr CT_RPrElt */
var parse_rpr = function parse_rpr(rpr, intro, outro) {
var font = {}, cp = 65001;
@ -121,11 +121,11 @@ var parse_rs = (function parse_rs_factory() {
var terms = [[],"",[]];
/* 18.4.12 t ST_Xstring */
var t = r.match(tregex), cp = 65001;
if(!isval(t)) return "";
if(!isval(t)/*:: || !t*/) return "";
terms[1] = t[1];
var rpr = r.match(rpregex);
if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]);
if(isval(rpr)/*:: && rpr*/) cp = parse_rpr(rpr[1], terms[0], terms[2]);
return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
}
@ -135,22 +135,22 @@ var parse_rs = (function parse_rs_factory() {
})();
/* 18.4.8 si CT_Rst */
var sitregex = /<t[^>]*>([^<]*)<\/t>/g, sirregex = /<r>/;
var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r>/;
function parse_si(x, opts) {
var html = opts ? opts.cellHTML : true;
var z = {};
if(!x) return null;
var y;
/* 18.4.12 t ST_Xstring (Plaintext String) */
if(x.charCodeAt(1) === 116) {
z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0]));
if(x.match(/^<(?:\w+:)?t[^>]*>/)) {
z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]));
z.r = x;
if(html) z.h = z.t;
}
/* 18.4.4 r CT_RElt (Rich Text Run) */
else if((y = x.match(sirregex))) {
z.r = x;
z.t = utf8read(unescapexml(x.match(sitregex).join("").replace(tagregex,"")));
z.t = utf8read(unescapexml((x.match(sitregex)||[]).join("").replace(tagregex,"")));
if(html) z.h = parse_rs(x);
}
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
@ -159,14 +159,15 @@ function parse_si(x, opts) {
}
/* 18.4 Shared String Table */
var sstr0 = /<sst([^>]*)>([\s\S]*)<\/sst>/;
var sstr1 = /<(?:si|sstItem)>/g;
var sstr2 = /<\/(?:si|sstItem)>/;
function parse_sst_xml(data, opts) {
var s = [], ss;
var sstr0 = /<(?:\w+:)?sst([^>]*)>([\s\S]*)<\/(?:\w+:)?sst>/;
var sstr1 = /<(?:\w+:)?(?:si|sstItem)>/g;
var sstr2 = /<\/(?:\w+:)?(?:si|sstItem)>/;
function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
var s/*:SST*/ = ([]/*:any*/), ss = "";
if(!data) return s;
/* 18.4.9 sst CT_Sst */
var sst = data.match(sstr0);
if(isval(sst)) {
if(isval(sst)/*:: && sst*/) {
ss = sst[2].replace(sstr1,"").split(sstr2);
for(var i = 0; i != ss.length; ++i) {
var o = parse_si(ss[i], opts);
@ -179,7 +180,7 @@ function parse_sst_xml(data, opts) {
RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
var straywsregex = /^\s|\s$|[\t\n\r]/;
function write_sst_xml(sst, opts) {
function write_sst_xml(sst/*:SST*/, opts)/*:string*/ {
if(!opts.bookSST) return "";
var o = [XML_HEADER];
o[o.length] = (writextag('sst', null, {

View File

@ -1,14 +1,19 @@
function _JS2ANSI(str) { if(typeof cptable !== 'undefined') return cptable.utils.encode(1252, str); return str.split("").map(function(x) { return x.charCodeAt(0); }); }
function _JS2ANSI(str/*:string*/)/*:Array<number>*/ {
if(typeof cptable !== 'undefined') return cptable.utils.encode(1252, str);
var o = [], oo = str.split("");
for(var i = 0; i < oo.length; ++i) o[i] = oo[i].charCodeAt(0);
return o;
}
/* [MS-OFFCRYPTO] 2.1.4 Version */
function parse_Version(blob, length) {
function parse_Version(blob, length/*:number*/) {
var o = {};
o.Major = blob.read_shift(2);
o.Minor = blob.read_shift(2);
return o;
}
/* [MS-OFFCRYPTO] 2.3.2 Encryption Header */
function parse_EncryptionHeader(blob, length) {
function parse_EncryptionHeader(blob, length/*:number*/) {
var o = {};
o.Flags = blob.read_shift(4);
@ -26,11 +31,11 @@ function parse_EncryptionHeader(blob, length) {
}
/* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */
function parse_EncryptionVerifier(blob, length) {
function parse_EncryptionVerifier(blob, length/*:number*/) {
return parsenoop(blob, length);
}
/* [MS-OFFCRYPTO] 2.3.5.1 RC4 CryptoAPI Encryption Header */
function parse_RC4CryptoHeader(blob, length) {
function parse_RC4CryptoHeader(blob, length/*:number*/) {
var o = {};
var vers = o.EncryptionVersionInfo = parse_Version(blob, 4); length -= 4;
if(vers.Minor != 2) throw 'unrecognized minor version code: ' + vers.Minor;
@ -42,7 +47,7 @@ function parse_RC4CryptoHeader(blob, length) {
return o;
}
/* [MS-OFFCRYPTO] 2.3.6.1 RC4 Encryption Header */
function parse_RC4Header(blob, length) {
function parse_RC4Header(blob, length/*:number*/) {
var o = {};
var vers = o.EncryptionVersionInfo = parse_Version(blob, 4); length -= 4;
if(vers.Major != 1 || vers.Minor != 1) throw 'unrecognized version code ' + vers.Major + ' : ' + vers.Minor;
@ -53,7 +58,7 @@ function parse_RC4Header(blob, length) {
}
/* [MS-OFFCRYPTO] 2.3.7.1 Binary Document Password Verifier Derivation */
function crypto_CreatePasswordVerifier_Method1(Password) {
function crypto_CreatePasswordVerifier_Method1(Password/*:string*/) {
var Verifier = 0x0000, PasswordArray;
var PasswordDecoded = _JS2ANSI(Password);
var len = PasswordDecoded.length + 1, i, PasswordByte;
@ -90,7 +95,7 @@ var crypto_CreateXorArray_Method1 = (function() {
}
return XorKey;
};
return function(password) {
return function(password/*:string*/) {
var Password = _JS2ANSI(password);
var XorKey = CreateXorKey_Method1(Password);
var Index = Password.length;
@ -130,7 +135,7 @@ var crypto_CreateXorArray_Method1 = (function() {
})();
/* [MS-OFFCRYPTO] 2.3.7.3 Binary Document XOR Data Transformation Method 1 */
var crypto_DecryptData_Method1 = function(password, Data, XorArrayIndex, XorArray, O) {
var crypto_DecryptData_Method1 = function(password/*:string*/, Data, XorArrayIndex, XorArray, O) {
/* If XorArray is set, use it; if O is not set, make changes in-place */
if(!O) O = Data;
if(!XorArray) XorArray = crypto_CreateXorArray_Method1(password);
@ -145,10 +150,10 @@ var crypto_DecryptData_Method1 = function(password, Data, XorArrayIndex, XorArra
return [O, XorArrayIndex, XorArray];
};
var crypto_MakeXorDecryptor = function(password) {
var crypto_MakeXorDecryptor = function(password/*:string*/) {
var XorArrayIndex = 0, XorArray = crypto_CreateXorArray_Method1(password);
return function(Data) {
var O = crypto_DecryptData_Method1(null, Data, XorArrayIndex, XorArray);
var O = crypto_DecryptData_Method1("", Data, XorArrayIndex, XorArray);
XorArrayIndex = O[1];
return O[0];
};
@ -156,7 +161,7 @@ var crypto_MakeXorDecryptor = function(password) {
/* 2.5.343 */
function parse_XORObfuscation(blob, length, opts, out) {
var o = { key: parseuint16(blob), verificationBytes: parseuint16(blob) };
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);
@ -164,13 +169,13 @@ function parse_XORObfuscation(blob, length, opts, out) {
}
/* 2.4.117 */
function parse_FilePassHeader(blob, length, oo) {
function parse_FilePassHeader(blob, length/*:number*/, oo) {
var o = oo || {}; o.Info = blob.read_shift(2); blob.l -= 2;
if(o.Info === 1) o.Data = parse_RC4Header(blob, length);
else o.Data = parse_RC4CryptoHeader(blob, length);
return o;
}
function parse_FilePass(blob, length, opts) {
function parse_FilePass(blob, length/*:number*/, opts) {
var o = { Type: blob.read_shift(2) }; /* wEncryptionType */
if(o.Type) parse_FilePassHeader(blob, length-2, o);
else parse_XORObfuscation(blob, length-2, opts, o);

View File

@ -38,7 +38,7 @@ function parse_fills(t, opts) {
break;
case '<fgColor/>': case '</fgColor>': break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills';
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in fills');
}
});
}
@ -46,9 +46,10 @@ function parse_fills(t, opts) {
/* 18.8.31 numFmts CT_NumFmts */
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
var k/*Array<number>*/ = (keys(SSF._table)/*:any*/);
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
if(!m) return;
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
@ -57,7 +58,7 @@ function parse_numFmts(t, opts) {
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in numFmts');
}
}
}
@ -101,7 +102,7 @@ function parse_cellXfs(t, opts) {
});
}
function write_cellXfs(cellXfs) {
function write_cellXfs(cellXfs)/*:string*/ {
var o = [];
o[o.length] = (writextag('cellXfs',null));
cellXfs.forEach(function(c) { o[o.length] = (writextag('xf', null, c)); });
@ -118,6 +119,7 @@ var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
return function parse_sty_xml(data, opts) {
if(!data) return styles;
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
@ -152,7 +154,7 @@ var STYLES_XML_ROOT = writextag('styleSheet', null, {
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
function write_sty_xml(wb, opts) {
function write_sty_xml(wb/*:Workbook*/, opts)/*:string*/ {
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');

View File

@ -1,13 +1,13 @@
/* [MS-XLSB] 2.4.651 BrtFmt */
function parse_BrtFmt(data, length) {
function parse_BrtFmt(data, length/*:number*/) {
var ifmt = data.read_shift(2);
var stFmtCode = parse_XLWideString(data,length-2);
return [ifmt, stFmtCode];
}
/* [MS-XLSB] 2.4.653 BrtFont TODO */
function parse_BrtFont(data, length) {
var out = {flags:{}};
function parse_BrtFont(data, length/*:number*/) {
var out = ({flags:{}}/*:any*/);
out.dyHeight = data.read_shift(2);
out.grbit = parse_FontFlags(data, 2);
out.bls = data.read_shift(2);
@ -33,7 +33,7 @@ function parse_BrtFont(data, length) {
}
/* [MS-XLSB] 2.4.816 BrtXF */
function parse_BrtXF(data, length) {
function parse_BrtXF(data, length/*:number*/) {
var ixfeParent = data.read_shift(2);
var ifmt = data.read_shift(2);
parsenoop(data, length-4);
@ -42,7 +42,7 @@ function parse_BrtXF(data, length) {
/* [MS-XLSB] 2.1.7.50 Styles */
function parse_sty_bin(data, opts) {
styles.NumberFmt = [];
styles.NumberFmt = ([]/*:any*/);
for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y];
styles.CellXf = [];

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
/* 18.6 Calculation Chain */
function parse_cc_xml(data, opts) {
var d = [];
if(!data) return d;
var l = 0, i = 1;
(data.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);

View File

@ -34,7 +34,7 @@ function insertCommentsIntoSheet(sheetName, sheet, comments) {
}
if (!cell.c) cell.c = [];
var o = {a: comment.author, t: comment.t, r: comment.r};
var o = ({a: comment.author, t: comment.t, r: comment.r}/*:any*/);
if(comment.h) o.h = comment.h;
cell.c.push(o);
});

View File

@ -1,21 +1,27 @@
/* 18.7.3 CT_Comment */
function parse_comments_xml(data, opts) {
function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
var authors = [];
var commentList = [];
data.match(/<(?:\w+:)?authors>([^\u2603]*)<\/(?:\w+:)?authors>/)[1].split(/<\/\w*:?author>/).forEach(function(x) {
var authtag = data.match(/<(?:\w+:)?authors>([^\u2603]*)<\/(?:\w+:)?authors>/);
if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
if(x === "" || x.trim() === "") return;
authors.push(x.match(/<(?:\w+:)?author[^>]*>(.*)/)[1]);
var a = x.match(/<(?:\w+:)?author[^>]*>(.*)/);
if(a) authors.push(a[1]);
});
(data.match(/<(?:\w+:)?commentList>([^\u2603]*)<\/(?:\w+:)?commentList>/)||["",""])[1].split(/<\/\w*:?comment>/).forEach(function(x, index) {
var cmnttag = data.match(/<(?:\w+:)?commentList>([^\u2603]*)<\/(?:\w+:)?commentList>/);
if(cmnttag && cmnttag[1]) cmnttag[1].split(/<\/\w*:?comment>/).forEach(function(x, index) {
if(x === "" || x.trim() === "") return;
var y = parsexmltag(x.match(/<(?:\w+:)?comment[^>]*>/)[0]);
var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
if(!cm) return;
var y = parsexmltag(cm[0]);
var comment/*:Comment*/ = ({ author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, 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(/<text>([^\u2603]*)<\/text>/);
var textMatch = x.match(/<(?:\w+:)?text>([^\u2603]*)<\/(?:\w+:)?text>/);
if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
var rt = parse_si(textMatch[1]);
if(!rt) return;
comment.r = rt.r;
comment.t = rt.t;
if(opts.cellHTML) comment.h = rt.h;

View File

@ -353,100 +353,106 @@ var parse_PtgTbl = parsenoop;
/* 2.5.198.25 */
var PtgTypes = {
0x01: { n:'PtgExp', f:parse_PtgExp },
0x02: { n:'PtgTbl', f:parse_PtgTbl },
0x03: { n:'PtgAdd', f:parse_PtgAdd },
0x04: { n:'PtgSub', f:parse_PtgSub },
0x05: { n:'PtgMul', f:parse_PtgMul },
0x06: { n:'PtgDiv', f:parse_PtgDiv },
0x07: { n:'PtgPower', f:parse_PtgPower },
0x08: { n:'PtgConcat', f:parse_PtgConcat },
0x09: { n:'PtgLt', f:parse_PtgLt },
0x0A: { n:'PtgLe', f:parse_PtgLe },
0x0B: { n:'PtgEq', f:parse_PtgEq },
0x0C: { n:'PtgGe', f:parse_PtgGe },
0x0D: { n:'PtgGt', f:parse_PtgGt },
0x0E: { n:'PtgNe', f:parse_PtgNe },
0x0F: { n:'PtgIsect', f:parse_PtgIsect },
0x10: { n:'PtgUnion', f:parse_PtgUnion },
0x11: { n:'PtgRange', f:parse_PtgRange },
0x12: { n:'PtgUplus', f:parse_PtgUplus },
0x13: { n:'PtgUminus', f:parse_PtgUminus },
0x14: { n:'PtgPercent', f:parse_PtgPercent },
0x15: { n:'PtgParen', f:parse_PtgParen },
0x16: { n:'PtgMissArg', f:parse_PtgMissArg },
0x17: { n:'PtgStr', f:parse_PtgStr },
0x1C: { n:'PtgErr', f:parse_PtgErr },
0x1D: { n:'PtgBool', f:parse_PtgBool },
0x1E: { n:'PtgInt', f:parse_PtgInt },
0x1F: { n:'PtgNum', f:parse_PtgNum },
0x20: { n:'PtgArray', f:parse_PtgArray },
0x21: { n:'PtgFunc', f:parse_PtgFunc },
0x22: { n:'PtgFuncVar', f:parse_PtgFuncVar },
0x23: { n:'PtgName', f:parse_PtgName },
0x24: { n:'PtgRef', f:parse_PtgRef },
0x25: { n:'PtgArea', f:parse_PtgArea },
0x26: { n:'PtgMemArea', f:parse_PtgMemArea },
0x27: { n:'PtgMemErr', f:parse_PtgMemErr },
0x28: { n:'PtgMemNoMem', f:parse_PtgMemNoMem },
0x29: { n:'PtgMemFunc', f:parse_PtgMemFunc },
0x2A: { n:'PtgRefErr', f:parse_PtgRefErr },
0x2B: { n:'PtgAreaErr', f:parse_PtgAreaErr },
0x2C: { n:'PtgRefN', f:parse_PtgRefN },
0x2D: { n:'PtgAreaN', f:parse_PtgAreaN },
0x39: { n:'PtgNameX', f:parse_PtgNameX },
0x3A: { n:'PtgRef3d', f:parse_PtgRef3d },
0x3B: { n:'PtgArea3d', f:parse_PtgArea3d },
0x3C: { n:'PtgRefErr3d', f:parse_PtgRefErr3d },
0x3D: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d },
0xFF: {}
/*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp },
/*::[*/0x02/*::]*/: { n:'PtgTbl', f:parse_PtgTbl },
/*::[*/0x03/*::]*/: { n:'PtgAdd', f:parse_PtgAdd },
/*::[*/0x04/*::]*/: { n:'PtgSub', f:parse_PtgSub },
/*::[*/0x05/*::]*/: { n:'PtgMul', f:parse_PtgMul },
/*::[*/0x06/*::]*/: { n:'PtgDiv', f:parse_PtgDiv },
/*::[*/0x07/*::]*/: { n:'PtgPower', f:parse_PtgPower },
/*::[*/0x08/*::]*/: { n:'PtgConcat', f:parse_PtgConcat },
/*::[*/0x09/*::]*/: { n:'PtgLt', f:parse_PtgLt },
/*::[*/0x0A/*::]*/: { n:'PtgLe', f:parse_PtgLe },
/*::[*/0x0B/*::]*/: { n:'PtgEq', f:parse_PtgEq },
/*::[*/0x0C/*::]*/: { n:'PtgGe', f:parse_PtgGe },
/*::[*/0x0D/*::]*/: { n:'PtgGt', f:parse_PtgGt },
/*::[*/0x0E/*::]*/: { n:'PtgNe', f:parse_PtgNe },
/*::[*/0x0F/*::]*/: { n:'PtgIsect', f:parse_PtgIsect },
/*::[*/0x10/*::]*/: { n:'PtgUnion', f:parse_PtgUnion },
/*::[*/0x11/*::]*/: { n:'PtgRange', f:parse_PtgRange },
/*::[*/0x12/*::]*/: { n:'PtgUplus', f:parse_PtgUplus },
/*::[*/0x13/*::]*/: { n:'PtgUminus', f:parse_PtgUminus },
/*::[*/0x14/*::]*/: { n:'PtgPercent', f:parse_PtgPercent },
/*::[*/0x15/*::]*/: { n:'PtgParen', f:parse_PtgParen },
/*::[*/0x16/*::]*/: { n:'PtgMissArg', f:parse_PtgMissArg },
/*::[*/0x17/*::]*/: { n:'PtgStr', f:parse_PtgStr },
/*::[*/0x1C/*::]*/: { n:'PtgErr', f:parse_PtgErr },
/*::[*/0x1D/*::]*/: { n:'PtgBool', f:parse_PtgBool },
/*::[*/0x1E/*::]*/: { n:'PtgInt', f:parse_PtgInt },
/*::[*/0x1F/*::]*/: { n:'PtgNum', f:parse_PtgNum },
/*::[*/0x20/*::]*/: { n:'PtgArray', f:parse_PtgArray },
/*::[*/0x21/*::]*/: { n:'PtgFunc', f:parse_PtgFunc },
/*::[*/0x22/*::]*/: { n:'PtgFuncVar', f:parse_PtgFuncVar },
/*::[*/0x23/*::]*/: { n:'PtgName', f:parse_PtgName },
/*::[*/0x24/*::]*/: { n:'PtgRef', f:parse_PtgRef },
/*::[*/0x25/*::]*/: { n:'PtgArea', f:parse_PtgArea },
/*::[*/0x26/*::]*/: { n:'PtgMemArea', f:parse_PtgMemArea },
/*::[*/0x27/*::]*/: { n:'PtgMemErr', f:parse_PtgMemErr },
/*::[*/0x28/*::]*/: { n:'PtgMemNoMem', f:parse_PtgMemNoMem },
/*::[*/0x29/*::]*/: { n:'PtgMemFunc', f:parse_PtgMemFunc },
/*::[*/0x2A/*::]*/: { n:'PtgRefErr', f:parse_PtgRefErr },
/*::[*/0x2B/*::]*/: { n:'PtgAreaErr', f:parse_PtgAreaErr },
/*::[*/0x2C/*::]*/: { n:'PtgRefN', f:parse_PtgRefN },
/*::[*/0x2D/*::]*/: { n:'PtgAreaN', f:parse_PtgAreaN },
/*::[*/0x39/*::]*/: { n:'PtgNameX', f:parse_PtgNameX },
/*::[*/0x3A/*::]*/: { n:'PtgRef3d', f:parse_PtgRef3d },
/*::[*/0x3B/*::]*/: { n:'PtgArea3d', f:parse_PtgArea3d },
/*::[*/0x3C/*::]*/: { n:'PtgRefErr3d', f:parse_PtgRefErr3d },
/*::[*/0x3D/*::]*/: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d },
/*::[*/0xFF/*::]*/: {}
};
/* These are duplicated in the PtgTypes table */
var PtgDupes = {
0x40: 0x20, 0x60: 0x20,
0x41: 0x21, 0x61: 0x21,
0x42: 0x22, 0x62: 0x22,
0x43: 0x23, 0x63: 0x23,
0x44: 0x24, 0x64: 0x24,
0x45: 0x25, 0x65: 0x25,
0x46: 0x26, 0x66: 0x26,
0x47: 0x27, 0x67: 0x27,
0x48: 0x28, 0x68: 0x28,
0x49: 0x29, 0x69: 0x29,
0x4A: 0x2A, 0x6A: 0x2A,
0x4B: 0x2B, 0x6B: 0x2B,
0x4C: 0x2C, 0x6C: 0x2C,
0x4D: 0x2D, 0x6D: 0x2D,
0x59: 0x39, 0x79: 0x39,
0x5A: 0x3A, 0x7A: 0x3A,
0x5B: 0x3B, 0x7B: 0x3B,
0x5C: 0x3C, 0x7C: 0x3C,
0x5D: 0x3D, 0x7D: 0x3D
/*::[*/0x40/*::]*/: 0x20, /*::[*/0x60/*::]*/: 0x20,
/*::[*/0x41/*::]*/: 0x21, /*::[*/0x61/*::]*/: 0x21,
/*::[*/0x42/*::]*/: 0x22, /*::[*/0x62/*::]*/: 0x22,
/*::[*/0x43/*::]*/: 0x23, /*::[*/0x63/*::]*/: 0x23,
/*::[*/0x44/*::]*/: 0x24, /*::[*/0x64/*::]*/: 0x24,
/*::[*/0x45/*::]*/: 0x25, /*::[*/0x65/*::]*/: 0x25,
/*::[*/0x46/*::]*/: 0x26, /*::[*/0x66/*::]*/: 0x26,
/*::[*/0x47/*::]*/: 0x27, /*::[*/0x67/*::]*/: 0x27,
/*::[*/0x48/*::]*/: 0x28, /*::[*/0x68/*::]*/: 0x28,
/*::[*/0x49/*::]*/: 0x29, /*::[*/0x69/*::]*/: 0x29,
/*::[*/0x4A/*::]*/: 0x2A, /*::[*/0x6A/*::]*/: 0x2A,
/*::[*/0x4B/*::]*/: 0x2B, /*::[*/0x6B/*::]*/: 0x2B,
/*::[*/0x4C/*::]*/: 0x2C, /*::[*/0x6C/*::]*/: 0x2C,
/*::[*/0x4D/*::]*/: 0x2D, /*::[*/0x6D/*::]*/: 0x2D,
/*::[*/0x59/*::]*/: 0x39, /*::[*/0x79/*::]*/: 0x39,
/*::[*/0x5A/*::]*/: 0x3A, /*::[*/0x7A/*::]*/: 0x3A,
/*::[*/0x5B/*::]*/: 0x3B, /*::[*/0x7B/*::]*/: 0x3B,
/*::[*/0x5C/*::]*/: 0x3C, /*::[*/0x7C/*::]*/: 0x3C,
/*::[*/0x5D/*::]*/: 0x3D, /*::[*/0x7D/*::]*/: 0x3D
};
(function(){for(var y in PtgDupes) PtgTypes[y] = PtgTypes[PtgDupes[y]];})();
var Ptg18 = {};
var Ptg19 = {
0x01: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
0x02: { n:'PtgAttrIf', f:parse_PtgAttrIf },
0x04: { n:'PtgAttrChoose', f:parse_PtgAttrChoose },
0x08: { n:'PtgAttrGoto', f:parse_PtgAttrGoto },
0x10: { n:'PtgAttrSum', f:parse_PtgAttrSum },
0x20: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
0x40: { n:'PtgAttrSpace', f:parse_PtgAttrSpace },
0x41: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi },
0xFF: {}
/*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
/*::[*/0x02/*::]*/: { n:'PtgAttrIf', f:parse_PtgAttrIf },
/*::[*/0x04/*::]*/: { n:'PtgAttrChoose', f:parse_PtgAttrChoose },
/*::[*/0x08/*::]*/: { n:'PtgAttrGoto', f:parse_PtgAttrGoto },
/*::[*/0x10/*::]*/: { n:'PtgAttrSum', f:parse_PtgAttrSum },
/*::[*/0x20/*::]*/: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
/*::[*/0x40/*::]*/: { n:'PtgAttrSpace', f:parse_PtgAttrSpace },
/*::[*/0x41/*::]*/: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi },
/*::[*/0xFF/*::]*/: {}
};
/* 2.4.127 TODO */
function parse_Formula(blob, length, opts) {
var cell = parse_XLSCell(blob, 6);
if(opts.biff == 2) ++blob.l;
var val = parse_FormulaValue(blob,8);
var flags = blob.read_shift(1);
blob.read_shift(1);
var chn = blob.read_shift(4);
if(opts.biff != 2) {
blob.read_shift(1);
if(opts.biff >= 5) {
var chn = blob.read_shift(4);
}
}
var cbf = "";
if(opts.biff === 5) blob.l += length-20;
if(opts.biff < 5) blob.l += length-16;
else if(opts.biff === 5) blob.l += length-20;
else cbf = parse_XLSCellParsedFormula(blob, length-20, opts);
return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
}
@ -461,6 +467,7 @@ function parse_FormulaValue(blob) {
case 0x02: b = blob[blob.l+2]; blob.l += 8; return [b,'e'];
case 0x03: blob.l += 8; return ["",'s'];
}
return [];
}
/* 2.5.198.103 */

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ var _ssfopts = {}; // spreadsheet formatting options
RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
function get_sst_id(sst, str) {
function get_sst_id(sst/*:SST*/, str)/*:number*/ {
for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len;
}

View File

@ -2,19 +2,20 @@ function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
var mergecregex = /<(?:\w:)?mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<hyperlink[^>]*\/>/g;
var hlinkregex = /<(?:\w*:)?hyperlink[^>]*\/>/g;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<col[^>]*\/>/g;
var colregex = /<(?:\w*:)?col[^>]*\/>/g;
/* 18.3 Worksheets */
function parse_ws_xml(data, opts, rels) {
function parse_ws_xml(data/*:?string*/, opts, rels) {
if(!data) return data;
/* 18.3.1.99 worksheet CT_Worksheet */
var s = {};
/* 18.3.1.35 dimension CT_SheetDimension ? */
var ridx = data.indexOf("<dimension");
// $FlowIgnore
var ridx = (data.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
if(ridx > 0) {
var ref = data.substr(ridx,50).match(dimregex);
if(ref != null) parse_ws_xml_dim(s, ref[1]);
@ -22,28 +23,27 @@ function parse_ws_xml(data, opts, rels) {
/* 18.3.1.55 mergeCells CT_MergeCells */
var mergecells = [];
if(data.indexOf("</mergeCells>")!==-1) {
var merges = data.match(mergecregex);
if(merges) for(ridx = 0; ridx != merges.length; ++ridx)
mergecells[ridx] = safe_decode_range(merges[ridx].substr(merges[ridx].indexOf("\"")+1));
}
var merges = data.match(mergecregex);
if(merges) for(ridx = 0; ridx != merges.length; ++ridx)
mergecells[ridx] = safe_decode_range(merges[ridx].substr(merges[ridx].indexOf("\"")+1));
/* 18.3.1.17 cols CT_Cols */
var columns = [];
if(opts.cellStyles && data.indexOf("</cols>")!==-1) {
if(opts.cellStyles) {
/* 18.3.1.13 col CT_Col */
var cols = data.match(colregex);
parse_ws_xml_cols(columns, cols);
if(cols) parse_ws_xml_cols(columns, cols);
}
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
/* 18.3.1.80 sheetData CT_SheetData ? */
var mtch=data.match(sheetdataregex);
if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess);
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
if(data.indexOf("</hyperlinks>")!==-1) parse_ws_xml_hlinks(s, data.match(hlinkregex), rels);
var hlink = data.match(hlinkregex);
if(hlink) parse_ws_xml_hlinks(s, hlink, rels);
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
if(opts.sheetRows > 0 && s["!ref"]) {
@ -109,11 +109,11 @@ function parse_ws_xml_cols(columns, cols) {
}
}
function write_ws_xml_cols(ws, cols) {
function write_ws_xml_cols(ws, cols)/*:string*/ {
var o = ["<cols>"], col, width;
for(var i = 0; i != cols.length; ++i) {
if(!(col = cols[i])) continue;
var p = {min:i+1,max:i+1};
var p = ({min:i+1,max:i+1}/*:any*/);
/* wch (chars), wpx (pixels) */
width = -1;
if(col.wpx) width = px2char(col.wpx);
@ -143,7 +143,7 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
break;
default: vv = cell.v; break;
}
var v = writetag('v', escapexml(vv)), o = {r:ref};
var v = writetag('v', escapexml(vv)), o = ({r:ref}/*:any*/);
/* TODO: cell style */
var os = get_cell_style(opts.cellXfs, cell, opts);
if(os !== 0) o.s = os;
@ -165,11 +165,11 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
var parse_ws_xml_data = (function parse_ws_xml_data_factory() {
var cellregex = /<(?:\w+:)?c[ >]/, rowregex = /<\/(?:\w+:)?row>/;
var rregex = /r=["']([^"']*)["']/, isregex = /<is>([\S\s]*?)<\/is>/;
var rregex = /r=["']([^"']*)["']/, isregex = /<(?:\w+:)?is>([\S\s]*?)<\/(?:\w+:)?is>/;
var match_v = matchtag("v"), match_f = matchtag("f");
return function parse_ws_xml_data(sdata, s, opts, guess) {
var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p;
var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p/*:any*/;
var tag, tagr = 0, tagc = 0;
var sstr;
var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf;
@ -194,7 +194,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
if(x.length === 0) continue;
cref = x.match(rregex); idx = ri; i=0; cc=0;
x = "<c " + (x.substr(0,1)=="<"?">":"") + x;
if(cref !== null && cref.length === 2) {
if(cref != null && cref.length === 2) {
idx = 0; d=cref[1];
for(i=0; i != d.length; ++i) {
if((cc=d.charCodeAt(i)-64) < 1 || cc > 26) break;
@ -207,10 +207,12 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
tag = parsexmltag(x.substr(0,i), true);
if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc});
d = x.substr(i);
p = {t:""};
p = ({t:""}/*:any*/);
if((cref=d.match(match_v))!== null && cref[1] !== '') p.v=unescapexml(cref[1]);
if(opts.cellFormula && (cref=d.match(match_f))!== null) p.f=unescapexml(cref[1]);
// $FlowIgnore
if((cref=d.match(match_v))!= null && cref[1] !== '') p.v=unescapexml(cref[1]);
// $FlowIgnore
if(opts.cellFormula && (cref=d.match(match_f))!= null && cref[1] !== '') p.f=unescapexml(cref[1]);
/* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */
if(tag.t === undefined && p.v === undefined) {
@ -237,7 +239,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
case 'inlineStr':
cref = d.match(isregex);
p.t = 's';
if(cref !== null) { sstr = parse_si(cref[1]); p.v = sstr.t; } else p.v = "";
if(cref != null) { if((sstr = parse_si(cref[1]))) p.v = sstr.t; } else p.v = "";
break; // inline string
case 'b': p.v = parsexmlbool(p.v); break;
case 'd':
@ -261,8 +263,8 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
}
}; })();
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C;
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R=0, C=0;
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 = [];
@ -282,7 +284,7 @@ var WS_XML_ROOT = writextag('worksheet', null, {
'xmlns:r': XMLNS.r
});
function write_ws_xml(idx/*:number*/, opts, wb)/*:string*/ {
function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
var o = [XML_HEADER, WS_XML_ROOT];
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
var ws = wb.Sheets[s];

View File

@ -222,10 +222,10 @@ function parse_ws_bin(data, opts, rels) {
var pass = false, end = false;
var row, p, cf, R, C, addr, sstr, rr;
var mergecells = [];
recordhopper(data, function ws_parse(val, R) {
//console.log(R);
recordhopper(data, function ws_parse(val, Record) {
//console.log(Record);
if(end) return;
switch(R.n) {
switch(Record.n) {
case 'BrtWsDim': ref = val; break;
case 'BrtRowHdr':
row = val;
@ -243,7 +243,7 @@ function parse_ws_bin(data, opts, rels) {
case 'BrtCellReal':
case 'BrtCellRk':
case 'BrtCellSt':
p = {t:val[2]};
p = ({t:val[2]}/*:any*/);
switch(val[2]) {
case 'n': p.v = val[1]; break;
case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
@ -261,7 +261,7 @@ function parse_ws_bin(data, opts, rels) {
break;
case 'BrtCellBlank': if(!opts.sheetStubs) break;
p = {t:'s',v:undefined};
p = ({t:'s',v:undefined}/*:any*/);
s[encode_col(C=val[0].c) + rr] = p;
if(refguess.s.r > row.r) refguess.s.r = row.r;
if(refguess.s.c > C) refguess.s.c = C;
@ -397,10 +397,10 @@ function parse_ws_bin(data, opts, rels) {
case 'BrtCellIgnoreEC': break;
case 'BrtEndCellIgnoreECs': break;
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + Record.n);
}
}, opts);
if(!s["!ref"] && (refguess.s.r < 2000000 || ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0)) s["!ref"] = encode_range(ref);
if(!s["!ref"] && (refguess.s.r < 2000000 || ref && (ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0))) s["!ref"] = encode_range(ref || refguess);
if(opts.sheetRows && s["!ref"]) {
var tmpref = safe_decode_range(s["!ref"]);
if(opts.sheetRows < +tmpref.e.r) {
@ -418,7 +418,7 @@ function parse_ws_bin(data, opts, rels) {
}
/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba, cell, R, C, opts) {
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
if(cell.v === undefined) return "";
var vv = "";
switch(cell.t) {
@ -426,7 +426,7 @@ function write_ws_bin_cell(ba, cell, R, C, opts) {
case 'n': case 'e': vv = ''+cell.v; break;
default: vv = cell.v; break;
}
var o = {r:R, c:C};
var o/*:CellAddress*/ = ({r:R, c:C}/*:any*/);
/* TODO: cell style */
o.s = get_cell_style(opts.cellXfs, cell, opts);
switch(cell.t) {

View File

@ -1,9 +1,10 @@
/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts) {
if(!data) throw new Error("Could not find file");
var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
var pass = false, xmlns = "xmlns";
data.match(tagregex).forEach(function xml_wb(x) {
(data.match(tagregex)||[]).forEach(function xml_wb(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<?xml': break;
@ -121,12 +122,12 @@ var WB_XML_ROOT = writextag('workbook', null, {
'xmlns:r': XMLNS.r
});
function safe1904(wb) {
function safe1904(wb/*:Workbook*/)/*:string*/ {
/* TODO: store date1904 somewhere else */
try { return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false"; } catch(e) { return "false"; }
}
function write_wb_xml(wb, opts) {
function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
var o = [XML_HEADER];
o[o.length] = WB_XML_ROOT;
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));

View File

@ -1,5 +1,5 @@
/* [MS-XLSB] 2.4.301 BrtBundleSh */
function parse_BrtBundleSh(data, length) {
function parse_BrtBundleSh(data, length/*:number*/) {
var z = {};
z.hsState = data.read_shift(4); //ST_SheetState
z.iTabID = data.read_shift(4);
@ -49,7 +49,7 @@ function parse_wb_bin(data, opts) {
case 'BrtBeginBook': break;
case 'BrtFileVersion': break;
case 'BrtWbProp': break;
case 'BrtWbProp14': case 'BrtWbProp': break;
case 'BrtACBegin': break;
case 'BrtAbsPath15': break;
case 'BrtACEnd': break;

58
bits/74_xmlbin.js Normal file
View File

@ -0,0 +1,58 @@
function parse_wb(data, name/*:string*/, opts)/*:Workbook*/ {
if(name.substr(name.length-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
return parse_wb_xml((data/*:any*/), opts);
}
function parse_ws(data, name/*:string*/, opts, rels)/*:Worksheet*/ {
if(name.substr(name.length-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels);
return parse_ws_xml((data/*:any*/), opts, rels);
}
function parse_sty(data, name/*:string*/, opts) {
if(name.substr(name.length-4)===".bin") return parse_sty_bin((data/*:any*/), opts);
return parse_sty_xml((data/*:any*/), opts);
}
function parse_theme(data, name/*:string*/, opts) {
return parse_theme_xml(data, opts);
}
function parse_sst(data, name/*:string*/, opts)/*:SST*/ {
if(name.substr(name.length-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
return parse_sst_xml((data/*:any*/), opts);
}
function parse_cmnt(data, name/*:string*/, opts) {
if(name.substr(name.length-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
return parse_comments_xml((data/*:any*/), opts);
}
function parse_cc(data, name/*:string*/, opts) {
if(name.substr(name.length-4)===".bin") return parse_cc_bin((data/*:any*/), opts);
return parse_cc_xml((data/*:any*/), opts);
}
function write_wb(wb, name/*:string*/, opts) {
return (name.substr(name.length-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
}
function write_ws(data/*:Worksheet*/, name/*:string*/, opts, wb/*:Workbook*/) {
return (name.substr(name.length-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
}
function write_sty(data, name/*:string*/, opts) {
return (name.substr(name.length-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
}
function write_sst(data/*:SST*/, name/*:string*/, opts) {
return (name.substr(name.length-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
}
/*
function write_cmnt(data, name:string, opts) {
return (name.substr(name.length-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
}
function write_cc(data, name:string, opts) {
return (name.substr(name.length-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
}
*/

View File

@ -1,13 +1,14 @@
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
var _chr = function(c) { return String.fromCharCode(c); };
function xlml_parsexmltag(tag, skip_root) {
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
var words = tag.split(/\s+/);
var z = []; if(!skip_root) z[0] = words[0];
var z/*:any*/ = ([]/*:any*/); if(!skip_root) z[0] = words[0];
if(words.length === 1) return z;
var m = tag.match(attregexg2), y, j, w, i;
if(m) for(i = 0; i != m.length; ++i) {
y = m[i].match(attregex2);
/*:: if(!y || !y[2]) continue; */
if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].substr(1,y[2].length-2);
else {
if(y[1].substr(0,6) === "xmlns:") w = "xmlns"+y[1].substr(6);
@ -17,13 +18,14 @@ function xlml_parsexmltag(tag, skip_root) {
}
return z;
}
function xlml_parsexmltagobj(tag) {
function xlml_parsexmltagobj(tag/*:string*/) {
var words = tag.split(/\s+/);
var z = {};
if(words.length === 1) return z;
var m = tag.match(attregexg2), y, j, w, i;
if(m) for(i = 0; i != m.length; ++i) {
y = m[i].match(attregex2);
/*:: if(!y || !y[2]) continue; */
if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].substr(1,y[2].length-2);
else {
if(y[1].substr(0,6) === "xmlns:") w = "xmlns"+y[1].substr(6);
@ -36,7 +38,7 @@ function xlml_parsexmltagobj(tag) {
// ----
function xlml_format(format, value) {
function xlml_format(format, value)/*:string*/ {
var fmt = XLMLFormatMap[format] || unescapexml(format);
if(fmt === "General") return SSF._general(value);
return SSF.format(fmt, value);
@ -54,7 +56,7 @@ function xlml_set_custprop(Custprops, Rn, cp, val) {
Custprops[unescapexml(Rn[3])] = val;
}
function safe_format_xlml(cell, nf, o) {
function safe_format_xlml(cell/*:Cell*/, nf, o) {
try {
if(cell.t === 'e') { cell.w = cell.w || BErr[cell.v]; }
else if(nf === "General") {
@ -80,7 +82,7 @@ function process_style_xlml(styles, stag, opts) {
}
/* TODO: there must exist some form of OSP-blessed spec */
function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, o) {
function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, o)/*:Workbook*/ {
var nf = "General", sid = cell.StyleID, S = {}; o = o || {};
var interiors = [];
if(sid === undefined && row) sid = row.StyleID;
@ -127,15 +129,15 @@ function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, o) {
cell.ixfe = cell.StyleID !== undefined ? cell.StyleID : 'Default';
}
function xlml_clean_comment(comment) {
function xlml_clean_comment(comment/*:any*/) {
comment.t = comment.v;
comment.v = comment.w = comment.ixfe = undefined;
}
function xlml_normalize(d) {
function xlml_normalize(d)/*:string*/ {
if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8');
if(typeof d === 'string') return d;
throw "badf";
throw new Error("Bad input format: expected Buffer or string");
}
/* TODO: Everything */
@ -145,7 +147,8 @@ function parse_xlml_xml(d, opts) {
var Rn;
var state = [], tmp;
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
var table = {}, cell = {}, row = {}, dtag, didx;
var table = {}, cell = ({}/*:any*/), row = {};
var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
var c = 0, r = 0;
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
var styles = {}, stag = {};
@ -677,7 +680,7 @@ function parse_xlml_xml(d, opts) {
}
if(opts.WTF) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
}
var out = {};
var out = ({}/*:Any*/);
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
out.SheetNames = sheetnames;
out.SSF = SSF.get_table();
@ -695,5 +698,7 @@ function parse_xlml(data, opts) {
}
}
function write_xlml(wb, opts) { }
function write_xlml(wb, opts)/*:string*/ {
var o = [XML_HEADER];
return o.join("");
}

View File

@ -22,11 +22,11 @@ function parse_compobj(obj) {
m = __lpstr(o, l); l += m.length === 0 ? 0 : 5 + m.length; v.Reserved1 = m;
if((m = __readUInt32LE(o,l)) !== 0x71b2e9f4) return v;
throw "Unsupported Unicode Extension";
throw new Error("Unsupported Unicode Extension");
}
/* 2.4.58 Continue logic */
function slurp(R, blob, length, opts) {
function slurp(R, blob, length/*:number*/, opts) {
var l = length;
var bufs = [];
var d = blob.slice(blob.l,blob.l+l);
@ -45,7 +45,7 @@ function slurp(R, blob, length, opts) {
blob.l += 4+l;
next = (XLSRecordEnum[__readUInt16LE(blob, blob.l)]);
}
var b = bconcat(bufs);
var b = (bconcat(bufs)/*:any*/);
prep_blob(b, 0);
var ll = 0; b.lens = [];
for(var j = 0; j < bufs.length; ++j) { b.lens.push(ll); ll += bufs[j].length; }
@ -53,10 +53,11 @@ function slurp(R, blob, length, opts) {
}
function safe_format_xf(p, opts, date1904) {
if(p.t === 'e') { p.w = p.w || BErr[p.v]; }
if(!p.XF) return;
try {
var fmtid = p.XF.ifmt||0;
if(p.t === 'e') { p.w = p.w || BErr[p.v]; }
if(p.t === 'e');
else if(fmtid === 0) {
if(p.t === 'n') {
if((p.v|0) === p.v) p.w = SSF._general_int(p.v);
@ -69,13 +70,13 @@ function safe_format_xf(p, opts, date1904) {
} catch(e) { if(opts.WTF) throw e; }
}
function make_cell(val, ixfe, t) {
return {v:val, ixfe:ixfe, t:t};
function make_cell(val, ixfe, t)/*:any*/ {
return ({v:val, ixfe:ixfe, t:t}/*:any*/);
}
// 2.3.2
function parse_workbook(blob, options) {
var wb = {opts:{}};
function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
var wb = ({opts:{}}/*:any*/);
var Sheets = {};
var out = {};
var Directory = {};
@ -123,7 +124,7 @@ function parse_workbook(blob, options) {
if(options.sheetRows && lastcell.r >= options.sheetRows) cell_valid = false;
else out[last_cell] = line;
};
var opts = {
var opts = ({
enc: false, // encrypted
sbcch: 0, // cch in the preceding SupBook
snames: [], // sheetnames
@ -135,17 +136,18 @@ function parse_workbook(blob, options) {
codepage: 0, // CP from CodePage record
winlocked: 0, // fLockWn from WinProtect
wtf: false
};
}/*:any*/);
if(options.password) opts.password = options.password;
var mergecells = [];
var objects = [];
var supbooks = [[]]; // 1-indexed, will hold extern names
var supbooks = ([[]]/*:any*/); // 1-indexed, will hold extern names
var sbc = 0, sbci = 0, sbcli = 0;
supbooks.SheetNames = opts.snames;
supbooks.sharedf = opts.sharedf;
supbooks.arrayf = opts.arrayf;
var last_Rn = '';
var file_depth = 0; /* TODO: make a real stack */
var BIFF2Fmt = 0;
/* explicit override for some broken writers */
opts.codepage = 1200;
@ -157,6 +159,7 @@ function parse_workbook(blob, options) {
if(RecordType === 0 && last_Rn === 'EOF') break;
var length = (blob.l === blob.length ? 0 : blob.read_shift(2)), y;
var R = XLSRecordEnum[RecordType];
//console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length);
if(R && R.f) {
if(options.bookSheets) {
if(last_Rn === 'BoundSheet8' && R.n !== 'BoundSheet8') break;
@ -172,10 +175,6 @@ function parse_workbook(blob, options) {
if(R.n === 'EOF') val = R.f(blob, length, opts);
else val = slurp(R, blob, length, opts);
var Rn = R.n;
/* BIFF5 overrides */
if(opts.biff === 5 || opts.biff === 2) switch(Rn) {
case 'Lbl': Rn = 'Label'; break;
}
/* nested switch statements to workaround V8 128 limit */
switch(Rn) {
/* Workbook Options */
@ -253,41 +252,48 @@ function parse_workbook(blob, options) {
out = {};
} break;
case 'BOF': {
if(opts.biff !== 8);
if(opts.biff !== 8){}
else if(val.BIFFVer === 0x0500) opts.biff = 5;
else if(val.BIFFVer === 0x0002) opts.biff = 2;
else if(val.BIFFVer === 0x0007) opts.biff = 2;
else if(RecordType === 0x0009) opts.biff = 2;
else if(RecordType === 0x0209) opts.biff = 3;
else if(RecordType === 0x0409) opts.biff = 4;
if(file_depth++) break;
cell_valid = true;
out = {};
if(opts.biff === 2) {
if(opts.biff < 5) {
if(cur_sheet === "") cur_sheet = "Sheet1";
range = {s:{r:0,c:0},e:{r:0,c:0}};
/* fake BoundSheet8 */
var fakebs8 = {pos: blob.l - length, name:cur_sheet};
Directory[fakebs8.pos] = fakebs8;
opts.snames.push(cur_sheet);
}
else cur_sheet = (Directory[s] || {name:""}).name;
mergecells = [];
objects = [];
} break;
case 'Number': case 'BIFF2NUM': {
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'};
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
case 'BoolErr': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t};
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
case 'RK': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'};
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
} break;
case 'MulRk': {
for(var j = val.c; j <= val.C; ++j) {
var ixfe = val.rkrec[j-val.c][0];
temp_val= {ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'};
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:j, r:val.r}, temp_val, options);
}
} break;
@ -296,10 +302,10 @@ function parse_workbook(blob, options) {
case 'String': last_formula = val; break;
case 'Array Formula': throw "Array Formula unsupported";
default:
temp_val = {v:val.val, ixfe:val.cell.ixfe, t:val.tt};
temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}/*:any*/);
temp_val.XF = XFs[temp_val.ixfe];
if(options.cellFormula) temp_val.f = "="+stringify_formula(val.formula,range,val.cell,supbooks, opts);
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell(val.cell, temp_val, options);
last_formula = val;
}
@ -307,10 +313,10 @@ function parse_workbook(blob, options) {
case 'String': {
if(last_formula) {
last_formula.val = val;
temp_val = {v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'};
temp_val = ({v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/);
temp_val.XF = XFs[temp_val.ixfe];
if(options.cellFormula) temp_val.f = "="+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell(last_formula.cell, temp_val, options);
last_formula = null;
}
@ -322,20 +328,18 @@ function parse_workbook(blob, options) {
if(!cell_valid) break;
//if(options.cellFormula) out[last_cell].f = stringify_formula(val[0], range, lastcell, supbooks, opts);
/* TODO: capture range */
shared_formulae[encode_cell(last_formula.cell)]= val[0];
if(last_formula) shared_formulae[encode_cell(last_formula.cell)]= val[0];
} break;
case 'LabelSst':
//temp_val={v:sst[val.isst].t, ixfe:val.ixfe, t:'s'};
temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
temp_val.XF = XFs[temp_val.ixfe];
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
break;
case 'Label': case 'BIFF2STR':
/* Some writers erroneously write Label */
temp_val=make_cell(val.val, val.ixfe, 's');
temp_val.XF = XFs[temp_val.ixfe];
if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904);
safe_format_xf(temp_val, options, wb.opts.Date1904);
addcell({c:val.c, r:val.r}, temp_val, options);
break;
case 'Dimensions': {
@ -347,6 +351,9 @@ function parse_workbook(blob, options) {
case 'Format': { /* val = [id, fmt] */
SSF.load(val[1], val[0]);
} break;
case 'BIFF2FORMAT': {
SSF.load(val, BIFF2Fmt++);
} break;
case 'MergeCells': mergecells = mergecells.concat(val); break;
@ -599,12 +606,18 @@ function parse_workbook(blob, options) {
/* Future Records */
case 'FrtFontList': case 'FrtWrapper': break;
default: switch(R.n) { /* nested */
/* BIFF5 records */
case 'ExternCount': break;
case 'RString': break;
case 'TabIdConf': case 'Radar': case 'RadarArea': case 'DropBar': case 'Intl': case 'CoordList': case 'SerAuxErrBar': break;
default: switch(R.n) { /* nested */
/* BIFF2-4 records */
case 'BIFF2FONTCLR': case 'BIFF2FMTCNT': break;
case 'BIFF2XF': case 'BIFF3XF': case 'BIFF4XF': break;
case 'BIFF4FMTCNT': case 'BIFF2ROW': case 'BIFF2WINDOW2': break;
case 'Dimension': break;
/* Miscellaneous */
case 'SCENARIO': case 'DConBin': case 'PicF': case 'DataLabExt':
case 'Lel': case 'BopPop': case 'BopPopCustom': case 'RealTimeData':
@ -613,7 +626,7 @@ function parse_workbook(blob, options) {
}}}}
} else blob.l += length;
}
var sheetnamesraw = opts.biff === 2 ? ['Sheet1'] : Object.keys(Directory).sort(function(a,b) { return Number(a) - Number(b); }).map(function(x){return Directory[x].name;});
var sheetnamesraw = Object.keys(Directory).sort(function(a,b) { return Number(a) - Number(b); }).map(function(x){return Directory[x].name;});
var sheetnames = sheetnamesraw.slice();
wb.Directory=sheetnamesraw;
wb.SheetNames=sheetnamesraw;
@ -627,22 +640,22 @@ function parse_workbook(blob, options) {
return wb;
}
function parse_xlscfb(cfb, options) {
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/) {
if(!options) options = {};
fix_read_opts(options);
reset_cp();
var CompObj, Summary, Workbook;
if(cfb.find) {
var CompObj, Summary, Workbook/*:?any*/;
if(cfb.FullPaths) {
CompObj = cfb.find('!CompObj');
Summary = cfb.find('!SummaryInformation');
Workbook = cfb.find('/Workbook');
} else {
prep_blob(cfb, 0);
Workbook = {content: cfb};
Workbook = ({content: cfb}/*:any*/);
}
if(!Workbook) Workbook = cfb.find('/Book');
var CompObjP, SummaryP, WorkbookP;
var CompObjP, SummaryP, WorkbookP/*:?any*/;
if(CompObj) CompObjP = parse_compobj(CompObj);
if(options.bookProps && !options.bookSheets) WorkbookP = {};
@ -651,7 +664,7 @@ else {
else throw new Error("Cannot find Workbook stream");
}
if(cfb.find) parse_props(cfb);
if(cfb.FullPaths) parse_props(cfb);
var props = {};
for(var y in cfb.Summary) props[y] = cfb.Summary[y];

1249
bits/77_parsetab.js Normal file

File diff suppressed because it is too large Load Diff

118
bits/78_writebiff.js Normal file
View File

@ -0,0 +1,118 @@
/* BIFF2-4 single-sheet workbooks */
function write_biff_rec(ba/*:BufArray*/, t/*:number*/, payload, length/*:?number*/) {
var len = (length || (payload||[]).length);
var o = ba.next(4 + len);
o.write_shift(2, t);
o.write_shift(2, len);
if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
}
function write_BOF(wb/*:Workbook*/, o) {
if(o.bookType != 'biff2') throw "unsupported BIFF version";
var out = new_buf(4);
out.write_shift(2, 0x0002); // "unused"
out.write_shift(2, 0x0010); // Sheet
return out;
}
function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
if(!out) out = new_buf(7);
out.write_shift(2, r);
out.write_shift(2, c);
out.write_shift(1, 0);
out.write_shift(1, 0);
out.write_shift(1, 0);
return out;
}
function write_BIFF2INT(r/*:number*/, c/*:number*/, val) {
var out = new_buf(9);
write_BIFF2Cell(out, r, c);
out.write_shift(2, val);
return out;
}
function write_BIFF2NUMBER(r, c, val) {
var out = new_buf(15);
write_BIFF2Cell(out, r, c);
out.write_shift(8, val, 'f');
return out;
}
function write_BIFF2BERR(r, c, val, t) {
var out = new_buf(9);
write_BIFF2Cell(out, r, c);
if(t == 'e') { out.write_shift(1, val); out.write_shift(1, 1); }
else { out.write_shift(1, val?1:0); out.write_shift(1, 0); }
return out;
}
/* TODO: codepage, large strings */
function write_BIFF2LABEL(r, c, val) {
var out = new_buf(8 + 2*val.length);
write_BIFF2Cell(out, r, c);
out.write_shift(1, val.length);
out.write_shift(val.length, val, 'sbcs');
return out.l < out.length ? out.slice(0, out.l) : out;
}
function write_ws_biff_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
switch(cell.t) {
case 'n':
if((cell.v == (cell.v|0)) && (cell.v >= 0) && (cell.v < 65536))
write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, cell.v));
else
write_biff_rec(ba, 0x0003, write_BIFF2NUMBER(R,C, cell.v));
break;
case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); break;
/* TODO: codepage, sst */
case 's': case 'str':
write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, cell.v));
break;
default: write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
}
}
function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
for(var R = range.s.r; R <= range.e.r; ++R) {
rr = encode_row(R);
for(var C = range.s.c; C <= range.e.c; ++C) {
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
if(!ws[ref]) continue;
/* write cell */
write_ws_biff_cell(ba, ws[ref], R, C, opts);
}
}
}
/* Based on test files */
function write_biff_buf(wb/*:Workbook*/, o/*:WriteOpts*/) {
var ba = buf_array();
var idx = 0;
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
write_biff_rec(ba, 0x0009, write_BOF(wb, o));
/* ... */
write_biff_ws(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
/* ... */
write_biff_rec(ba, 0x000a);
// TODO
return ba.end();
}
function write_biff(wb/*:Workbook*/, o/*:WriteOpts*/) {
var out = write_biff_buf(wb, o);
switch(o.type) {
case "base64": break; // TODO
case "binary": {
var bstr = "";
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
return bstr;
}
case "file": return _fs.writeFileSync(o.file, out);
case "buffer": return out;
default: throw new Error("Unrecognized type " + o.type);
}
}

View File

@ -1,52 +0,0 @@
function parse_wb(data, name, opts) {
return (name.substr(-4)===".bin" ? parse_wb_bin : parse_wb_xml)(data, opts);
}
function parse_ws(data, name, opts, rels) {
return (name.substr(-4)===".bin" ? parse_ws_bin : parse_ws_xml)(data, opts, rels);
}
function parse_sty(data, name, opts) {
return (name.substr(-4)===".bin" ? parse_sty_bin : parse_sty_xml)(data, opts);
}
function parse_theme(data, name, opts) {
return parse_theme_xml(data, opts);
}
function parse_sst(data, name, opts) {
return (name.substr(-4)===".bin" ? parse_sst_bin : parse_sst_xml)(data, opts);
}
function parse_cmnt(data, name, opts) {
return (name.substr(-4)===".bin" ? parse_comments_bin : parse_comments_xml)(data, opts);
}
function parse_cc(data, name, opts) {
return (name.substr(-4)===".bin" ? parse_cc_bin : parse_cc_xml)(data, opts);
}
function write_wb(wb, name, opts) {
return (name.substr(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
}
function write_ws(data, name, opts, wb) {
return (name.substr(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
}
function write_sty(data, name, opts) {
return (name.substr(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
}
function write_sst(data, name, opts) {
return (name.substr(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
}
/*
function write_cmnt(data, name, opts) {
return (name.substr(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
}
function write_cc(data, name, opts) {
return (name.substr(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
}
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
function fix_opts_func(defaults) {
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
return function fix_opts(opts) {
for(var i = 0; i != defaults.length; ++i) {
var d = defaults[i];

View File

@ -6,15 +6,15 @@ function safe_parse_wbrels(wbrels, sheets) {
return !wbrels || wbrels.length === 0 ? null : wbrels;
}
function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts) {
function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRels, sheets, opts) {
try {
sheetRels[sheet]=parse_rels(getzipdata(zip, relsPath, true), path);
sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet]);
} catch(e) { if(opts.WTF) throw e; }
}
var nodirs = function nodirs(x){return x.substr(-1) != '/';};
function parse_zip(zip, opts) {
var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.substr(-1) != '/';};
function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
make_ssf(SSF);
opts = opts || {};
fix_read_opts(opts);
@ -24,7 +24,7 @@ function parse_zip(zip, opts) {
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
var entries = keys(zip.files).filter(nodirs).sort();
var dir = parse_ct(getzipdata(zip, '[Content_Types].xml'), opts);
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/), opts);
var xlsb = false;
var sheets, binname;
if(dir.workbooks.length === 0) {
@ -56,10 +56,10 @@ function parse_zip(zip, opts) {
var props = {}, propdata = "";
if(dir.coreprops.length !== 0) {
propdata = getzipdata(zip, dir.coreprops[0].replace(/^\//,''), true);
propdata = getzipstr(zip, dir.coreprops[0].replace(/^\//,''), true);
if(propdata) props = parse_core_props(propdata);
if(dir.extprops.length !== 0) {
propdata = getzipdata(zip, dir.extprops[0].replace(/^\//,''), true);
propdata = getzipstr(zip, dir.extprops[0].replace(/^\//,''), true);
if(propdata) parse_ext_props(propdata, props);
}
}
@ -67,7 +67,7 @@ function parse_zip(zip, opts) {
var custprops = {};
if(!opts.bookSheets || opts.bookProps) {
if (dir.custprops.length !== 0) {
propdata = getzipdata(zip, dir.custprops[0].replace(/^\//,''), true);
propdata = getzipstr(zip, dir.custprops[0].replace(/^\//,''), true);
if(propdata) custprops = parse_cust_props(propdata, opts);
}
}
@ -86,7 +86,7 @@ function parse_zip(zip, opts) {
if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, dir.calcchain.replace(/^\//,'')),dir.calcchain,opts);
var i=0;
var sheetRels = {};
var sheetRels = ({}/*:any*/);
var path, relsPath;
if(!props.Worksheets) {
var wbsheets = wb.Sheets;
@ -99,12 +99,12 @@ function parse_zip(zip, opts) {
var wbext = xlsb ? "bin" : "xml";
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
var wbrels = parse_rels(getzipdata(zip, wbrelsfile, true), wbrelsfile);
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
/* Numbers iOS hack */
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
for(i = 0; i != props.Worksheets; ++i) {
if(wbrels) path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
if(wbrels && wbrels[i]) path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
else {
path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;
path = path.replace(/sheet0\./,"sheet.");
@ -115,7 +115,7 @@ function parse_zip(zip, opts) {
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
out = {
out = ({
Directory: dir,
Workbook: wb,
Props: props,
@ -127,14 +127,14 @@ function parse_zip(zip, opts) {
Styles: styles,
Themes: themes,
SSF: SSF.get_table()
};
}/*:any*/);
if(opts.bookFiles) {
out.keys = entries;
out.files = zip.files;
}
if(opts.bookVBA) {
if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,dir.vba[0],true);
else if(dir.defaults.bin === 'application/vnd.ms-office.vbaProject') out.vbaraw = getzipdata(zip,'xl/vbaProject.bin',true);
else if(dir.defaults && dir.defaults.bin === 'application/vnd.ms-office.vbaProject') out.vbaraw = getzipdata(zip,'xl/vbaProject.bin',true);
}
return out;
}

View File

@ -9,7 +9,7 @@ function add_rels(rels, rId, f, type, relobj) {
rels[('/' + relobj.Target).replace("//","/")] = relobj;
}
function write_zip(wb, opts) {
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/) {
if(opts.bookType == "ods") return write_ods(wb, opts);
if(wb && !wb.SSF) {
wb.SSF = SSF.get_table();
@ -25,19 +25,21 @@ function write_zip(wb, opts) {
coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [],
TODO:[], rels:[], xmlns: "" };
fix_write_opts(opts = opts || {});
/*:: if(!jszip) throw new Error("JSZip is not available"); */
var zip = new jszip();
var f = "", rId = 0;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
if(!wb.Props) wb.Props = {};
f = "docProps/core.xml";
zip.file(f, write_core_props(wb.Props, opts));
ct.coreprops.push(f);
add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
f = "docProps/app.xml";
if(!wb.Props) wb.Props = {};
wb.Props.SheetNames = wb.SheetNames;
wb.Props.Worksheets = wb.SheetNames.length;
zip.file(f, write_ext_props(wb.Props, opts));

View File

@ -1,14 +1,15 @@
function firstbyte(f,o) {
function firstbyte(f/*:RawData*/,o/*:?TypeOpts*/)/*:number*/ {
switch((o||{}).type || "base64") {
case 'buffer': return f[0];
case 'base64': return Base64.decode(f.substr(0,12)).charCodeAt(0);
case 'binary': return f.charCodeAt(0);
case 'array': return f[0];
default: throw new Error("Unrecognized type " + o.type);
default: throw new Error("Unrecognized type " + (o ? o.type : "undefined"));
}
}
function read_zip(data, opts) {
function read_zip(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
/*:: if(!jszip) throw new Error("JSZip is not available"); */
var zip, d = data;
var o = opts||{};
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
@ -16,31 +17,26 @@ function read_zip(data, opts) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
case "buffer": zip = new jszip(d); break;
case "file": zip=new jszip(d=_fs.readFileSync(data)); break;
default: throw new Error("Unrecognized type " + o.type);
}
return parse_zip(zip, o);
}
function readSync(data, opts) {
var zip, d = data, isfile = false, n;
function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var zip, d = data, n=0;
var o = opts||{};
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
if(o.type == "file") { isfile = true; o.type = "buffer"; d = _fs.readFileSync(data); }
if(o.type == "file") { o.type = "buffer"; d = _fs.readFileSync(data); }
switch((n = firstbyte(d, o))) {
case 0xD0:
if(isfile) o.type = "file";
return parse_xlscfb(CFB.read(data, o), o);
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(data) : data), o);
case 0xD0: return parse_xlscfb(CFB.read(d, o), o);
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o);
case 0x3C: return parse_xlml(d, o);
case 0x50:
if(isfile) o.type = "file";
return read_zip(data, opts);
case 0x50: return read_zip(d, o);
default: throw new Error("Unsupported file " + n);
}
}
function readFileSync(data, opts) {
function readFileSync(filename/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{}; o.type = 'file';
return readSync(data, o);
return readSync(filename, o);
}

View File

@ -1,8 +1,8 @@
function write_zip_type(wb, opts) {
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
var o = opts||{};
var z = write_zip(wb, o);
var oopts = {};
if(opts.compression) oopts.compression = 'DEFLATE';
if(o.compression) oopts.compression = 'DEFLATE';
switch(o.type) {
case "base64": oopts.type = "base64"; break;
case "binary": oopts.type = "string"; break;
@ -14,15 +14,16 @@ function write_zip_type(wb, opts) {
return z.generate(oopts);
}
function writeSync(wb, opts) {
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
var o = opts||{};
switch(o.bookType) {
case 'xml': return write_xlml(wb, o);
case 'biff2': return write_biff(wb, o);
default: return write_zip_type(wb, o);
}
}
function writeFileSync(wb, filename, opts) {
function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOpts*/) {
var o = opts||{}; o.type = 'file';
o.file = filename;
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
@ -30,7 +31,7 @@ function writeFileSync(wb, filename, opts) {
case '.xlsm': o.bookType = 'xlsm'; break;
case '.xlsb': o.bookType = 'xlsb'; break;
default: switch(o.file.substr(-4).toLowerCase()) {
case '.xls': o.bookType = 'xls'; break;
case '.xls': o.bookType = 'biff2'; break;
case '.xml': o.bookType = 'xml'; break;
case '.ods': o.bookType = 'ods'; break;
}}

View File

@ -1,26 +1,26 @@
function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
function encode_row(row) { return "" + (row + 1); }
function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); }
function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); }
function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); }
function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); }
function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); }
function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); }
function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); }
function fix_cell(cstr) { return fix_col(fix_row(cstr)); }
function unfix_cell(cstr) { return unfix_col(unfix_row(cstr)); }
function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
function encode_range(cs,ce) {
function split_cell(cstr/*:string*/)/*:Array<string>*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
function encode_cell(cell/*:Cell*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); }
function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); }
function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); }
function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; }
function encode_range(cs/*:any*/,ce/*:?any*/)/*:string*/ {
if(ce === undefined || typeof ce === 'number') return encode_range(cs.s, cs.e);
if(typeof cs !== 'string') cs = encode_cell(cs); if(typeof ce !== 'string') ce = encode_cell(ce);
return cs == ce ? cs : cs + ":" + ce;
}
function safe_decode_range(range) {
function safe_decode_range(range/*:string*/)/*:Range*/ {
var o = {s:{c:0,r:0},e:{c:0,r:0}};
var idx = 0, i = 0, cc = 0;
var len = range.length;
@ -52,20 +52,20 @@ function safe_decode_range(range) {
return o;
}
function safe_format_cell(cell, v) {
function safe_format_cell(cell/*:Cell*/, v/*:any*/) {
if(cell.z !== undefined) try { return (cell.w = SSF.format(cell.z, v)); } catch(e) { }
if(!cell.XF) return v;
try { return (cell.w = SSF.format(cell.XF.ifmt||0, v)); } catch(e) { return ''+v; }
}
function format_cell(cell, v) {
function format_cell(cell/*:Cell*/, v/*:any*/) {
if(cell == null || cell.t == null) return "";
if(cell.w !== undefined) return cell.w;
if(v === undefined) return safe_format_cell(cell, cell.v);
return safe_format_cell(cell, v);
}
function sheet_to_json(sheet, opts){
function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/){
var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v;
var o = opts != null ? opts : {};
var raw = o.raw;
@ -127,9 +127,9 @@ function sheet_to_json(sheet, opts){
return out;
}
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); }
function sheet_to_row_object_array(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) { return sheet_to_json(sheet, opts != null ? opts : {}); }
function sheet_to_csv(sheet, opts) {
function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
var out = "", txt = "", qreg = /"/g;
var o = opts == null ? {} : opts;
if(sheet == null || sheet["!ref"] == null) return "";
@ -156,7 +156,7 @@ function sheet_to_csv(sheet, opts) {
}
var make_csv = sheet_to_csv;
function sheet_to_formulae(sheet) {
function sheet_to_formulae(sheet/*:Worksheet*/) {
var cmds, y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return "";
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;

View File

@ -1,8 +1,7 @@
{
"name": "js-xlsx",
"homepage": "https://github.com/SheetJS/js-xlsx",
"main": "dist/xlsx.js",
"version": "0.8.2",
"main": "dist/xlsx.core.min.js",
"ignore": [
"bin",
"bits",

3
dist/ods.js vendored
View File

@ -61,8 +61,7 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
if(typeof jszip === 'undefined') jszip = require('./js'+'zip');
_fs = require('f'+'s');
}
}

2
dist/ods.min.js vendored

File diff suppressed because one or more lines are too long

2
dist/ods.min.map vendored

File diff suppressed because one or more lines are too long

20
dist/xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

29
dist/xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

5657
dist/xlsx.js vendored

File diff suppressed because one or more lines are too long

20
dist/xlsx.min.js vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map vendored

File diff suppressed because one or more lines are too long

View File

@ -1,23 +0,0 @@
{
"name": "js-xlsx",
"homepage": "https://github.com/SheetJS/js-xlsx",
"main": "dist/xlsx.js",
"version": "_VERSION_",
"ignore": [
"bin",
"bits",
"misc",
"**/.*"
],
"keywords": [
"excel",
"xls",
"xml",
"xlsx",
"xlsm",
"xlsb",
"ods",
"js-xls",
"js-xlsx"
]
}

View File

@ -1,12 +1,40 @@
/*::
type ZIPFile = any;
type ParseOpts = any;
type Workbook = {
SheetNames: Array<string>;
Sheets: any;
};
interface CellAddress {
r:number;
c:number;
};
type Cell = any;
type Range = {
s: CellAddress;
e: CellAddress;
}
type Worksheet = any;
type Sheet2CSVOpts = any;
type Sheet2JSONOpts = any;
type ParseOpts = any;
type WriteOpts = any;
type WriteFileOpts = any;
type RawData = any;
interface TypeOpts {
type:string;
}
type XLSXModule = any;
type SST = any;
type Comment = any;
*/

View File

@ -5,4 +5,6 @@ declare module 'xlsx' { declare var exports:XLSXModule; };
declare module '../' { declare var exports:XLSXModule; };
declare module 'commander' { declare var exports:any; };
type ZIP = any;
*/

View File

@ -17,13 +17,13 @@ var get_utils = function() {
};
var has_buf = (typeof Buffer !== 'undefined');
function cc2str(arr) {
function cc2str(arr)/*:string*/ {
var o = "";
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
return o;
}
function dup(o/*:object*/)/*:object*/ {
function dup(o/*:any*/)/*:any*/ {
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
if(typeof o != 'object' || !o) return o;
var out = {};
@ -63,8 +63,7 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
if(typeof jszip === 'undefined') jszip = require('./js'+'zip');
_fs = require('f'+'s');
}
}

3
ods.js
View File

@ -61,8 +61,7 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
if(typeof jszip === 'undefined') jszip = require('./js'+'zip');
_fs = require('f'+'s');
}
}

View File

@ -1,12 +1,12 @@
var has_buf = (typeof Buffer !== 'undefined');
function cc2str(arr) {
function cc2str(arr)/*:string*/ {
var o = "";
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
return o;
}
function dup(o/*:object*/)/*:object*/ {
function dup(o/*:any*/)/*:any*/ {
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
if(typeof o != 'object' || !o) return o;
var out = {};

View File

@ -31,8 +31,7 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
if(typeof jszip === 'undefined') jszip = require('./js'+'zip');
_fs = require('f'+'s');
}
}

View File

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.8.2",
"version": "0.8.3",
"author": "sheetjs",
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS spreadsheet parser and writer",
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ],
@ -13,7 +13,6 @@
"ssf":"~0.8.1",
"codepage":"",
"cfb":">=0.10.0",
"jszip":"2.4.0",
"crc-32":"",
"adler-32":"",
"commander":""

44
test.js
View File

@ -12,6 +12,7 @@ if(process.env.WTF) {
opts.cellStyles = true;
}
var fullex = [".xlsb", ".xlsm", ".xlsx"];
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2"];
var ex = fullex.slice(); ex.push(".ods"); ex.push(".xls"); ex.push("xml");
if(process.env.FMTS === "full") process.env.FMTS = ex.join(":");
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
@ -1033,6 +1034,47 @@ describe('json output', function() {
});
});
describe('js -> file -> js', function() {
var data, ws, wb, BIN="binary";
before(function() {
data = [
[1,2,3],
[true, false, null, "sheetjs"],
["foo","bar",new Date("2014-02-19T14:30Z"), "0.3"],
["baz", 6.9, "qux"]
];
ws = sheet_from_array_of_arrays(data);
wb = { SheetNames: ['Sheet1'], Sheets: {Sheet1: ws} };
});
function eqcell(wb1, wb2, s, a) {
assert.equal(wb1.Sheets[s][a].v, wb2.Sheets[s][a].v);
assert.equal(wb1.Sheets[s][a].t, wb2.Sheets[s][a].t);
}
ofmt.forEach(function(f) {
it(f, function() {
var newwb = X.read(X.write(wb, {type:BIN, bookType: f}), {type:BIN});
/* int */
eqcell(wb, newwb, 'Sheet1', 'A1');
eqcell(wb, newwb, 'Sheet1', 'B1');
eqcell(wb, newwb, 'Sheet1', 'C1');
/* double */
eqcell(wb, newwb, 'Sheet1', 'B4');
/* bool */
eqcell(wb, newwb, 'Sheet1', 'A2');
eqcell(wb, newwb, 'Sheet1', 'B2');
/* string */
eqcell(wb, newwb, 'Sheet1', 'D2');
eqcell(wb, newwb, 'Sheet1', 'A3');
eqcell(wb, newwb, 'Sheet1', 'B3');
eqcell(wb, newwb, 'Sheet1', 'D3');
eqcell(wb, newwb, 'Sheet1', 'A4');
eqcell(wb, newwb, 'Sheet1', 'C4');
/* date */
eqcell(wb, newwb, 'Sheet1', 'C3');
});
});
});
describe('corner cases', function() {
it('output functions', function() {
var data = [
@ -1054,6 +1096,8 @@ describe('corner cases', function() {
X.write(wb, {type: "binary", bookType: 'xlsx'});
X.write(wb, {type: "buffer", bookType: 'xlsm'});
X.write(wb, {type: "base64", bookType: 'xlsb'});
X.write(wb, {type: "binary", bookType: 'ods'});
X.write(wb, {type: "binary", bookType: 'biff2'});
ws.A2.t = "f";
assert.throws(function() { X.utils.make_json(ws); });
});

View File

@ -25,7 +25,7 @@ text_and_numbers.xlsb
xlsx-stream-d-date-cell.xlsb
2013/apachepoi_29982.xls.xlsb
2013/apachepoi_43251.xls.xlsb
#2013/apachepoi_44593.xls.xlsb ## xlsb loop timeout
2013/apachepoi_44593.xls.xlsb ## xlsb loop timeout
2013/apachepoi_44643.xls.xlsb
2013/apachepoi_44958.xls.xlsb
2013/apachepoi_46136-NoWarnings.xls.xlsb
@ -344,7 +344,7 @@ formula_stress_test.ods
merge_cells.ods
number_format.ods
rich_text_stress.ods
# roo_Bibelbund.ods ## timeout
roo_Bibelbund.ods
roo_Bibelbund1.ods
roo_bbu.ods
roo_boolean.ods
@ -475,7 +475,7 @@ apachepoi_44200.xls
apachepoi_44201.xls
apachepoi_44235.xls
apachepoi_44297.xls
# apachepoi_44593.xls ## xlsb loop timeout
apachepoi_44593.xls ## xlsb loop timeout
apachepoi_44636.xls
apachepoi_44643.xls
apachepoi_44693.xls
@ -615,12 +615,12 @@ apachepoi_PercentPtg.xls
apachepoi_QuotientFunctionTestCaseData.xls
apachepoi_RangePtg.xls
apachepoi_ReadOnlyRecommended.xls
# apachepoi_ReferencePtg.xls ## xlsb loop timeout
apachepoi_ReferencePtg.xls ## xlsb loop timeout
apachepoi_RepeatingRowsCols.xls
apachepoi_ReptFunctionTestCaseData.xls
apachepoi_RomanFunctionTestCaseData.xls
apachepoi_SampleSS.xls
# apachepoi_SharedFormulaTest.xls ## xlsb loop timeout
apachepoi_SharedFormulaTest.xls ## xlsb loop timeout
apachepoi_SheetWithDrawing.xls
apachepoi_ShrinkToFit.xls
apachepoi_Simple.xls
@ -899,7 +899,7 @@ libreoffice_calc_xls-import_pivot-dup-data-fields.xls
libreoffice_calc_xls-import_pivot-layout-field-non-default.xls
libreoffice_calc_xls-import_row-attributes_row-all-hidden.xls
libreoffice_calc_xls-import_row-attributes_row-filtered.xls
# libreoffice_calc_xls-import_row-attributes_row-heights.xls ## xlsb loop timeout
libreoffice_calc_xls-import_row-attributes_row-heights.xls ## xlsb loop timeout
libreoffice_calc_xls-import_row-attributes_row-tail-hidden-2.xls
libreoffice_calc_xls-import_row-attributes_row-tail-hidden-last-row-visible.xls
libreoffice_calc_xls-import_row-attributes_row-tail-hidden.xls

View File

@ -6,7 +6,7 @@ var data = [
[1,2,3],
[true, false, null, "sheetjs"],
["foo","bar",new Date("2014-02-19T14:30Z"), "0.3"],
["baz", null, "qux"]
["baz", null, "qux", 3.14159]
];
var ws_name = "SheetJS";
@ -87,5 +87,5 @@ ws['!cols'] = wscols;
XLSX.writeFile(wb, 'sheetjs.xlsx');
XLSX.writeFile(wb, 'sheetjs.xlsm');
XLSX.writeFile(wb, 'sheetjs.xlsb');
//XLSX.writeFile(wb, 'sheetjs.xls');
XLSX.writeFile(wb, 'sheetjs.xls', {bookType:'biff2'});
XLSX.writeFile(wb, 'sheetjs.ods');

File diff suppressed because one or more lines are too long

5657
xlsx.js

File diff suppressed because one or more lines are too long