forked from sheetjs/sheetjs
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);
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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');
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, {
|
||||
|
@ -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);
|
||||
|
@ -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>');
|
||||
|
@ -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 = [];
|
||||
|
174
bits/49_theme.js
174
bits/49_theme.js
File diff suppressed because one or more lines are too long
@ -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);
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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;
|
||||
|
163
bits/62_fxls.js
163
bits/62_fxls.js
@ -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 */
|
||||
|
1910
bits/64_ftab.js
1910
bits/64_ftab.js
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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) {
|
||||
|
@ -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)}));
|
@ -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
58
bits/74_xmlbin.js
Normal 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);
|
||||
}
|
||||
*/
|
@ -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("");
|
||||
}
|
@ -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
1249
bits/77_parsetab.js
Normal file
File diff suppressed because it is too large
Load Diff
118
bits/78_writebiff.js
Normal file
118
bits/78_writebiff.js
Normal 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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
*/
|
1230
bits/82_parsetab.js
1230
bits/82_parsetab.js
File diff suppressed because it is too large
Load Diff
@ -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];
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}}
|
||||
|
@ -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;
|
||||
|
@ -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
3
dist/ods.js
vendored
@ -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
2
dist/ods.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/ods.min.map
vendored
2
dist/ods.min.map
vendored
File diff suppressed because one or more lines are too long
20
dist/xlsx.core.min.js
vendored
20
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
29
dist/xlsx.full.min.js
vendored
29
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
5657
dist/xlsx.js
vendored
5657
dist/xlsx.js
vendored
File diff suppressed because one or more lines are too long
20
dist/xlsx.min.js
vendored
20
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
@ -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"
|
||||
]
|
||||
}
|
32
misc/flow.js
32
misc/flow.js
@ -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;
|
||||
*/
|
||||
|
@ -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;
|
||||
*/
|
||||
|
@ -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
3
ods.js
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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 = {};
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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
44
test.js
@ -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); });
|
||||
});
|
||||
|
12
tests.lst
12
tests.lst
@ -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
|
||||
|
@ -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');
|
||||
|
5944
xlsx.flow.js
5944
xlsx.flow.js
File diff suppressed because one or more lines are too long
5657
xlsx.js
5657
xlsx.js
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user