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:
parent
06670ae181
commit
ab2ecebac9
@ -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
|
||||
|
@ -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/
|
||||
|
@ -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"
|
||||
|
18
Makefile
18
Makefile
@ -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
|
||||
|
||||
|
54
README.md
54
README.md
@ -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:
|
||||
|
||||
|
23
bin/xlsx.njs
23
bin/xlsx.njs
@ -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");
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.8.2';
|
||||
XLSX.version = '0.8.3';
|
||||
|
@ -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; });
|
||||
}
|
||||
|
@ -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};
|
||||
*/
|
||||
|
@ -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*/);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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 = {
|
||||
'"': '"',
|
||||
@ -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',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|