forked from sheetjs/sheetjs
version bump 0.10.0: cleanup
- updated SSF to 0.9.2 - XLSB style records and number format writing - CSV avoid parseFloat (fixes #646 h/t @jabbermarky) - CSV recognize mac line ending (fixes #648 h/t @charlesread) - BIFF2 format table refactored to align with SSF - BIFF5 image data exposure - SSF custom format auto table update (fixes #267 h/t @Fangmingdu) - eslint more checks - browser test timeout extended to 10 seconds
This commit is contained in:
parent
810c447bf9
commit
a8736580a5
@ -5,10 +5,12 @@
|
||||
"ecmaVersion": 3,
|
||||
},
|
||||
"plugins": [ "html", "json" ],
|
||||
"!extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"no-use-before-define": [ 1, {
|
||||
"functions":false, "classes":true, "variables":false
|
||||
}],
|
||||
"no-console": 0,
|
||||
"no-bitwise": 0,
|
||||
"curly": 0,
|
||||
"comma-style": [ 2, "last" ],
|
||||
|
110
README.md
110
README.md
@ -6,7 +6,8 @@ Emphasis on parsing and writing robustness, cross-format feature compatibility
|
||||
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
|
||||
|
||||
This is the community version. We also offer a pro version with performance
|
||||
enhancements and additional features by request.
|
||||
enhancements, additional features by request, and dedicated support.
|
||||
|
||||
|
||||
[**Pro Version**](http://sheetjs.com/pro)
|
||||
|
||||
@ -18,17 +19,33 @@ enhancements and additional features by request.
|
||||
|
||||
[**Source Code**](http://git.io/xlsx)
|
||||
|
||||
[**Issues and Bug Reports**](https://github.com/sheetjs/js-xlsx/issues)
|
||||
|
||||
[**Other General Support Issues**](https://discourse.sheetjs.com)
|
||||
|
||||
[**File format support for known spreadsheet data formats:**](#file-formats)
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
<details>
|
||||
<summary>Graph Legend</summary>
|
||||
<summary><b>Graph of supported formats</b> (click to show)</summary>
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
![graph legend](legend.png)
|
||||
|
||||
</details>
|
||||
|
||||
[**Browser Test**](http://oss.sheetjs.com/js-xlsx/tests/)
|
||||
|
||||
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
|
||||
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
|
||||
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
|
||||
[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<details>
|
||||
@ -40,6 +57,7 @@ enhancements and additional features by request.
|
||||
* [JS Ecosystem Demos](#js-ecosystem-demos)
|
||||
* [Optional Modules](#optional-modules)
|
||||
* [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
|
||||
- [Philosophy](#philosophy)
|
||||
- [Parsing Workbooks](#parsing-workbooks)
|
||||
* [Complete Examples](#complete-examples)
|
||||
* [Note on Streaming Read](#note-on-streaming-read)
|
||||
@ -114,7 +132,6 @@ enhancements and additional features by request.
|
||||
* [Windows](#windows)
|
||||
- [License](#license)
|
||||
- [References](#references)
|
||||
- [Badges](#badges)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
@ -122,18 +139,18 @@ enhancements and additional features by request.
|
||||
|
||||
## Installation
|
||||
|
||||
In the browser, just add a script tag:
|
||||
|
||||
```html
|
||||
<script lang="javascript" src="dist/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
With [npm](https://www.npmjs.org/package/xlsx):
|
||||
|
||||
```bash
|
||||
$ npm install xlsx
|
||||
```
|
||||
|
||||
In the browser:
|
||||
|
||||
```html
|
||||
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
|
||||
```
|
||||
|
||||
With [bower](http://bower.io/search/?q=js-xlsx):
|
||||
|
||||
```bash
|
||||
@ -194,6 +211,41 @@ To use the shim, add the shim before the script tag that loads xlsx.js:
|
||||
<script type="text/javascript" src="/path/to/shim.js"></script>
|
||||
```
|
||||
|
||||
## Philosophy
|
||||
|
||||
<details>
|
||||
<summary><b>Philosophy</b> (click to show)</summary>
|
||||
|
||||
Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
|
||||
Third-party libraries either supported one format, or they involved a separate
|
||||
set of classes for each supported file type. Even though XLSB was introduced in
|
||||
Excel 2007, nothing outside of SheetJS or Excel supported the format.
|
||||
|
||||
To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
|
||||
that we call the ["Common Spreadsheet Format"](#common-spreadsheet-format).
|
||||
Emphasizing a uniform object representation enables radical features like format
|
||||
conversion (e.g. reading an XLSX template and saving as XLS) and circumvents the
|
||||
"class trap". By abstracting the complexities of the various formats, tools
|
||||
need not worry about the specific file type!
|
||||
|
||||
A simple object representation combined with careful coding practices enables
|
||||
use cases in older browsers and in alternative environments like ExtendScript
|
||||
and Web Workers. It is always tempting to use the latest and greatest features,
|
||||
but they tend to require the latest versions of browsers, limiting usability.
|
||||
|
||||
Utility functions capture common use cases like generating JS objects or HTML.
|
||||
Most simple operations should only require a few lines of code. More complex
|
||||
operations generally should be straightforward to implement.
|
||||
|
||||
Excel pushes the XLSX format as default starting in Excel 2007. However, there
|
||||
are other formats with more appealing properties. For example, the XLSB format
|
||||
is spiritually similar to XLSX but files often tend up taking less than half the
|
||||
space and open much faster! Even though an XLSX writer is available, other
|
||||
format writers are available so users can take advantage of the unique
|
||||
characteristics of each format.
|
||||
|
||||
</details>
|
||||
|
||||
## Parsing Workbooks
|
||||
|
||||
For parsing, the first step is to read the file. This involves acquiring the
|
||||
@ -505,7 +557,6 @@ Utilities are available in the `XLSX.utils` object:
|
||||
**Exporting:**
|
||||
|
||||
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
|
||||
`sheet_to_row_object_array` is an alias that will be removed in the future.
|
||||
- `sheet_to_csv` generates delimiter-separated-values output.
|
||||
- `sheet_to_formulae` generates a list of the formulae (with value fallbacks).
|
||||
|
||||
@ -1008,17 +1059,14 @@ at index 164. The following example creates a custom format from scratch:
|
||||
|
||||
```js
|
||||
var tbl = {};
|
||||
XLSX.SSF.init_table(tbl); // <-- load builtin formats
|
||||
tbl[164] = "\"T\"\ #0.00";
|
||||
var wb = {
|
||||
SSF: tbl,
|
||||
SheetNames: ["Sheet1"],
|
||||
Sheets: {
|
||||
Sheet1: {
|
||||
"!ref":"A1:C1",
|
||||
A1: { t:"n", v:10000 }, // <-- General format
|
||||
B1: { t:"n", v:10000, z: tbl[4] }, // <-- Builtin format
|
||||
C1: { t:"n", v:10000, z: tbl[164] } // <-- Custom format
|
||||
A1: { t:"n", v:10000 }, // <-- General format
|
||||
B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format
|
||||
C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1439,8 +1487,8 @@ the output will be encoded in codepage `1200` and the BOM will be prepended.
|
||||
|
||||
### JSON
|
||||
|
||||
`XLSX.utils.sheet_to_json` and the alias `XLSX.utils.sheet_to_row_object_array`
|
||||
generate different types of JS objects. The function takes an options argument:
|
||||
`XLSX.utils.sheet_to_json` generates different types of JS objects. The function
|
||||
takes an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
@ -1834,6 +1882,9 @@ $ open -a Chromium.app http://localhost:8000/stress.html
|
||||
|
||||
### Tested Environments
|
||||
|
||||
<details>
|
||||
<summary>(click to show)</summary>
|
||||
|
||||
- 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 (IE6-9 browsers require shims for interacting with client)
|
||||
- Chrome 24+
|
||||
@ -1847,6 +1898,8 @@ Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
|
||||
- <https://travis-ci.org/SheetJS/SheetJS.github.io> for XLS\* modules
|
||||
- <https://saucelabs.com/u/sheetjs> for XLS\* modules using Sauce Labs
|
||||
|
||||
</details>
|
||||
|
||||
### Test Files
|
||||
|
||||
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
|
||||
@ -1980,20 +2033,3 @@ granted by the Apache 2.0 License are reserved by the Original Author.
|
||||
- Worksheet File Format (From Lotus) December 1984
|
||||
|
||||
|
||||
## Badges
|
||||
|
||||
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
|
||||
|
||||
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
|
||||
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
|
||||
|
||||
[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
|
||||
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
|
||||
|
||||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* eslint-env node */
|
||||
var n = "xlsx";
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
var X = require('../');
|
||||
@ -176,9 +177,9 @@ var oo = "";
|
||||
var strm = false;
|
||||
if(!program.quiet) console.error(target_sheet);
|
||||
if(program.formulae) oo = X.utils.get_formulae(ws).join("\n");
|
||||
else if(program.json) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws));
|
||||
else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws,{raw:true}));
|
||||
else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws,{raw:true, header:1}));
|
||||
else if(program.json) oo = JSON.stringify(X.utils.sheet_to_json(ws));
|
||||
else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true}));
|
||||
else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1}));
|
||||
else {
|
||||
strm = true;
|
||||
var stream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
|
||||
|
@ -3,5 +3,6 @@
|
||||
/*jshint -W041 */
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
/*exported XLSX */
|
||||
/*global exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.9.13';
|
||||
XLSX.version = '0.10.0';
|
||||
|
@ -1,8 +1,8 @@
|
||||
var current_codepage = 1200, current_cptable;
|
||||
var current_codepage = 1200;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js');
|
||||
current_cptable = cptable[current_codepage];
|
||||
}
|
||||
function reset_cp() { set_cp(1200); }
|
||||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
@ -18,7 +18,7 @@ var debom = function(data/*:string*/)/*:string*/ {
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
|
||||
set_cp = function(cp) { current_codepage = cp; };
|
||||
debom = function(data) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
|
@ -1,7 +1,7 @@
|
||||
var Base64 = (function make_b64(){
|
||||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
return {
|
||||
encode: function(input/*:string*/, utf8)/*:string*/ {
|
||||
encode: function(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3, e1, e2, e3, e4;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
@ -18,7 +18,7 @@ var Base64 = (function make_b64(){
|
||||
}
|
||||
return o;
|
||||
},
|
||||
decode: function b64_decode(input/*:string*/, utf8)/*:string*/ {
|
||||
decode: function b64_decode(input/*:string*/)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
|
@ -2,7 +2,7 @@
|
||||
/*jshint -W041 */
|
||||
var SSF = {};
|
||||
var make_ssf = function make_ssf(SSF){
|
||||
SSF.version = '0.9.1';
|
||||
SSF.version = '0.9.2';
|
||||
function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
|
||||
function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
@ -270,12 +270,14 @@ function write_num_exp(fmt/*:string*/, val/*:number*/)/*:string*/{
|
||||
var o/*:string*/;
|
||||
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
|
||||
if(fmt.match(/^#+0.0E\+0$/)) {
|
||||
if(val == 0) return "0.0E+0";
|
||||
else if(val < 0) return "-" + write_num_exp(fmt, -val);
|
||||
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
|
||||
var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
|
||||
var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
|
||||
if(ee < 0) ee += period;
|
||||
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
|
||||
if(o.indexOf("e") === -1) {
|
||||
var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
|
||||
var fakee = Math.floor(Math.log(val)*Math.LOG10E);
|
||||
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
else o += "E+" + (fakee - ee);
|
||||
while(o.substr(0,2) === "0.") {
|
||||
@ -353,7 +355,7 @@ function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/))) {
|
||||
return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
|
||||
}
|
||||
if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
|
||||
if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
|
||||
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val) + carry(val, r[1].length))) + "." + pad0(dec(val, r[1].length),r[1].length);
|
||||
}
|
||||
@ -401,7 +403,12 @@ function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(ri,r[1].length);
|
||||
}
|
||||
switch(fmt) {
|
||||
case "###,##0.00": return write_num_flt(type, "#,##0.00", val);
|
||||
case "###,###":
|
||||
case "##,###":
|
||||
case "#,###": var x = commaify(pad0r(aval,0)); return x !== "0" ? sign + x : "";
|
||||
case "###,###.00": return write_num_flt(type, "###,##0.00",val).replace(/^0\./,".");
|
||||
case "#,###.00": return write_num_flt(type, "#,##0.00",val).replace(/^0\./,".");
|
||||
default:
|
||||
}
|
||||
throw new Error("unsupported format |" + fmt + "|");
|
||||
@ -419,12 +426,14 @@ function write_num_exp2(fmt/*:string*/, val/*:number*/)/*:string*/{
|
||||
var o/*:string*/;
|
||||
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
|
||||
if(fmt.match(/^#+0.0E\+0$/)) {
|
||||
if(val == 0) return "0.0E+0";
|
||||
else if(val < 0) return "-" + write_num_exp2(fmt, -val);
|
||||
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
|
||||
var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period;
|
||||
var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
|
||||
if(ee < 0) ee += period;
|
||||
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
|
||||
if(!o.match(/[Ee]/)) {
|
||||
var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
|
||||
var fakee = Math.floor(Math.log(val)*Math.LOG10E);
|
||||
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
else o += "E+" + (fakee - ee);
|
||||
o = o.replace(/\+-/,"-");
|
||||
@ -446,7 +455,7 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
if(fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);
|
||||
if(fmt.charCodeAt(0) === 36) return "$"+write_num_int(type,fmt.substr(fmt.charAt(1)==' '?2:1),val);
|
||||
var o;
|
||||
var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
|
||||
var r/*:?Array<string>*/, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
|
||||
if(fmt.match(/^00+$/)) return sign + pad0(aval,fmt.length);
|
||||
if(fmt.match(/^[#?]+$/)) {
|
||||
o = (""+val); if(val === 0) o = "";
|
||||
@ -466,7 +475,7 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/))) {
|
||||
return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
|
||||
}
|
||||
if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify((""+aval));
|
||||
if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify((""+aval));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
|
||||
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length);
|
||||
}
|
||||
@ -482,12 +491,12 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
}
|
||||
var oa = "";
|
||||
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
|
||||
ri = Math.min(r[4].length,7);
|
||||
ri = Math.min(/*::String(*/r[4]/*::)*/.length,7);
|
||||
ff = frac(aval, Math.pow(10,ri)-1, false);
|
||||
o = "" + sign;
|
||||
oa = write_num("n", r[1], ff[1]);
|
||||
oa = write_num("n", /*::String(*/r[1]/*::)*/, ff[1]);
|
||||
if(oa.charAt(oa.length-1) == " ") oa = oa.substr(0,oa.length-1) + "0";
|
||||
o += oa + r[2] + "/" + r[3];
|
||||
o += oa + /*::String(*/r[2]/*::)*/ + "/" + /*::String(*/r[3]/*::)*/;
|
||||
oa = rpad_(ff[2],ri);
|
||||
if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
|
||||
o += oa;
|
||||
@ -513,8 +522,12 @@ function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string
|
||||
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(0,r[1].length);
|
||||
}
|
||||
switch(fmt) {
|
||||
case "###,###":
|
||||
case "##,###":
|
||||
case "#,###": var x = commaify(""+aval); return x !== "0" ? sign + x : "";
|
||||
default:
|
||||
if(fmt.slice(-3) == ".00") return write_num_int(type, fmt.slice(0,-3), val) + ".00";
|
||||
if(fmt.slice(-2) == ".0") return write_num_int(type, fmt.slice(0,-2), val) + ".0";
|
||||
}
|
||||
throw new Error("unsupported format |" + fmt + "|");
|
||||
}
|
||||
@ -610,7 +623,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
if(v < 0) return "";
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
o = c; while(++i<fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c;
|
||||
if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; /* m = minute */
|
||||
if(c === 'm' && lst.toLowerCase() === 'h') c = 'M';
|
||||
if(c === 'h') c = hr;
|
||||
out[out.length] = {t:c, v:o}; lst = c; break;
|
||||
case 'A':
|
||||
@ -628,6 +641,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
if(o.match(abstime)) {
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'Z', v:o.toLowerCase()};
|
||||
lst = o.charAt(1);
|
||||
} else if(o.indexOf("$") > -1) {
|
||||
o = (o.match(/\$([^-\[\]]*)/)||[])[1]||"$";
|
||||
if(!fmt_is_date(fmt)) out[out.length] = {t:'t',v:o};
|
||||
@ -641,7 +655,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
}
|
||||
/* falls through */
|
||||
case '0': case '#':
|
||||
o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1 || c=='\\' && fmt.charAt(i+1) == "-" && "0#".indexOf(fmt.charAt(i+2))>-1) o += c;
|
||||
o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1 || c=='\\' && fmt.charAt(i+1) == "-" && i < fmt.length - 2 && "0#".indexOf(fmt.charAt(i+2))>-1) o += c;
|
||||
out[out.length] = {t:'n', v:o}; break;
|
||||
case '?':
|
||||
o = c; while(fmt.charAt(++i) === c) o+=c;
|
||||
@ -705,7 +719,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
(c=out[jj].t) === "?" || c === "D" ||
|
||||
(c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/') ||
|
||||
out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') ||
|
||||
c === 't' && (out[jj].v === '/' || '$€'.indexOf(out[jj].v) > -1 || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
|
||||
c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
|
||||
)) {
|
||||
out[i].v += out[jj].v;
|
||||
out[jj] = {v:"", t:";"}; ++jj;
|
||||
@ -819,7 +833,6 @@ function choose_fmt(f/*:string*/, v) {
|
||||
}
|
||||
function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
|
||||
if(o == null) o = {};
|
||||
//fixopts(o != null ? o : (o=[]));
|
||||
var sfmt = "";
|
||||
switch(typeof fmt) {
|
||||
case "string":
|
||||
|
@ -53,6 +53,7 @@ function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ {
|
||||
|
||||
var _fs, jszip;
|
||||
/*:: declare var JSZip:any; */
|
||||
/*global JSZip:true */
|
||||
if(typeof JSZip !== 'undefined') jszip = JSZip;
|
||||
if (typeof exports !== 'undefined') {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
|
@ -37,7 +37,7 @@ var encodings = {
|
||||
'&': '&'
|
||||
};
|
||||
var rencoding = evert(encodings);
|
||||
var rencstr = "&<>'\"".split("");
|
||||
//var rencstr = "&<>'\"".split("");
|
||||
|
||||
// TODO: CP remap (need to read file version to determine OS)
|
||||
var unescapexml/*:StringConv*/ = (function() {
|
||||
|
@ -33,5 +33,6 @@ var make_offcrypto = function(O, _crypto) {
|
||||
};
|
||||
};
|
||||
/*:: declare var crypto:any; */
|
||||
/*global crypto:true */
|
||||
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);
|
||||
|
||||
|
@ -1,8 +1,31 @@
|
||||
function write_UInt32LE(x/*:number*/, o) {
|
||||
if(!o) o = new_buf(4);
|
||||
o.write_shift(4, x);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.168 */
|
||||
function parse_XLWideString(data)/*:string*/ {
|
||||
var cchCharacters = data.read_shift(4);
|
||||
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
|
||||
}
|
||||
function write_XLWideString(data/*:string*/, o) {
|
||||
var _null = false; if(o == null) { _null = true; o = new_buf(4+2*data.length); }
|
||||
o.write_shift(4, data.length);
|
||||
if(data.length > 0) o.write_shift(0, data, 'dbcs');
|
||||
return _null ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.143 */
|
||||
function parse_StrRun(data, length/*:?number*/) {
|
||||
return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
|
||||
}
|
||||
function write_StrRun(run, o) {
|
||||
if(!o) o = new_buf(4);
|
||||
o.write_shift(2, run.ich || 0);
|
||||
o.write_shift(2, run.ifnt || 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.121 */
|
||||
function parse_RichStr(data, length/*:number*/)/*:XLString*/ {
|
||||
@ -31,6 +54,17 @@ function write_RichStr(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
|
||||
write_XLWideString(str.t, o);
|
||||
return _null ? o.slice(0, o.l) : o;
|
||||
}
|
||||
/* [MS-XLSB] 2.4.325 BrtCommentText (RichStr w/1 run) */
|
||||
var parse_BrtCommentText = parse_RichStr;
|
||||
function write_BrtCommentText(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
|
||||
/* TODO: formatted string */
|
||||
var _null = false; if(o == null) { _null = true; o = new_buf(23+4*str.t.length); }
|
||||
o.write_shift(1,1);
|
||||
write_XLWideString(str.t, o);
|
||||
o.write_shift(4,1);
|
||||
write_StrRun({ich:0,ifnt:0}, o);
|
||||
return _null ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.9 */
|
||||
function parse_XLSBCell(data)/*:any*/ {
|
||||
@ -65,18 +99,6 @@ function write_XLNullableWideString(data/*:string*/, o) {
|
||||
return _null ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.168 */
|
||||
function parse_XLWideString(data)/*:string*/ {
|
||||
var cchCharacters = data.read_shift(4);
|
||||
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
|
||||
}
|
||||
function write_XLWideString(data/*:string*/, o) {
|
||||
var _null = false; if(o == null) { _null = true; o = new_buf(4+2*data.length); }
|
||||
o.write_shift(4, data.length);
|
||||
if(data.length > 0) o.write_shift(0, data, 'dbcs');
|
||||
return _null ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.165 */
|
||||
var parse_XLNameWideString = parse_XLWideString;
|
||||
var write_XLNameWideString = write_XLWideString;
|
||||
@ -153,23 +175,75 @@ var RBErr = evert_num(BErr);
|
||||
function parse_BrtColor(data, length/*:number*/) {
|
||||
var out = {};
|
||||
var d = data.read_shift(1);
|
||||
out.fValidRGB = d & 1;
|
||||
out.xColorType = d >>> 1;
|
||||
out.index = data.read_shift(1);
|
||||
out.nTintAndShade = data.read_shift(2, 'i');
|
||||
out.bRed = data.read_shift(1);
|
||||
out.bGreen = data.read_shift(1);
|
||||
out.bBlue = data.read_shift(1);
|
||||
out.bAlpha = data.read_shift(1);
|
||||
|
||||
var fValidRGB = d & 1;
|
||||
var xColorType = d >>> 1;
|
||||
|
||||
var index = data.read_shift(1);
|
||||
var nTS = data.read_shift(2, 'i');
|
||||
var bR = data.read_shift(1);
|
||||
var bG = data.read_shift(1);
|
||||
var bB = data.read_shift(1);
|
||||
var bAlpha = data.read_shift(1);
|
||||
|
||||
switch(xColorType) {
|
||||
case 0: out.auto = 1; break;
|
||||
case 1:
|
||||
out.index = index;
|
||||
var icv = XLSIcv[index];
|
||||
/* automatic pseudo index 81 */
|
||||
if(icv) out.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
|
||||
break;
|
||||
case 2:
|
||||
/* if(!fValidRGB) throw new Error("invalid"); */
|
||||
out.rgb = bR.toString(16) + bG.toString(16) + bB.toString(16);
|
||||
break;
|
||||
case 3: out.theme = index; break;
|
||||
}
|
||||
if(nTS != 0) out.tint = nTS > 0 ? nTS / 32767 : nTS / 32768;
|
||||
|
||||
return out;
|
||||
}
|
||||
function write_BrtColor(color, o) {
|
||||
if(!o) o = new_buf(8);
|
||||
if(!color||color.auto) { o.write_shift(4, 0); o.write_shift(4, 0); return o; }
|
||||
if(color.index) {
|
||||
o.write_shift(1, 0x02);
|
||||
o.write_shift(1, color.index);
|
||||
} else if(color.theme) {
|
||||
o.write_shift(1, 0x06);
|
||||
o.write_shift(1, color.theme);
|
||||
} else {
|
||||
o.write_shift(1, 0x05);
|
||||
o.write_shift(1, 0);
|
||||
}
|
||||
var nTS = color.tint || 0;
|
||||
if(nTS > 0) nTS *= 32767;
|
||||
else if(nTS < 0) nTS *= 32768;
|
||||
o.write_shift(2, nTS);
|
||||
if(!color.rgb) {
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(1, 0);
|
||||
} else {
|
||||
var rgb = (color.rgb || 'FFFFFF');
|
||||
o.write_shift(1, parseInt(rgb.substr(0,2),16));
|
||||
o.write_shift(1, parseInt(rgb.substr(2,2),16));
|
||||
o.write_shift(1, parseInt(rgb.substr(4,2),16));
|
||||
o.write_shift(1, 0xFF);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.52 */
|
||||
function parse_FontFlags(data, length/*:number*/) {
|
||||
function parse_FontFlags(data, length/*:number*/, opts) {
|
||||
var d = data.read_shift(1);
|
||||
data.l++;
|
||||
var out = {
|
||||
fItalic: d & 0x2,
|
||||
fStrikeout: d & 0x8,
|
||||
/* fBold: d & 0x01 */
|
||||
fItalic: d & 0x02,
|
||||
/* fUnderline: d & 0x04 */
|
||||
fStrikeout: d & 0x08,
|
||||
fOutline: d & 0x10,
|
||||
fShadow: d & 0x20,
|
||||
fCondense: d & 0x40,
|
||||
@ -177,3 +251,17 @@ function parse_FontFlags(data, length/*:number*/) {
|
||||
};
|
||||
return out;
|
||||
}
|
||||
function write_FontFlags(font, o) {
|
||||
if(!o) o = new_buf(2);
|
||||
var grbit =
|
||||
(font.italic ? 0x02 : 0) |
|
||||
(font.strike ? 0x08 : 0) |
|
||||
(font.outline ? 0x10 : 0) |
|
||||
(font.shadow ? 0x20 : 0) |
|
||||
(font.condense ? 0x40 : 0) |
|
||||
(font.extend ? 0x80 : 0);
|
||||
o.write_shift(1, grbit);
|
||||
o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -1,40 +1,40 @@
|
||||
/* [MS-OLEPS] 2.2 PropertyType */
|
||||
{
|
||||
var VT_EMPTY = 0x0000;
|
||||
var VT_NULL = 0x0001;
|
||||
//var VT_EMPTY = 0x0000;
|
||||
//var VT_NULL = 0x0001;
|
||||
var VT_I2 = 0x0002;
|
||||
var VT_I4 = 0x0003;
|
||||
var VT_R4 = 0x0004;
|
||||
var VT_R8 = 0x0005;
|
||||
var VT_CY = 0x0006;
|
||||
var VT_DATE = 0x0007;
|
||||
var VT_BSTR = 0x0008;
|
||||
var VT_ERROR = 0x000A;
|
||||
//var VT_R4 = 0x0004;
|
||||
//var VT_R8 = 0x0005;
|
||||
//var VT_CY = 0x0006;
|
||||
//var VT_DATE = 0x0007;
|
||||
//var VT_BSTR = 0x0008;
|
||||
//var VT_ERROR = 0x000A;
|
||||
var VT_BOOL = 0x000B;
|
||||
var VT_VARIANT = 0x000C;
|
||||
var VT_DECIMAL = 0x000E;
|
||||
var VT_I1 = 0x0010;
|
||||
var VT_UI1 = 0x0011;
|
||||
var VT_UI2 = 0x0012;
|
||||
//var VT_DECIMAL = 0x000E;
|
||||
//var VT_I1 = 0x0010;
|
||||
//var VT_UI1 = 0x0011;
|
||||
//var VT_UI2 = 0x0012;
|
||||
var VT_UI4 = 0x0013;
|
||||
var VT_I8 = 0x0014;
|
||||
//var VT_I8 = 0x0014;
|
||||
var VT_UI8 = 0x0015;
|
||||
var VT_INT = 0x0016;
|
||||
var VT_UINT = 0x0017;
|
||||
//var VT_INT = 0x0016;
|
||||
//var VT_UINT = 0x0017;
|
||||
var VT_LPSTR = 0x001E;
|
||||
var VT_LPWSTR = 0x001F;
|
||||
//var VT_LPWSTR = 0x001F;
|
||||
var VT_FILETIME = 0x0040;
|
||||
var VT_BLOB = 0x0041;
|
||||
var VT_STREAM = 0x0042;
|
||||
var VT_STORAGE = 0x0043;
|
||||
var VT_STREAMED_Object = 0x0044;
|
||||
var VT_STORED_Object = 0x0045;
|
||||
var VT_BLOB_Object = 0x0046;
|
||||
//var VT_BLOB = 0x0041;
|
||||
//var VT_STREAM = 0x0042;
|
||||
//var VT_STORAGE = 0x0043;
|
||||
//var VT_STREAMED_Object = 0x0044;
|
||||
//var VT_STORED_Object = 0x0045;
|
||||
//var VT_BLOB_Object = 0x0046;
|
||||
var VT_CF = 0x0047;
|
||||
var VT_CLSID = 0x0048;
|
||||
var VT_VERSIONED_STREAM = 0x0049;
|
||||
//var VT_CLSID = 0x0048;
|
||||
//var VT_VERSIONED_STREAM = 0x0049;
|
||||
var VT_VECTOR = 0x1000;
|
||||
var VT_ARRAY = 0x2000;
|
||||
//var VT_ARRAY = 0x2000;
|
||||
|
||||
var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
|
||||
var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
|
||||
@ -186,6 +186,7 @@ var XLSFillPattern = [
|
||||
function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
|
||||
|
||||
/* [MS-XLS] 2.5.161 */
|
||||
/* [MS-XLSB] 2.5.75 */
|
||||
var XLSIcv = rgbify([
|
||||
/* Color Constants */
|
||||
0x000000,
|
||||
@ -197,7 +198,7 @@ var XLSIcv = rgbify([
|
||||
0xFF00FF,
|
||||
0x00FFFF,
|
||||
|
||||
/* Defaults */
|
||||
/* Overridable Defaults */
|
||||
0x000000,
|
||||
0xFFFFFF,
|
||||
0xFF0000,
|
||||
@ -258,8 +259,24 @@ var XLSIcv = rgbify([
|
||||
0x333399,
|
||||
0x333333,
|
||||
|
||||
/* Sheet */
|
||||
0xFFFFFF,
|
||||
0x000000
|
||||
/* Other entries to appease BIFF8/12 */
|
||||
0xFFFFFF, /* 0x40 icvForeground ?? */
|
||||
0x000000, /* 0x41 icvBackground ?? */
|
||||
0x000000, /* 0x42 icvFrame ?? */
|
||||
0x000000, /* 0x43 icv3D ?? */
|
||||
0x000000, /* 0x44 icv3DText ?? */
|
||||
0x000000, /* 0x45 icv3DHilite ?? */
|
||||
0x000000, /* 0x46 icv3DShadow ?? */
|
||||
0x000000, /* 0x47 icvHilite ?? */
|
||||
0x000000, /* 0x48 icvCtlText ?? */
|
||||
0x000000, /* 0x49 icvCtlScrl ?? */
|
||||
0x000000, /* 0x4A icvCtlInv ?? */
|
||||
0x000000, /* 0x4B icvCtlBody ?? */
|
||||
0x000000, /* 0x4C icvCtlFrame ?? */
|
||||
0x000000, /* 0x4D icvCtlFore ?? */
|
||||
0x000000, /* 0x4E icvCtlBack ?? */
|
||||
0x000000, /* 0x4F icvCtlNeutral */
|
||||
0x000000, /* 0x50 icvInfoBk ?? */
|
||||
0x000000 /* 0x51 icvInfoText ?? */
|
||||
]);
|
||||
|
||||
|
@ -55,7 +55,7 @@ function write_rels(rels)/*:string*/ {
|
||||
function add_rels(rels, rId, f, type, relobj)/*:number*/ {
|
||||
if(!relobj) relobj = {};
|
||||
if(!rels['!id']) rels['!id'] = {};
|
||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){}
|
||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||
relobj.Id = 'rId' + rId;
|
||||
relobj.Type = type;
|
||||
relobj.Target = f;
|
||||
|
@ -39,7 +39,7 @@ function parse_cust_props(data/*:string*/, opts) {
|
||||
default:
|
||||
if(opts.WTF && typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
|
||||
}
|
||||
} else if(x.substr(0,2) === "</") {
|
||||
} else if(x.substr(0,2) === "</") {/* empty */
|
||||
} else if(opts.WTF) throw new Error(x);
|
||||
}
|
||||
}
|
||||
|
@ -174,28 +174,25 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
|
||||
case 0: PropH[piddsi.n] = 1252;
|
||||
/* falls through */
|
||||
case 10000: // OSX Roman
|
||||
case 1252: // Windows Latin
|
||||
|
||||
case 874: // SB Windows Thai
|
||||
case 1250: // SB Windows Central Europe
|
||||
case 1251: // SB Windows Cyrillic
|
||||
case 1253: // SB Windows Greek
|
||||
case 1254: // SB Windows Turkish
|
||||
case 1255: // SB Windows Hebrew
|
||||
case 1256: // SB Windows Arabic
|
||||
case 1257: // SB Windows Baltic
|
||||
case 1258: // SB Windows Vietnam
|
||||
|
||||
case 932: // DB Windows Japanese Shift-JIS
|
||||
case 936: // DB Windows Simplified Chinese GBK
|
||||
case 949: // DB Windows Korean
|
||||
case 950: // DB Windows Traditional Chinese Big5
|
||||
|
||||
case 1200: // UTF16LE
|
||||
case 1201: // UTF16BE
|
||||
case 65000: case -536: // UTF-7
|
||||
case 65001: case -535: // UTF-8
|
||||
case 874:
|
||||
case 932:
|
||||
case 936:
|
||||
case 949:
|
||||
case 950:
|
||||
case 1250:
|
||||
case 1251:
|
||||
case 1253:
|
||||
case 1254:
|
||||
case 1255:
|
||||
case 1256:
|
||||
case 1257:
|
||||
case 1258:
|
||||
case 10000:
|
||||
case 1200:
|
||||
case 1201:
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
@ -262,7 +259,7 @@ function parse_PropertySetStream(file, PIDSI) {
|
||||
if(NumSets === 1) return rval;
|
||||
if(blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
|
||||
var PSet1;
|
||||
try { PSet1 = parse_PropertySet(blob, null); } catch(e) { }
|
||||
try { PSet1 = parse_PropertySet(blob, null); } catch(e) {/* empty */}
|
||||
for(y in PSet1) rval[y] = PSet1[y];
|
||||
rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
|
||||
return rval;
|
||||
@ -363,7 +360,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
|
||||
var parse_ControlInfo = parsenoop;
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */
|
||||
var parse_URLMoniker = function(blob, length) {
|
||||
var parse_URLMoniker = function(blob/*, length, opts*/) {
|
||||
var len = blob.read_shift(4), start = blob.l;
|
||||
var extra = false;
|
||||
if(len > 24) {
|
||||
|
@ -21,7 +21,7 @@ function parse_frtHeader(blob) {
|
||||
function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); }
|
||||
|
||||
/* 2.5.158 */
|
||||
var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL'];
|
||||
//var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL'];
|
||||
var parse_HideObjEnum = parseuint16;
|
||||
|
||||
/* 2.5.344 */
|
||||
@ -99,35 +99,39 @@ function parse_FtCf(blob, length) {
|
||||
}
|
||||
|
||||
/* 2.5.140 - 2.5.154 and friends */
|
||||
function parse_FtSkip(blob, length) { blob.l += 2; blob.l += blob.read_shift(2); }
|
||||
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 */
|
||||
/*::[*/0x00/*::]*/: parse_FtSkip, /* FtEnd */
|
||||
/*::[*/0x04/*::]*/: parse_FtSkip, /* FtMacro */
|
||||
/*::[*/0x05/*::]*/: parse_FtSkip, /* FtButton */
|
||||
/*::[*/0x06/*::]*/: parse_FtSkip, /* FtGmo */
|
||||
/*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
|
||||
/*::[*/0x08/*::]*/: parse_FtSkip, /* FtPioGrbit */
|
||||
/*::[*/0x09/*::]*/: parse_FtSkip, /* FtPictFmla */
|
||||
/*::[*/0x0A/*::]*/: parse_FtSkip, /* FtCbls */
|
||||
/*::[*/0x0B/*::]*/: parse_FtSkip, /* FtRbo */
|
||||
/*::[*/0x0C/*::]*/: parse_FtSkip, /* FtSbs */
|
||||
/*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
|
||||
/*::[*/0x0E/*::]*/: parse_FtSkip, /* FtSbsFmla */
|
||||
/*::[*/0x0F/*::]*/: parse_FtSkip, /* FtGboData */
|
||||
/*::[*/0x10/*::]*/: parse_FtSkip, /* FtEdoData */
|
||||
/*::[*/0x11/*::]*/: parse_FtSkip, /* FtRboData */
|
||||
/*::[*/0x12/*::]*/: parse_FtSkip, /* FtCblsData */
|
||||
/*::[*/0x13/*::]*/: parse_FtSkip, /* FtLbsData */
|
||||
/*::[*/0x14/*::]*/: parse_FtSkip, /* FtCblsFmla */
|
||||
/*::[*/0x15/*::]*/: parse_FtCmo
|
||||
};
|
||||
function parse_FtArray(blob, length, ot) {
|
||||
var s = blob.l;
|
||||
var tgt = blob.l + length;
|
||||
var fts = [];
|
||||
while(blob.l < s + length) {
|
||||
while(blob.l < tgt) {
|
||||
var ft = blob.read_shift(2);
|
||||
blob.l-=2;
|
||||
try {
|
||||
fts.push(FtTab[ft](blob, s + length - blob.l));
|
||||
} catch(e) { blob.l = s + length; return fts; }
|
||||
fts.push(FtTab[ft](blob, tgt - blob.l));
|
||||
} catch(e) { blob.l = tgt; return fts; }
|
||||
}
|
||||
if(blob.l != s + length) blob.l = s + length; //throw new Error("bad Object Ft-sequence");
|
||||
if(blob.l != tgt) blob.l = tgt; //throw new Error("bad Object Ft-sequence");
|
||||
return fts;
|
||||
}
|
||||
|
||||
@ -158,7 +162,7 @@ function parse_BOF(blob, length) {
|
||||
function parse_InterfaceHdr(blob, length) {
|
||||
if(length === 0) return 0x04b0;
|
||||
var q;
|
||||
if((q=blob.read_shift(2))!==0x04b0){}
|
||||
if((q=blob.read_shift(2))!==0x04b0){/* empty */}
|
||||
return 0x04b0;
|
||||
}
|
||||
|
||||
@ -246,11 +250,16 @@ function parse_RecalcId(blob, length) {
|
||||
}
|
||||
|
||||
/* 2.4.87 */
|
||||
function parse_DefaultRowHeight(blob, length) {
|
||||
var f = blob.read_shift(2);
|
||||
var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
|
||||
/* char is misleading, miyRw and miyRwHidden overlap */
|
||||
function parse_DefaultRowHeight(blob, length, opts) {
|
||||
var f = 0;
|
||||
if(!(opts && opts.biff == 2)) {
|
||||
f = blob.read_shift(2);
|
||||
}
|
||||
var miyRw = blob.read_shift(2);
|
||||
if((opts && opts.biff == 2)) {
|
||||
f = 1 - (miyRw >> 15); miyRw &= 0x7fff;
|
||||
}
|
||||
var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
|
||||
return [fl, miyRw];
|
||||
}
|
||||
|
||||
@ -265,9 +274,17 @@ function parse_Window1(blob, length) {
|
||||
|
||||
/* 2.4.122 TODO */
|
||||
function parse_Font(blob, length, opts) {
|
||||
blob.l += 14;
|
||||
var name = parse_ShortXLUnicodeString(blob, 0, opts);
|
||||
return name;
|
||||
var o = {
|
||||
dyHeight: blob.read_shift(2),
|
||||
fl: blob.read_shift(2)
|
||||
};
|
||||
switch(opts && opts.biff || 8) {
|
||||
case 2: break;
|
||||
case 3: case 4: blob.l += 2; break;
|
||||
default: blob.l += 10; break;
|
||||
}
|
||||
o.name = parse_ShortXLUnicodeString(blob, 0, opts);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.149 */
|
||||
@ -299,8 +316,8 @@ var parse_BIFF2Format = parse_XLUnicodeString2;
|
||||
function parse_Dimensions(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var w = opts.biff == 8 || !opts.biff ? 4 : 2;
|
||||
var r = blob.read_shift(w), R = blob.read_shift(w),
|
||||
c = blob.read_shift(2), C = blob.read_shift(2);
|
||||
var r = blob.read_shift(w), R = blob.read_shift(w);
|
||||
var c = blob.read_shift(2), C = blob.read_shift(2);
|
||||
blob.l = end;
|
||||
return {s: {r:r, c:c}, e: {r:R, c:C}};
|
||||
}
|
||||
@ -549,11 +566,49 @@ function parse_MergeCells(blob, length) {
|
||||
}
|
||||
|
||||
/* 2.4.181 TODO: parse all the things! */
|
||||
function parse_Obj(blob, length) {
|
||||
function parse_Obj(blob, length, opts) {
|
||||
if(opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts);
|
||||
var cmo = parse_FtCmo(blob, 22); // id, ot, flags
|
||||
var fts = parse_FtArray(blob, length-22, cmo[1]);
|
||||
return { cmo: cmo, ft:fts };
|
||||
}
|
||||
/* from older spec */
|
||||
var parse_BIFF5OT = [];
|
||||
parse_BIFF5OT[0x08] = function(blob, length, opts) {
|
||||
var tgt = blob.l + length;
|
||||
blob.l += 10; // todo
|
||||
var cf = blob.read_shift(2);
|
||||
blob.l += 4;
|
||||
var cbPictFmla = blob.read_shift(2);
|
||||
blob.l += 2;
|
||||
var grbit = blob.read_shift(2);
|
||||
blob.l += 4;
|
||||
var cchName = blob.read_shift(1);
|
||||
blob.l += cchName; // TODO: stName
|
||||
blob.l = tgt; // TODO: fmla
|
||||
return { fmt:cf };
|
||||
};
|
||||
|
||||
function parse_BIFF5Obj(blob, length, opts) {
|
||||
var cnt = blob.read_shift(4);
|
||||
var ot = blob.read_shift(2);
|
||||
var id = blob.read_shift(2);
|
||||
var grbit = blob.read_shift(2);
|
||||
var colL = blob.read_shift(2);
|
||||
var dxL = blob.read_shift(2);
|
||||
var rwT = blob.read_shift(2);
|
||||
var dyT = blob.read_shift(2);
|
||||
var colR = blob.read_shift(2);
|
||||
var dxR = blob.read_shift(2);
|
||||
var rwB = blob.read_shift(2);
|
||||
var dyB = blob.read_shift(2);
|
||||
var cbMacro = blob.read_shift(2);
|
||||
blob.l += 6;
|
||||
length -= 36;
|
||||
var fts = [];
|
||||
fts.push((parse_BIFF5OT[ot]||parsenoop)(blob, length, opts));
|
||||
return { cmo: [id, ot, grbit], ft:fts };
|
||||
}
|
||||
|
||||
/* 2.4.329 TODO: parse properly */
|
||||
function parse_TxO(blob, length, opts) {
|
||||
@ -684,7 +739,6 @@ var parse_StyleExt = parsenoop;
|
||||
|
||||
var parse_Window2 = parsenoop;
|
||||
|
||||
|
||||
var parse_Backup = parsebool; /* 2.4.14 */
|
||||
var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */
|
||||
var parse_BottomMargin = parse_Xnum; /* 2.4.27 */
|
||||
@ -991,6 +1045,16 @@ var parse_BopPopCustom = parsenoop;
|
||||
var parse_Fbi2 = parsenoop;
|
||||
|
||||
/* --- Specific to versions before BIFF8 --- */
|
||||
function parse_ImData(blob, length, opts) {
|
||||
var tgt = blob.l + length;
|
||||
var cf = blob.read_shift(2);
|
||||
var env = blob.read_shift(2);
|
||||
var lcb = blob.read_shift(4);
|
||||
var o = {fmt:cf, env:env, len:lcb, data:blob.slice(blob.l,blob.l+lcb)};
|
||||
blob.l += lcb;
|
||||
return o;
|
||||
}
|
||||
|
||||
function parse_BIFF5String(blob) {
|
||||
var len = blob.read_shift(1);
|
||||
return blob.read_shift(len, 'sbcs-cont');
|
||||
@ -1037,7 +1101,7 @@ function parse_BIFF2FONTXTRA(blob, length) {
|
||||
blob.l += 1; // charset
|
||||
blob.l += 3; // unknown
|
||||
blob.l += 1; // font family
|
||||
blob.l += length - 9;
|
||||
blob.l += length - 13;
|
||||
}
|
||||
|
||||
/* TODO: parse rich text runs */
|
||||
|
@ -210,17 +210,23 @@ var SYLK = (function() {
|
||||
var Mval = 0, j;
|
||||
for (; ri !== records.length; ++ri) {
|
||||
Mval = 0;
|
||||
var record = records[ri].trim().split(";");
|
||||
var RT = record[0], val;
|
||||
switch(RT) {
|
||||
case 'P': if(record[1].charAt(0) == 'P') formats.push(records[ri].trim().substr(3).replace(/;;/g, ";"));
|
||||
var rstr=records[ri].trim(), record=rstr.split(";"), RT=record[0], val;
|
||||
if(rstr.length > 0) switch(RT) {
|
||||
case 'ID': break; /* header */
|
||||
case 'E': break; /* EOF */
|
||||
case 'B': break; /* dimensions */
|
||||
case 'O': break; /* options? */
|
||||
case 'P':
|
||||
if(record[1].charAt(0) == 'P')
|
||||
formats.push(rstr.substr(3).replace(/;;/g, ";"));
|
||||
break;
|
||||
case 'C': case 'F': for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
case 'C':
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
case 'X': C = parseInt(record[rj].substr(1))-1; break;
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; C = 0;
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
break;
|
||||
case 'X': C = parseInt(record[rj].substr(1))-1; break;
|
||||
case 'K':
|
||||
val = record[rj].substr(1);
|
||||
if(val.charAt(0) === '"') val = val.substr(1,val.length - 2);
|
||||
@ -233,13 +239,27 @@ var SYLK = (function() {
|
||||
arr[R][C] = val;
|
||||
next_cell_format = null;
|
||||
break;
|
||||
case 'P':
|
||||
if(RT !== 'F') break;
|
||||
next_cell_format = formats[parseInt(record[rj].substr(1))];
|
||||
case 'E':
|
||||
/* formula = record[rj].substr(1); */
|
||||
break; /* TODO: formula */
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
} break;
|
||||
case 'F':
|
||||
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
|
||||
case 'X': C = parseInt(record[rj].substr(1))-1; break;
|
||||
case 'Y':
|
||||
R = parseInt(record[rj].substr(1))-1; C = 0;
|
||||
for(j = arr.length; j <= R; ++j) arr[j] = [];
|
||||
break;
|
||||
case 'M': Mval = parseInt(record[rj].substr(1)) / 20; break;
|
||||
case 'F': break; /* ??? */
|
||||
case 'P':
|
||||
next_cell_format = formats[parseInt(record[rj].substr(1))];
|
||||
break;
|
||||
case 'S': break; /* cell style */
|
||||
case 'D': break; /* column */
|
||||
case 'N': break; /* font */
|
||||
case 'W':
|
||||
if(RT !== 'F') break;
|
||||
cw = record[rj].substr(1).split(" ");
|
||||
for(j = parseInt(cw[0], 10); j <= parseInt(cw[1], 10); ++j) {
|
||||
Mval = parseInt(cw[2], 10);
|
||||
@ -250,8 +270,10 @@ var SYLK = (function() {
|
||||
rowinfo[R] = {};
|
||||
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
|
||||
else if(Mval == 0) rowinfo[R].hidden = true;
|
||||
break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
} break;
|
||||
default: break;
|
||||
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
|
||||
}
|
||||
}
|
||||
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
|
||||
@ -297,7 +319,7 @@ var SYLK = (function() {
|
||||
});
|
||||
}
|
||||
|
||||
function write_ws_rows_sylk(out, rows) {
|
||||
function write_ws_rows_sylk(out/*:Array<string>*/, rows/*:Array<RowInfo>*/) {
|
||||
rows.forEach(function(row, i) {
|
||||
var rec = "F;";
|
||||
if(row.hidden) rec += "M0;";
|
||||
@ -318,6 +340,7 @@ var SYLK = (function() {
|
||||
if(ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
|
||||
if(ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
|
||||
|
||||
preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
for(var C = r.s.c; C <= r.e.c; ++C) {
|
||||
var coord = encode_cell({r:R,c:C});
|
||||
@ -447,7 +470,7 @@ var PRN = (function() {
|
||||
function set_text_arr(data/*:string*/, arr/*:AOA*/, R/*:number*/, C/*:number*/) {
|
||||
if(data === 'TRUE') arr[R][C] = true;
|
||||
else if(data === 'FALSE') arr[R][C] = false;
|
||||
else if(data === ""){}
|
||||
else if(data === ""){/* empty */}
|
||||
else if(+data == +data) arr[R][C] = +data;
|
||||
else arr[R][C] = data;
|
||||
}
|
||||
@ -485,29 +508,36 @@ var PRN = (function() {
|
||||
|
||||
/* known sep */
|
||||
if(str.substr(0,4) == "sep=" && str.charCodeAt(5) == 10) { sep = str.charAt(4); str = str.substr(6); }
|
||||
/* TODO: actually determine the separator */
|
||||
if(str.substr(0,1024).indexOf("\t") == -1) sep = ","; else sep = "\t";
|
||||
else if(str.substr(0,1024).indexOf("\t") == -1) sep = ","; else sep = "\t";
|
||||
var R = 0, C = 0, v = 0;
|
||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0;
|
||||
str = str.replace(/\r\n/g, "\n");
|
||||
for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: instr = !instr; break;
|
||||
case sepcc: case 0x0a: if(instr) break;
|
||||
str = str.replace(/\r\n/mg, "\n");
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var cell = ({}/*:any*/);
|
||||
if(s.charCodeAt(0) == 0x3D) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
|
||||
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
|
||||
else if(!isNaN(v = parseFloat(s))) { cell.t = 'n'; cell.w = s; cell.v = v; }
|
||||
else { cell.t = 's'; cell.v = s.replace(/^"/,"").replace(/"$/,"").replace(/""/g,'"'); }
|
||||
else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; }
|
||||
else if(!isNaN(new Date(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); }
|
||||
else {
|
||||
cell.t = 's';
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
cell.v = s;
|
||||
}
|
||||
if(o.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = cell; }
|
||||
else ws[encode_cell({c:C,r:R})] = cell;
|
||||
start = end+1;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(cc == sepcc) ++C; else { C = 0; ++R; } break;
|
||||
if(cc == sepcc) ++C; else { C = 0; ++R; }
|
||||
}
|
||||
for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: if(instr || (end - start == 0)) instr = !instr; break;
|
||||
case sepcc: case 0x0a: case 0x0d: if(!instr) finish_cell(); break;
|
||||
default: break;
|
||||
}
|
||||
if(end - start > 0) finish_cell();
|
||||
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
|
@ -22,8 +22,8 @@ function parse_sst_bin(data, opts)/*:SST*/ {
|
||||
pass = false; break;
|
||||
|
||||
default:
|
||||
if(R_n.indexOf("Begin") > 0){}
|
||||
else if(R_n.indexOf("End") > 0){}
|
||||
if(R_n.indexOf("Begin") > 0){/* empty */}
|
||||
else if(R_n.indexOf("End") > 0){/* empty */}
|
||||
if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
});
|
||||
|
@ -138,30 +138,47 @@ function parse_fonts(t, styles, themes, opts) {
|
||||
case '<name': if(y.val) font.name = y.val; break;
|
||||
case '<name/>': case '</name>': break;
|
||||
|
||||
/* 18.8.2 b CT_BooleanProperty */
|
||||
case '<b': break; // TODO: read val (0 = off)
|
||||
case '<b/>': font.bold = true; break;
|
||||
/* 18.8.2 b CT_BooleanProperty */
|
||||
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<b/>': font.bold = 1; break;
|
||||
|
||||
/* 18.8.26 i CT_BooleanProperty */
|
||||
case '<i': break; // TODO: read val (0 = off)
|
||||
case '<i/>': font.italic = true; break;
|
||||
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<i/>': font.italic = 1; break;
|
||||
|
||||
/* 18.4.13 u CT_UnderlineProperty */
|
||||
case '<u': font.underline = true; break; // TODO: double underline
|
||||
case '<u/>': font.underline = true; break;
|
||||
case '<u':
|
||||
switch(y.val) {
|
||||
case "none": font.underline = 0x00; break;
|
||||
case "single": font.underline = 0x01; break;
|
||||
case "double": font.underline = 0x02; break;
|
||||
case "singleAccounting": font.underline = 0x21; break;
|
||||
case "doubleAccounting": font.underline = 0x22; break;
|
||||
} break;
|
||||
case '<u/>': font.underline = 1; break;
|
||||
|
||||
/* 18.4.10 strike CT_BooleanProperty */
|
||||
case '<strike': break; // TODO: read val (0 = off)
|
||||
case '<strike/>': font.strike = true; break;
|
||||
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<strike/>': font.strike = 1; break;
|
||||
|
||||
/* 18.4.2 outline CT_BooleanProperty */
|
||||
case '<outline/>': font.outline = true; break;
|
||||
/* 18.4.2 outline CT_BooleanProperty */
|
||||
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<outline/>': font.outline = 1; break;
|
||||
|
||||
/* 18.8.36 shadow CT_BooleanProperty */
|
||||
case '<shadow/>': font.shadow = true; break;
|
||||
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<shadow/>': font.shadow = 1; break;
|
||||
|
||||
/* 18.8.12 condense CT_BooleanProperty */
|
||||
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<condense/>': font.condense = 1; break;
|
||||
|
||||
/* 18.8.17 extend CT_BooleanProperty */
|
||||
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
|
||||
case '<extend/>': font.extend = 1; break;
|
||||
|
||||
/* 18.4.11 sz CT_FontSize */
|
||||
case '<sz': if(y.val) font.sz = y.val; break;
|
||||
case '<sz': if(y.val) font.sz = +y.val; break;
|
||||
case '<sz/>': case '</sz>': break;
|
||||
|
||||
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
|
||||
@ -169,28 +186,39 @@ function parse_fonts(t, styles, themes, opts) {
|
||||
case '<vertAlign/>': case '</vertAlign>': break;
|
||||
|
||||
/* 18.8.18 family CT_FontFamily */
|
||||
case '<family': if(y.val) font.family = y.val; break;
|
||||
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
|
||||
case '<family/>': case '</family>': break;
|
||||
|
||||
/* 18.8.35 scheme CT_FontScheme */
|
||||
case '<scheme': if(y.val) font.scheme = y.val; break;
|
||||
case '<scheme/>': case '</scheme>': break;
|
||||
|
||||
/* 18.4.1 charset CT_IntProperty TODO */
|
||||
/* 18.4.1 charset CT_IntProperty */
|
||||
case '<charset':
|
||||
if(y.val == '1') break;
|
||||
y.codepage = CS2CP[parseInt(y.val, 10)];
|
||||
break;
|
||||
|
||||
/* 18.?.? color CT_Color TODO */
|
||||
/* 18.?.? color CT_Color */
|
||||
case '<color':
|
||||
if(!font.color) font.color = {};
|
||||
if(y.theme) font.color.theme = y.theme;
|
||||
if(y.tint) font.color.tint = y.tint;
|
||||
if(y.theme && themes.themeElements && themes.themeElements.clrScheme) {
|
||||
font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
|
||||
}
|
||||
if(y.auto) font.color.auto = parsexmlbool(y.auto);
|
||||
|
||||
if(y.rgb) font.color.rgb = y.rgb;
|
||||
else if(y.indexed) {
|
||||
font.color.index = parseInt(y.indexed, 10);
|
||||
var icv = XLSIcv[font.color.index];
|
||||
if(font.color.index == 81) icv = XLSIcv[1];
|
||||
if(!icv) throw new Error(x);
|
||||
font.color.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
|
||||
} else if(y.theme) {
|
||||
font.color.theme = parseInt(y.theme, 10);
|
||||
if(y.tint) font.color.tint = parseFloat(y.tint);
|
||||
if(y.theme && themes.themeElements && themes.themeElements.clrScheme) {
|
||||
font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case '<color/>': case '</color>': break;
|
||||
|
||||
@ -302,17 +330,18 @@ return function parse_sty_xml(data, themes, opts) {
|
||||
/* 18.8.23 fonts CT_Fonts ? */
|
||||
if((t=data.match(fontsRegex))) parse_fonts(t, styles, themes, opts);
|
||||
|
||||
/* 18.8.21 fills CT_Fills */
|
||||
/* 18.8.21 fills CT_Fills ? */
|
||||
if((t=data.match(fillsRegex))) parse_fills(t, styles, themes, opts);
|
||||
|
||||
/* 18.8.5 borders CT_Borders ? */
|
||||
/* 18.8.5 borders CT_Borders ? */
|
||||
if((t=data.match(bordersRegex))) parse_borders(t, styles, themes, opts);
|
||||
|
||||
/* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
|
||||
/* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs ? */
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
|
||||
|
||||
/* 18.8.8 cellStyles CT_CellStyles ? */
|
||||
/* 18.8.15 dxfs CT_Dxfs ? */
|
||||
/* 18.8.42 tableStyles CT_TableStyles ? */
|
||||
/* 18.8.11 colors CT_Colors ? */
|
||||
|
@ -4,33 +4,132 @@ function parse_BrtFmt(data, length/*:number*/) {
|
||||
var stFmtCode = parse_XLWideString(data,length-2);
|
||||
return [ifmt, stFmtCode];
|
||||
}
|
||||
function write_BrtFmt(i/*:number*/, f/*:string*/, o) {
|
||||
if(!o) o = new_buf(6 + 4 * f.length);
|
||||
o.write_shift(2, i);
|
||||
write_XLWideString(f, o);
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.653 BrtFont TODO */
|
||||
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);
|
||||
out.sss = data.read_shift(2);
|
||||
out.uls = data.read_shift(1);
|
||||
out.bFamily = data.read_shift(1);
|
||||
out.bCharSet = data.read_shift(1);
|
||||
function parse_BrtFont(data, length/*:number*/, opts) {
|
||||
var out = ({}/*:any*/);
|
||||
|
||||
out.sz = data.read_shift(2) / 20;
|
||||
|
||||
var grbit = parse_FontFlags(data, 2, opts);
|
||||
if(grbit.fCondense) out.condense = 1;
|
||||
if(grbit.fExtend) out.extend = 1;
|
||||
if(grbit.fShadow) out.shadow = 1;
|
||||
if(grbit.fOutline) out.outline = 1;
|
||||
if(grbit.fStrikeout) out.strike = 1;
|
||||
if(grbit.fItalic) out.italic = 1;
|
||||
|
||||
var bls = data.read_shift(2);
|
||||
if(bls === 0x02BC) out.bold = 1;
|
||||
|
||||
switch(data.read_shift(2)) {
|
||||
/* case 0: out.vertAlign = "baseline"; break; */
|
||||
case 1: out.vertAlign = "superscript"; break;
|
||||
case 2: out.vertAlign = "subscript"; break;
|
||||
}
|
||||
|
||||
var underline = data.read_shift(1);
|
||||
if(underline != 0) out.underline = underline;
|
||||
|
||||
var family = data.read_shift(1);
|
||||
if(family > 0) out.family = family;
|
||||
|
||||
var bCharSet = data.read_shift(1);
|
||||
if(bCharSet > 0) out.charset = bCharSet;
|
||||
|
||||
data.l++;
|
||||
out.brtColor = parse_BrtColor(data, 8);
|
||||
out.bFontScheme = data.read_shift(1);
|
||||
out.color = parse_BrtColor(data, 8);
|
||||
|
||||
switch(data.read_shift(1)) {
|
||||
/* case 0: out.scheme = "none": break; */
|
||||
case 1: out.scheme = "major"; break;
|
||||
case 2: out.scheme = "minor"; break;
|
||||
}
|
||||
|
||||
out.name = parse_XLWideString(data, length - 21);
|
||||
|
||||
out.flags.Bold = out.bls === 0x02BC;
|
||||
out.flags.Italic = out.grbit.fItalic;
|
||||
out.flags.Strikeout = out.grbit.fStrikeout;
|
||||
out.flags.Outline = out.grbit.fOutline;
|
||||
out.flags.Shadow = out.grbit.fShadow;
|
||||
out.flags.Condense = out.grbit.fCondense;
|
||||
out.flags.Extend = out.grbit.fExtend;
|
||||
out.flags.Sub = out.sss & 0x2;
|
||||
out.flags.Sup = out.sss & 0x1;
|
||||
return out;
|
||||
}
|
||||
function write_BrtFont(font, o) {
|
||||
if(!o) o = new_buf(25+4*32);
|
||||
o.write_shift(2, font.sz * 20);
|
||||
write_FontFlags(font, o);
|
||||
o.write_shift(2, font.bold ? 0x02BC : 0x0190);
|
||||
var sss = 0;
|
||||
if(font.vertAlign == "superscript") sss = 1;
|
||||
else if(font.vertAlign == "subscript") sss = 2;
|
||||
o.write_shift(2, sss);
|
||||
o.write_shift(1, font.underline || 0);
|
||||
o.write_shift(1, font.family || 0);
|
||||
o.write_shift(1, font.charset || 0);
|
||||
o.write_shift(1, 0);
|
||||
write_BrtColor(font.color, o);
|
||||
var scheme = 0;
|
||||
if(font.scheme == "major") scheme = 1;
|
||||
if(font.scheme == "minor") scheme = 2;
|
||||
o.write_shift(1, scheme);
|
||||
write_XLWideString(font.name, o);
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.644 BrtFill */
|
||||
var XLSBFillPTNames = [
|
||||
"none",
|
||||
"solid",
|
||||
"mediumGray",
|
||||
"darkGray",
|
||||
"lightGray",
|
||||
"darkHorizontal",
|
||||
"darkVertical",
|
||||
"darkDown",
|
||||
"darkUp",
|
||||
"darkGrid",
|
||||
"darkTrellis",
|
||||
"lightHorizontal",
|
||||
"lightVertical",
|
||||
"lightDown",
|
||||
"lightUp",
|
||||
"lightGrid",
|
||||
"lightTrellis",
|
||||
"gray125",
|
||||
"gray0625"
|
||||
];
|
||||
var rev_XLSBFillPTNames = evert(XLSBFillPTNames);
|
||||
/* TODO: gradient fill representation */
|
||||
function write_BrtFill(fill, o) {
|
||||
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
|
||||
var fls = rev_XLSBFillPTNames[fill.patternType];
|
||||
if(fls == null) fls = 0x28;
|
||||
o.write_shift(4, fls);
|
||||
var j = 0;
|
||||
if(fls != 0x28) {
|
||||
/* TODO: custom FG Color */
|
||||
write_BrtColor({auto:1}, o);
|
||||
/* TODO: custom BG Color */
|
||||
write_BrtColor({auto:1}, o);
|
||||
|
||||
for(; j < 12; ++j) o.write_shift(4, 0);
|
||||
} else {
|
||||
for(; j < 4; ++j) o.write_shift(4, 0);
|
||||
|
||||
for(; j < 12; ++j) o.write_shift(4, 0); /* TODO */
|
||||
/* iGradientType */
|
||||
/* xnumDegree */
|
||||
/* xnumFillToLeft */
|
||||
/* xnumFillToRight */
|
||||
/* xnumFillToTop */
|
||||
/* xnumFillToBottom */
|
||||
/* cNumStop */
|
||||
/* xfillGradientStop */
|
||||
}
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.816 BrtXF */
|
||||
function parse_BrtXF(data, length/*:number*/) {
|
||||
@ -39,6 +138,62 @@ function parse_BrtXF(data, length/*:number*/) {
|
||||
parsenoop(data, length-4);
|
||||
return {ixfe:ixfeParent, ifmt:ifmt };
|
||||
}
|
||||
function write_BrtXF(data, ixfeP, o) {
|
||||
if(!o) o = new_buf(16);
|
||||
o.write_shift(2, ixfeP||0);
|
||||
o.write_shift(2, data.numFmtId||0);
|
||||
o.write_shift(2, 0); /* iFont */
|
||||
o.write_shift(2, 0); /* iFill */
|
||||
o.write_shift(2, 0); /* ixBorder */
|
||||
o.write_shift(1, 0); /* trot */
|
||||
o.write_shift(1, 0); /* indent */
|
||||
o.write_shift(1, 0); /* flags */
|
||||
o.write_shift(1, 0); /* flags */
|
||||
o.write_shift(1, 0); /* xfGrbitAtr */
|
||||
o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.5.4 Blxf TODO */
|
||||
function write_Blxf(data, o) {
|
||||
if(!o) o = new_buf(10);
|
||||
o.write_shift(1, 0); /* dg */
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(4, 0); /* color */
|
||||
o.write_shift(4, 0); /* color */
|
||||
return o;
|
||||
}
|
||||
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
|
||||
function write_BrtBorder(border, o) {
|
||||
if(!o) o = new_buf(51);
|
||||
o.write_shift(1, 0); /* diagonal */
|
||||
write_Blxf(null, o); /* top */
|
||||
write_Blxf(null, o); /* bottom */
|
||||
write_Blxf(null, o); /* left */
|
||||
write_Blxf(null, o); /* right */
|
||||
write_Blxf(null, o); /* diag */
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.755 BrtStyle TODO */
|
||||
function write_BrtStyle(style, o) {
|
||||
if(!o) o = new_buf(12+4*10);
|
||||
o.write_shift(4, style.xfId);
|
||||
o.write_shift(2, 1);
|
||||
o.write_shift(1, +style.builtinId);
|
||||
o.write_shift(1, 0); /* iLevel */
|
||||
write_XLNullableWideString(style.name || "", o);
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.269 BrtBeginTableStyles */
|
||||
function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) {
|
||||
var o = new_buf(4+256*2*4);
|
||||
o.write_shift(4, cnt);
|
||||
write_XLNullableWideString(defTableStyle, o);
|
||||
write_XLNullableWideString(defPivotStyle, o);
|
||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.50 Styles */
|
||||
function parse_sty_bin(data, themes, opts) {
|
||||
@ -57,6 +212,9 @@ function parse_sty_bin(data, themes, opts) {
|
||||
break;
|
||||
case 0x002B: /* 'BrtFont' */
|
||||
styles.Fonts.push(val);
|
||||
if(val.color.theme != null && themes && themes.themeElements && themes.themeElements.clrScheme) {
|
||||
val.color.rgb = rgb_tint(themes.themeElements.clrScheme[val.color.theme].rgb, val.color.tint || 0);
|
||||
}
|
||||
break;
|
||||
case 0x0401: /* 'BrtKnownFonts' */ break;
|
||||
case 0x002D: /* 'BrtFill' */ break;
|
||||
@ -98,20 +256,126 @@ function parse_sty_bin(data, themes, opts) {
|
||||
return styles;
|
||||
}
|
||||
|
||||
function write_FMTS_bin(ba, NF) {
|
||||
if(!NF) return;
|
||||
var cnt = 0;
|
||||
[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt;
|
||||
});
|
||||
|
||||
if(cnt == 0) return;
|
||||
write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt));
|
||||
[[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) {
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i]));
|
||||
});
|
||||
write_record(ba, "BrtEndFmts");
|
||||
}
|
||||
|
||||
function write_FONTS_bin(ba, data) {
|
||||
var cnt = 1;
|
||||
|
||||
if(cnt == 0) return;
|
||||
write_record(ba, "BrtBeginFonts", write_UInt32LE(cnt));
|
||||
write_record(ba, "BrtFont", write_BrtFont({
|
||||
sz:12,
|
||||
color: {theme:1},
|
||||
name: "Calibri",
|
||||
family: 2,
|
||||
scheme: "minor"
|
||||
}));
|
||||
/* 1*65491BrtFont [ACFONTS] */
|
||||
write_record(ba, "BrtEndFonts");
|
||||
}
|
||||
|
||||
function write_FILLS_bin(ba, data) {
|
||||
var cnt = 2;
|
||||
|
||||
if(cnt == 0) return;
|
||||
write_record(ba, "BrtBeginFills", write_UInt32LE(cnt));
|
||||
write_record(ba, "BrtFill", write_BrtFill({patternType:"none"}));
|
||||
write_record(ba, "BrtFill", write_BrtFill({patternType:"gray125"}));
|
||||
/* 1*65431BrtFill */
|
||||
write_record(ba, "BrtEndFills");
|
||||
}
|
||||
|
||||
function write_BORDERS_bin(ba, data) {
|
||||
var cnt = 1;
|
||||
|
||||
if(cnt == 0) return;
|
||||
write_record(ba, "BrtBeginBorders", write_UInt32LE(cnt));
|
||||
write_record(ba, "BrtBorder", write_BrtBorder({}));
|
||||
/* 1*65430BrtBorder */
|
||||
write_record(ba, "BrtEndBorders");
|
||||
}
|
||||
|
||||
function write_CELLSTYLEXFS_bin(ba, data) {
|
||||
var cnt = 1;
|
||||
write_record(ba, "BrtBeginCellStyleXFs", write_UInt32LE(cnt));
|
||||
write_record(ba, "BrtXF", write_BrtXF({
|
||||
numFmtId:0,
|
||||
fontId:0,
|
||||
fillId:0,
|
||||
borderId:0
|
||||
}, 0xFFFF));
|
||||
/* 1*65430(BrtXF *FRT) */
|
||||
write_record(ba, "BrtEndCellStyleXFs");
|
||||
}
|
||||
|
||||
function write_CELLXFS_bin(ba, data) {
|
||||
write_record(ba, "BrtBeginCellXFs", write_UInt32LE(data.length));
|
||||
data.forEach(function(c) { write_record(ba, "BrtXF", write_BrtXF(c,0)); });
|
||||
/* 1*65430(BrtXF *FRT) */
|
||||
write_record(ba, "BrtEndCellXFs");
|
||||
}
|
||||
|
||||
function write_STYLES_bin(ba, data) {
|
||||
var cnt = 1;
|
||||
|
||||
write_record(ba, "BrtBeginStyles", write_UInt32LE(1));
|
||||
write_record(ba, "BrtStyle", write_BrtStyle({
|
||||
xfId:0,
|
||||
builtinId:0,
|
||||
name:"Normal"
|
||||
}));
|
||||
/* 1*65430(BrtStyle *FRT) */
|
||||
write_record(ba, "BrtEndStyles");
|
||||
}
|
||||
|
||||
function write_DXFS_bin(ba, data) {
|
||||
var cnt = 0;
|
||||
|
||||
write_record(ba, "BrtBeginDXFs", write_UInt32LE(cnt));
|
||||
/* *2147483647(BrtDXF *FRT) */
|
||||
write_record(ba, "BrtEndDXFs");
|
||||
}
|
||||
|
||||
function write_TABLESTYLES_bin(ba, data) {
|
||||
var cnt = 0;
|
||||
|
||||
write_record(ba, "BrtBeginTableStyles", write_BrtBeginTableStyles(cnt, "TableStyleMedium9", "PivotStyleMedium4"));
|
||||
/* *TABLESTYLE */
|
||||
write_record(ba, "BrtEndTableStyles");
|
||||
}
|
||||
|
||||
function write_COLORPALETTE_bin(ba, data) {
|
||||
return;
|
||||
/* BrtBeginColorPalette [INDEXEDCOLORS] [MRUCOLORS] BrtEndColorPalette */
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.1.7.50 Styles */
|
||||
function write_sty_bin(data, opts) {
|
||||
function write_sty_bin(wb, opts) {
|
||||
var ba = buf_array();
|
||||
write_record(ba, "BrtBeginStyleSheet");
|
||||
/* [FMTS] */
|
||||
/* [FONTS] */
|
||||
/* [FILLS] */
|
||||
/* [BORDERS] */
|
||||
/* CELLSTYLEXFS */
|
||||
/* CELLXFS*/
|
||||
/* STYLES */
|
||||
/* DXFS */
|
||||
/* TABLESTYLES */
|
||||
/* [COLORPALETTE] */
|
||||
write_FMTS_bin(ba, wb.SSF);
|
||||
write_FONTS_bin(ba, wb);
|
||||
write_FILLS_bin(ba, wb);
|
||||
write_BORDERS_bin(ba, wb);
|
||||
write_CELLSTYLEXFS_bin(ba, wb);
|
||||
write_CELLXFS_bin(ba, opts.cellXfs);
|
||||
write_STYLES_bin(ba, wb);
|
||||
write_DXFS_bin(ba, wb);
|
||||
write_TABLESTYLES_bin(ba, wb);
|
||||
write_COLORPALETTE_bin(ba, wb);
|
||||
/* FRTSTYLESHEET*/
|
||||
write_record(ba, "BrtEndStyleSheet");
|
||||
return ba.end();
|
||||
|
@ -7,50 +7,41 @@ function parse_clrScheme(t, themes, opts) {
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(y[0]) {
|
||||
/* 20.1.6.2 clrScheme (Color Scheme) CT_ColorScheme */
|
||||
case '<a:clrScheme': case '</a:clrScheme>': break;
|
||||
|
||||
/* 20.1.2.3.32 srgbClr CT_SRgbColor */
|
||||
case '<a:srgbClr': color.rgb = y.val; break;
|
||||
case '<a:srgbClr':
|
||||
color.rgb = y.val; break;
|
||||
|
||||
/* 20.1.2.3.33 sysClr CT_SystemColor */
|
||||
case '<a:sysClr': color.rgb = y.lastClr; break;
|
||||
case '<a:sysClr':
|
||||
color.rgb = y.lastClr; break;
|
||||
|
||||
/* 20.1.4.1.9 dk1 (Dark 1) */
|
||||
case '<a:dk1>':
|
||||
case '</a:dk1>':
|
||||
/* 20.1.4.1.10 dk2 (Dark 2) */
|
||||
case '<a:dk2>':
|
||||
case '</a:dk2>':
|
||||
/* 20.1.4.1.22 lt1 (Light 1) */
|
||||
case '<a:lt1>':
|
||||
case '</a:lt1>':
|
||||
/* 20.1.4.1.23 lt2 (Light 2) */
|
||||
case '<a:lt2>':
|
||||
case '</a:lt2>':
|
||||
/* 20.1.4.1.1 accent1 (Accent 1) */
|
||||
case '<a:accent1>':
|
||||
case '</a:accent1>':
|
||||
/* 20.1.4.1.2 accent2 (Accent 2) */
|
||||
case '<a:accent2>':
|
||||
case '</a:accent2>':
|
||||
/* 20.1.4.1.3 accent3 (Accent 3) */
|
||||
case '<a:accent3>':
|
||||
case '</a:accent3>':
|
||||
/* 20.1.4.1.4 accent4 (Accent 4) */
|
||||
case '<a:accent4>':
|
||||
case '</a:accent4>':
|
||||
/* 20.1.4.1.5 accent5 (Accent 5) */
|
||||
case '<a:accent5>':
|
||||
case '</a:accent5>':
|
||||
/* 20.1.4.1.6 accent6 (Accent 6) */
|
||||
case '<a:accent6>':
|
||||
case '</a:accent6>':
|
||||
/* 20.1.4.1.19 hlink (Hyperlink) */
|
||||
case '<a:hlink>':
|
||||
case '</a:hlink>':
|
||||
/* 20.1.4.1.9 dk1 (Dark 1) */
|
||||
/* 20.1.4.1.10 dk2 (Dark 2) */
|
||||
/* 20.1.4.1.15 folHlink (Followed Hyperlink) */
|
||||
case '<a:folHlink>':
|
||||
case '</a:folHlink>':
|
||||
/* 20.1.4.1.19 hlink (Hyperlink) */
|
||||
/* 20.1.4.1.22 lt1 (Light 1) */
|
||||
/* 20.1.4.1.23 lt2 (Light 2) */
|
||||
case '<a:dk1>': case '</a:dk1>':
|
||||
case '<a:lt1>': case '</a:lt1>':
|
||||
case '<a:dk2>': case '</a:dk2>':
|
||||
case '<a:lt2>': case '</a:lt2>':
|
||||
case '<a:accent1>': case '</a:accent1>':
|
||||
case '<a:accent2>': case '</a:accent2>':
|
||||
case '<a:accent3>': case '</a:accent3>':
|
||||
case '<a:accent4>': case '</a:accent4>':
|
||||
case '<a:accent5>': case '</a:accent5>':
|
||||
case '<a:accent6>': case '</a:accent6>':
|
||||
case '<a:hlink>': case '</a:hlink>':
|
||||
case '<a:folHlink>': case '</a:folHlink>':
|
||||
if (y[0][1] === '/') {
|
||||
themes.themeElements.clrScheme.push(color);
|
||||
color = {};
|
||||
|
@ -22,8 +22,8 @@ function parse_cc_bin(data, opts) {
|
||||
out.push(val); break;
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0){}
|
||||
else if((R_n||"").indexOf("End") > 0){}
|
||||
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||
else if((R_n||"").indexOf("End") > 0){/* empty */}
|
||||
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ function write_comments_vml(rId, comments) {
|
||||
writetag('x:AutoFill', "False"),
|
||||
writetag('x:Row', String(c.r)),
|
||||
writetag('x:Column', String(c.c)),
|
||||
'<x:Visible/>',
|
||||
'</x:ClientData>',
|
||||
'</v:shape>'
|
||||
]); });
|
||||
|
@ -22,9 +22,6 @@ function write_BrtBeginComment(data, o) {
|
||||
/* [MS-XLSB] 2.4.324 BrtCommentAuthor */
|
||||
var parse_BrtCommentAuthor = parse_XLWideString;
|
||||
|
||||
/* [MS-XLSB] 2.4.325 BrtCommentText */
|
||||
var parse_BrtCommentText = parse_RichStr;
|
||||
|
||||
/* [MS-XLSB] 2.1.7.8 Comments */
|
||||
function parse_comments_bin(data, opts) {
|
||||
var out = [];
|
||||
@ -57,8 +54,8 @@ function parse_comments_bin(data, opts) {
|
||||
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0){}
|
||||
else if((R_n||"").indexOf("End") > 0){}
|
||||
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||
else if((R_n||"").indexOf("End") > 0){/* empty */}
|
||||
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
});
|
||||
@ -87,7 +84,7 @@ function write_comments_bin(data, opts) {
|
||||
c.iauthor = iauthor.indexOf(c.a);
|
||||
var range = {s:decode_cell(comment[0]),e:decode_cell(comment[0])};
|
||||
write_record(ba, "BrtBeginComment", write_BrtBeginComment([range, c]));
|
||||
if(c.t && c.t.length > 0) write_record(ba, "BrtCommentText", write_RichStr(c));
|
||||
if(c.t && c.t.length > 0) write_record(ba, "BrtCommentText", write_BrtCommentText(c));
|
||||
write_record(ba, "BrtEndComment");
|
||||
delete c.iauthor;
|
||||
});
|
||||
|
171
bits/62_fxls.js
171
bits/62_fxls.js
@ -1,7 +1,7 @@
|
||||
/* --- formula references point to MS-XLS --- */
|
||||
/* Small helpers */
|
||||
function parseread(l) { return function(blob, length) { blob.l+=l; return; }; }
|
||||
function parseread1(blob, length) { blob.l+=1; return; }
|
||||
function parseread1(blob) { blob.l+=1; return; }
|
||||
|
||||
/* Rgce Helpers */
|
||||
|
||||
@ -25,7 +25,7 @@ function parse_RgceArea(blob, length, opts) {
|
||||
return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} };
|
||||
}
|
||||
/* BIFF 2-5 encodes flags in the row field */
|
||||
function parse_RgceArea_BIFF2(blob, length, opts) {
|
||||
function parse_RgceArea_BIFF2(blob/*, length, opts*/) {
|
||||
var r=parse_ColRelU(blob, 2), R=parse_ColRelU(blob, 2);
|
||||
var c=blob.read_shift(1);
|
||||
var C=blob.read_shift(1);
|
||||
@ -33,7 +33,7 @@ function parse_RgceArea_BIFF2(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.5.198.105 TODO */
|
||||
function parse_RgceAreaRel(blob, length, opts) {
|
||||
function parse_RgceAreaRel(blob, length/*, opts*/) {
|
||||
var r=blob.read_shift(length == 12 ? 4 : 2), R=blob.read_shift(length == 12 ? 4 : 2);
|
||||
var c=parse_ColRelU(blob, 2);
|
||||
var C=parse_ColRelU(blob, 2);
|
||||
@ -701,12 +701,12 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
var f = formula[0][ff];
|
||||
//console.log("++",f, stack)
|
||||
switch(f[0]) {
|
||||
/* 2.5.198.93 */
|
||||
case 'PtgUminus': stack.push("-" + stack.pop()); break;
|
||||
/* 2.5.198.95 */
|
||||
case 'PtgUplus': stack.push("+" + stack.pop()); break;
|
||||
/* 2.5.198.81 */
|
||||
case 'PtgPercent': stack.push(stack.pop() + "%"); break;
|
||||
case 'PtgUminus': /* 2.5.198.93 */
|
||||
stack.push("-" + stack.pop()); break;
|
||||
case 'PtgUplus': /* 2.5.198.95 */
|
||||
stack.push("+" + stack.pop()); break;
|
||||
case 'PtgPercent': /* 2.5.198.81 */
|
||||
stack.push(stack.pop() + "%"); break;
|
||||
|
||||
case 'PtgAdd': /* 2.5.198.26 */
|
||||
case 'PtgConcat': /* 2.5.198.43 */
|
||||
@ -723,10 +723,12 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
e1 = stack.pop(); e2 = stack.pop();
|
||||
if(last_sp >= 0) {
|
||||
switch(formula[0][last_sp][1][0]) {
|
||||
// $FlowIgnore
|
||||
case 0: sp = fill(" ", formula[0][last_sp][1][1]); break;
|
||||
// $FlowIgnore
|
||||
case 1: sp = fill("\r", formula[0][last_sp][1][1]); break;
|
||||
case 0:
|
||||
// $FlowIgnore
|
||||
sp = fill(" ", formula[0][last_sp][1][1]); break;
|
||||
case 1:
|
||||
// $FlowIgnore
|
||||
sp = fill("\r", formula[0][last_sp][1][1]); break;
|
||||
default:
|
||||
sp = "";
|
||||
// $FlowIgnore
|
||||
@ -738,51 +740,46 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
stack.push(e2+PtgBinOp[f[0]]+e1);
|
||||
break;
|
||||
|
||||
/* 2.5.198.67 */
|
||||
case 'PtgIsect':
|
||||
case 'PtgIsect': /* 2.5.198.67 */
|
||||
e1 = stack.pop(); e2 = stack.pop();
|
||||
stack.push(e2+" "+e1);
|
||||
break;
|
||||
case 'PtgUnion':
|
||||
case 'PtgUnion': /* 2.5.198.94 */
|
||||
e1 = stack.pop(); e2 = stack.pop();
|
||||
stack.push(e2+","+e1);
|
||||
break;
|
||||
case 'PtgRange':
|
||||
case 'PtgRange': /* 2.5.198.83 */
|
||||
e1 = stack.pop(); e2 = stack.pop();
|
||||
stack.push(e2+":"+e1);
|
||||
break;
|
||||
|
||||
/* 2.5.198.34 */
|
||||
case 'PtgAttrChoose': break;
|
||||
/* 2.5.198.35 */
|
||||
case 'PtgAttrGoto': break;
|
||||
/* 2.5.198.36 */
|
||||
case 'PtgAttrIf': break;
|
||||
/* [MS-XLSB] 2.5.97.28 */
|
||||
case 'PtgAttrIfError': break;
|
||||
case 'PtgAttrChoose': /* 2.5.198.34 */
|
||||
break;
|
||||
case 'PtgAttrGoto': /* 2.5.198.35 */
|
||||
break;
|
||||
case 'PtgAttrIf': /* 2.5.198.36 */
|
||||
break;
|
||||
case 'PtgAttrIfError': /* [MS-XLSB] 2.5.97.28 */
|
||||
break;
|
||||
|
||||
|
||||
/* 2.5.198.84 */
|
||||
case 'PtgRef':
|
||||
case 'PtgRef': /* 2.5.198.84 */
|
||||
type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts);
|
||||
stack.push(encode_cell_xls(c));
|
||||
break;
|
||||
/* 2.5.198.88 */
|
||||
case 'PtgRefN':
|
||||
case 'PtgRefN': /* 2.5.198.88 */
|
||||
type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1];
|
||||
stack.push(encode_cell_xls(c));
|
||||
break;
|
||||
case 'PtgRef3d': // TODO: lots of stuff
|
||||
case 'PtgRef3d': /* 2.5.198.85 */
|
||||
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts);
|
||||
sname = supbooks.SheetNames[ixti];
|
||||
var w = sname; /* IE9 fails on defined names */
|
||||
stack.push(sname + "!" + encode_cell_xls(c));
|
||||
break;
|
||||
|
||||
/* 2.5.198.62 */
|
||||
case 'PtgFunc':
|
||||
/* 2.5.198.63 */
|
||||
case 'PtgFuncVar':
|
||||
case 'PtgFunc': /* 2.5.198.62 */
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc/*:number*/ = f[1][0], func/*:string*/ = f[1][1];
|
||||
@ -793,43 +790,38 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
stack.push(func + "(" + args.join(",") + ")");
|
||||
break;
|
||||
|
||||
/* 2.5.198.42 */
|
||||
case 'PtgBool': stack.push(f[1] ? "TRUE" : "FALSE"); break;
|
||||
/* 2.5.198.66 */
|
||||
case 'PtgInt': stack.push(/*::String(*/f[1]/*::)*/); break;
|
||||
/* 2.5.198.79 TODO: precision? */
|
||||
case 'PtgNum': stack.push(String(f[1])); break;
|
||||
/* 2.5.198.89 */
|
||||
// $FlowIgnore
|
||||
case 'PtgStr': stack.push('"' + f[1] + '"'); break;
|
||||
/* 2.5.198.57 */
|
||||
case 'PtgErr': stack.push(/*::String(*/f[1]/*::)*/); break;
|
||||
/* 2.5.198.31 TODO */
|
||||
case 'PtgAreaN':
|
||||
case 'PtgBool': /* 2.5.198.42 */
|
||||
stack.push(f[1] ? "TRUE" : "FALSE"); break;
|
||||
case 'PtgInt': /* 2.5.198.66 */
|
||||
stack.push(/*::String(*/f[1]/*::)*/); break;
|
||||
case 'PtgNum': /* 2.5.198.79 TODO: precision? */
|
||||
stack.push(String(f[1])); break;
|
||||
case 'PtgStr': /* 2.5.198.89 */
|
||||
// $FlowIgnore
|
||||
stack.push('"' + f[1] + '"'); break;
|
||||
case 'PtgErr': /* 2.5.198.57 */
|
||||
stack.push(/*::String(*/f[1]/*::)*/); break;
|
||||
case 'PtgAreaN': /* 2.5.198.31 TODO */
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
|
||||
stack.push(encode_range_xls((r/*:any*/), opts));
|
||||
break;
|
||||
/* 2.5.198.27 TODO: fixed points */
|
||||
case 'PtgArea':
|
||||
case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
|
||||
stack.push(encode_range_xls((r/*:any*/), opts));
|
||||
break;
|
||||
/* 2.5.198.28 */
|
||||
case 'PtgArea3d': // TODO: lots of stuff
|
||||
case 'PtgArea3d': /* 2.5.198.28 TODO */
|
||||
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; r = f[1][2];
|
||||
sname = (supbooks && supbooks[1] ? supbooks[1][ixti+1] : "**MISSING**");
|
||||
stack.push(sname + "!" + encode_range((r/*:any*/)));
|
||||
break;
|
||||
/* 2.5.198.41 */
|
||||
case 'PtgAttrSum':
|
||||
case 'PtgAttrSum': /* 2.5.198.41 */
|
||||
stack.push("SUM(" + stack.pop() + ")");
|
||||
break;
|
||||
|
||||
/* 2.5.198.37 */
|
||||
case 'PtgAttrSemi': break;
|
||||
case 'PtgAttrSemi': /* 2.5.198.37 */
|
||||
break;
|
||||
|
||||
/* 2.5.97.60 TODO: do something different for revisions */
|
||||
case 'PtgName':
|
||||
case 'PtgName': /* 2.5.97.60 TODO: revisions */
|
||||
/* f[1] = type, 0, nameindex */
|
||||
nameidx = f[1][2];
|
||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||
@ -838,8 +830,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
stack.push(name);
|
||||
break;
|
||||
|
||||
/* 2.5.97.61 TODO: do something different for revisions */
|
||||
case 'PtgNameX':
|
||||
case 'PtgNameX': /* 2.5.97.61 TODO: revisions */
|
||||
/* f[1] = type, ixti, nameindex */
|
||||
var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = f[1][2]; var externbook;
|
||||
/* TODO: Properly handle missing values */
|
||||
@ -850,7 +841,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
} else {
|
||||
var pnxname = supbooks.SheetNames[bookidx];
|
||||
var o = "";
|
||||
if(((supbooks[bookidx]||[])[0]||[])[0] == 0x3A01){}
|
||||
if(((supbooks[bookidx]||[])[0]||[])[0] == 0x3A01){/* empty */}
|
||||
else if(((supbooks[bookidx]||[])[0]||[])[0] == 0x0401){
|
||||
if(supbooks[bookidx][nameidx] && supbooks[bookidx][nameidx].itab > 0) {
|
||||
o = supbooks.SheetNames[supbooks[bookidx][nameidx].itab-1] + "!";
|
||||
@ -867,8 +858,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
stack.push(externbook.Name);
|
||||
break;
|
||||
|
||||
/* 2.5.198.80 */
|
||||
case 'PtgParen':
|
||||
case 'PtgParen': /* 2.5.198.80 */
|
||||
var lp = '(', rp = ')';
|
||||
if(last_sp >= 0) {
|
||||
sp = "";
|
||||
@ -889,15 +879,13 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
}
|
||||
stack.push(lp + stack.pop() + rp); break;
|
||||
|
||||
/* 2.5.198.86 */
|
||||
case 'PtgRefErr': stack.push('#REF!'); break;
|
||||
case 'PtgRefErr': /* 2.5.198.86 */
|
||||
stack.push('#REF!'); break;
|
||||
|
||||
/* 2.5.198.87 */
|
||||
case 'PtgRefErr3d': stack.push('#REF!'); break;
|
||||
case 'PtgRefErr3d': /* 2.5.198.87 */
|
||||
stack.push('#REF!'); break;
|
||||
|
||||
/* */
|
||||
/* 2.5.198.58 TODO */
|
||||
case 'PtgExp':
|
||||
case 'PtgExp': /* 2.5.198.58 TODO */
|
||||
c = {c:f[1][1],r:f[1][0]};
|
||||
var q = ({c: cell.c, r:cell.r}/*:any*/);
|
||||
if(supbooks.sharedf[encode_cell(c)]) {
|
||||
@ -919,42 +907,37 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
}
|
||||
break;
|
||||
|
||||
/* 2.5.198.32 TODO */
|
||||
case 'PtgArray':
|
||||
case 'PtgArray': /* 2.5.198.32 TODO */
|
||||
stack.push("{" + stringify_array(f[1]) + "}");
|
||||
break;
|
||||
|
||||
/* 2.5.198.70 TODO: confirm this is a non-display */
|
||||
case 'PtgMemArea':
|
||||
case 'PtgMemArea': /* 2.5.198.70 TODO: confirm this is a non-display */
|
||||
//stack.push("(" + f[2].map(encode_range).join(",") + ")");
|
||||
break;
|
||||
|
||||
/* 2.5.198.38 */
|
||||
case 'PtgAttrSpace':
|
||||
/* 2.5.198.39 */
|
||||
case 'PtgAttrSpaceSemi':
|
||||
case 'PtgAttrSpace': /* 2.5.198.38 */
|
||||
case 'PtgAttrSpaceSemi': /* 2.5.198.39 */
|
||||
last_sp = ff;
|
||||
break;
|
||||
|
||||
/* 2.5.198.92 TODO */
|
||||
case 'PtgTbl': break;
|
||||
case 'PtgTbl': /* 2.5.198.92 TODO */
|
||||
break;
|
||||
|
||||
/* 2.5.198.71 */
|
||||
case 'PtgMemErr': break;
|
||||
case 'PtgMemErr': /* 2.5.198.71 */
|
||||
break;
|
||||
|
||||
/* 2.5.198.74 */
|
||||
case 'PtgMissArg':
|
||||
case 'PtgMissArg': /* 2.5.198.74 */
|
||||
stack.push("");
|
||||
break;
|
||||
|
||||
/* 2.5.198.29 */
|
||||
case 'PtgAreaErr': stack.push("#REF!"); break;
|
||||
case 'PtgAreaErr': /* 2.5.198.29 */
|
||||
stack.push("#REF!"); break;
|
||||
|
||||
/* 2.5.198.30 */
|
||||
case 'PtgAreaErr3d': stack.push("#REF!"); break;
|
||||
case 'PtgAreaErr3d': /* 2.5.198.30 */
|
||||
stack.push("#REF!"); break;
|
||||
|
||||
/* 2.5.198.72 TODO */
|
||||
case 'PtgMemFunc': break;
|
||||
case 'PtgMemFunc': /* 2.5.198.72 TODO */
|
||||
break;
|
||||
|
||||
default: throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
}
|
||||
@ -966,12 +949,14 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
/* note: some bad XLSB files omit the PtgParen */
|
||||
case 4: _left = false;
|
||||
/* falls through */
|
||||
// $FlowIgnore
|
||||
case 0: sp = fill(" ", f[1][1]); break;
|
||||
case 0:
|
||||
// $FlowIgnore
|
||||
sp = fill(" ", f[1][1]); break;
|
||||
case 5: _left = false;
|
||||
/* falls through */
|
||||
// $FlowIgnore
|
||||
case 1: sp = fill("\r", f[1][1]); break;
|
||||
case 1:
|
||||
// $FlowIgnore
|
||||
sp = fill("\r", f[1][1]); break;
|
||||
default:
|
||||
sp = "";
|
||||
// $FlowIgnore
|
||||
|
@ -39,7 +39,16 @@ function default_margins(margins, mode) {
|
||||
|
||||
function get_cell_style(styles, cell, opts) {
|
||||
var z = opts.revssf[cell.z != null ? cell.z : "General"];
|
||||
for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
|
||||
var i = 0x3c, len = styles.length;
|
||||
if(z == null && opts.ssf) {
|
||||
for(; i < 0x188; ++i) if(opts.ssf[i] == null) {
|
||||
SSF.load(cell.z, i);
|
||||
opts.ssf[i] = cell.z;
|
||||
opts.revssf[cell.z] = z = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i = 0; i != len; ++i) if(styles[i].numFmtId === z) return i;
|
||||
styles[len] = {
|
||||
numFmtId:z,
|
||||
fontId:0,
|
||||
@ -77,7 +86,7 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
if(fillid) try {
|
||||
p.s = styles.Fills[fillid];
|
||||
if (p.s.fgColor && p.s.fgColor.theme) {
|
||||
if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
|
||||
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
|
||||
if(opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb;
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ function write_row_header(ba, ws, range, R) {
|
||||
var parse_BrtWsDim = parse_UncheckedRfX;
|
||||
var write_BrtWsDim = write_UncheckedRfX;
|
||||
|
||||
/* [MS-XLSB] 2.4.813 BrtWsFmtInfo */
|
||||
//function write_BrtWsFmtInfo(ws, o) { }
|
||||
|
||||
/* [MS-XLSB] 2.4.815 BrtWsProp */
|
||||
function parse_BrtWsProp(data, length) {
|
||||
var z = {};
|
||||
@ -78,8 +81,9 @@ function parse_BrtWsProp(data, length) {
|
||||
return z;
|
||||
}
|
||||
function write_BrtWsProp(str, o) {
|
||||
if(o == null) o = new_buf(80+4*str.length);
|
||||
for(var i = 0; i < 11; ++i) o.write_shift(1,0);
|
||||
if(o == null) o = new_buf(84+4*str.length);
|
||||
for(var i = 0; i < 3; ++i) o.write_shift(1,0);
|
||||
write_BrtColor({auto:1}, o);
|
||||
o.write_shift(-4,-1);
|
||||
o.write_shift(-4,-1);
|
||||
write_XLSBCodeName(str, o);
|
||||
@ -260,8 +264,8 @@ function write_BrtHLink(l, rId, o) {
|
||||
write_UncheckedRfX({s:decode_cell(l[0]), e:decode_cell(l[0])}, o);
|
||||
write_RelID("rId" + rId, o);
|
||||
var locidx = l[1].Target.indexOf("#");
|
||||
var location = locidx == -1 ? "" : l[1].Target.substr(locidx+1);
|
||||
write_XLWideString(location || "", o);
|
||||
var loc = locidx == -1 ? "" : l[1].Target.substr(locidx+1);
|
||||
write_XLWideString(loc || "", o);
|
||||
write_XLWideString(l[1].Tooltip || "", o);
|
||||
write_XLWideString("", o);
|
||||
return o.slice(0, o.l);
|
||||
@ -536,6 +540,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
s['!margins'] = val;
|
||||
break;
|
||||
|
||||
/* case 'BrtUid' */
|
||||
case 0x00AF: /* 'BrtAFilterDateGroupItem' */
|
||||
case 0x0284: /* 'BrtActiveX' */
|
||||
case 0x0271: /* 'BrtBigName' */
|
||||
@ -585,7 +590,6 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
case 0x0413: /* 'BrtSparkline' */
|
||||
case 0x01AC: /* 'BrtTable' */
|
||||
case 0x00AA: /* 'BrtTop10Filter' */
|
||||
/* case 'BrtUid' */
|
||||
case 0x0032: /* 'BrtValueMeta' */
|
||||
case 0x0816: /* 'BrtWebExtension' */
|
||||
case 0x01E5: /* 'BrtWsFmtInfo' */
|
||||
@ -601,8 +605,8 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
case 0x0026: /* 'BrtACEnd' */ break;
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0){}
|
||||
else if((R_n||"").indexOf("End") > 0){}
|
||||
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||
else if((R_n||"").indexOf("End") > 0){/* empty */}
|
||||
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
}, opts);
|
||||
@ -646,7 +650,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
||||
}
|
||||
var o/*:any*/ = ({r:R, c:C}/*:any*/);
|
||||
/* TODO: cell style */
|
||||
//o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
if(cell.l) ws['!links'].push([encode_cell(o), cell.l]);
|
||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||
switch(cell.t) {
|
||||
@ -753,6 +757,11 @@ function write_WSVIEWS2(ba, ws) {
|
||||
write_record(ba, "BrtEndWsViews");
|
||||
}
|
||||
|
||||
function write_WSFMTINFO(ba, ws) {
|
||||
/* [ACWSFMTINFO] */
|
||||
//write_record(ba, "BrtWsFmtInfo", write_BrtWsFmtInfo(ws));
|
||||
}
|
||||
|
||||
function write_SHEETPROTECT(ba, ws) {
|
||||
if(!ws['!protect']) return;
|
||||
/* [BrtSheetProtectionIso] */
|
||||
@ -770,7 +779,7 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
|
||||
write_record(ba, "BrtWsProp", write_BrtWsProp(s));
|
||||
write_record(ba, "BrtWsDim", write_BrtWsDim(r));
|
||||
write_WSVIEWS2(ba, ws);
|
||||
/* [WSFMTINFO] */
|
||||
write_WSFMTINFO(ba, ws);
|
||||
write_COLINFOS(ba, ws, idx, opts, wb);
|
||||
write_CELLTABLE(ba, ws, idx, opts, wb);
|
||||
/* [BrtSheetCalcProp] */
|
||||
|
@ -24,7 +24,7 @@ function parse_BrtWbProp(data, length) {
|
||||
return [dwThemeVersion, strName];
|
||||
}
|
||||
function write_BrtWbProp(data, o) {
|
||||
if(!o) o = new_buf(68);
|
||||
if(!o) o = new_buf(72);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(4, 0);
|
||||
write_XLSBCodeName("ThisWorkbook", o);
|
||||
@ -85,6 +85,9 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
||||
break;
|
||||
case 0x040C: /* 'BrtNameExt' */ break;
|
||||
|
||||
/* case 'BrtModelTimeGroupingCalcCol' */
|
||||
/* case 'BrtRevisionPtr' */
|
||||
/* case 'BrtUid' */
|
||||
case 0x0817: /* 'BrtAbsPath15' */
|
||||
case 0x0216: /* 'BrtBookProtection' */
|
||||
case 0x02A5: /* 'BrtBookProtectionIso' */
|
||||
@ -100,11 +103,9 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
||||
case 0x0299: /* 'BrtFnGroup' */
|
||||
case 0x0850: /* 'BrtModelRelationship' */
|
||||
case 0x084D: /* 'BrtModelTable' */
|
||||
/* case 'BrtModelTimeGroupingCalcCol' */
|
||||
case 0x0225: /* 'BrtOleSize' */
|
||||
case 0x0805: /* 'BrtPivotTableRef' */
|
||||
case 0x0169: /* 'BrtPlaceholderName' */
|
||||
/* case 'BrtRevisionPtr' */
|
||||
case 0x0254: /* 'BrtSmartTagType' */
|
||||
case 0x029B: /* 'BrtSupAddin' */
|
||||
case 0x0163: /* 'BrtSupBookSrc' */
|
||||
@ -113,7 +114,6 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
||||
case 0x081C: /* 'BrtTableSlicerCacheID' */
|
||||
case 0x081B: /* 'BrtTableSlicerCacheIDs' */
|
||||
case 0x0822: /* 'BrtTimelineCachePivotCacheID' */
|
||||
/* case 'BrtUid' */
|
||||
case 0x018D: /* 'BrtUserBookView' */
|
||||
case 0x009A: /* 'BrtWbFactoid' */
|
||||
case 0x0099: /* 'BrtWbProp' */
|
||||
@ -132,8 +132,8 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
||||
case 0x0010: /* 'BrtFRTArchID$' */ break;
|
||||
|
||||
default:
|
||||
if((R_n||"").indexOf("Begin") > 0){}
|
||||
else if((R_n||"").indexOf("End") > 0){}
|
||||
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||
else if((R_n||"").indexOf("End") > 0){/* empty */}
|
||||
else if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||
}
|
||||
}, opts);
|
||||
|
@ -530,7 +530,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
/* WorksheetOptions */
|
||||
case 'WorksheetOptions': switch(Rn[3]) {
|
||||
case 'Visible':
|
||||
if(Rn[0].slice(-2) === "/>"){}
|
||||
if(Rn[0].slice(-2) === "/>"){/* empty */}
|
||||
else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
|
||||
case "SheetHidden": wsprops.Hidden = 1; break;
|
||||
case "SheetVeryHidden": wsprops.Hidden = 2; break;
|
||||
@ -729,12 +729,10 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
default: seen = false;
|
||||
} break;
|
||||
|
||||
/* Sorting */
|
||||
case 'Sorting':
|
||||
/* ConditionalFormatting */
|
||||
case 'ConditionalFormatting':
|
||||
/* DataValidation */
|
||||
case 'DataValidation': switch(Rn[3]) {
|
||||
case 'DataValidation':
|
||||
switch(Rn[3]) {
|
||||
case 'Range': break;
|
||||
case 'Type': break;
|
||||
case 'Min': break;
|
||||
@ -889,7 +887,7 @@ function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workb
|
||||
|
||||
if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
|
||||
/* Visible */
|
||||
if(!!wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden"), {}));
|
||||
if(wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden"), {}));
|
||||
else {
|
||||
/* Selected */
|
||||
for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
|
||||
|
@ -56,7 +56,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
|
||||
if(p.t === 'z') return;
|
||||
if(!p.XF) return;
|
||||
try {
|
||||
var fmtid = p.XF.ifmt||0;
|
||||
var fmtid = p.z || p.XF.ifmt || 0;
|
||||
if(opts.cellNF) p.z = SSF._table[fmtid];
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
if(!opts || opts.cellText !== false) try {
|
||||
@ -179,6 +179,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
var last_Rn = '';
|
||||
var file_depth = 0; /* TODO: make a real stack */
|
||||
var BIFF2Fmt = 0;
|
||||
var BIFF2FmtTable = [];
|
||||
var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
|
||||
var last_lbl;
|
||||
|
||||
@ -309,7 +310,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
out = options.dense ? [] : {};
|
||||
} break;
|
||||
case 'BOF': {
|
||||
if(opts.biff !== 8){}
|
||||
if(opts.biff !== 8){/* empty */}
|
||||
else if(RecordType === 0x0009) opts.biff = 2;
|
||||
else if(RecordType === 0x0209) opts.biff = 3;
|
||||
else if(RecordType === 0x0409) opts.biff = 4;
|
||||
@ -342,17 +343,20 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
|
||||
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
||||
if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c;
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'};
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'};
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
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(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
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(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
} break;
|
||||
@ -360,6 +364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
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(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:j, r:val.r}, temp_val, options);
|
||||
}
|
||||
@ -377,6 +382,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
else temp_val.F = ((options.dense ? (out[_fr]||[])[_fc]: out[_fe]) || {}).F;
|
||||
} else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
}
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell(val.cell, temp_val, options);
|
||||
last_formula = val;
|
||||
@ -389,6 +395,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
if(options.cellFormula) {
|
||||
temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
|
||||
}
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell(last_formula.cell, temp_val, options);
|
||||
last_formula = null;
|
||||
@ -419,11 +426,13 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
case 'LabelSst':
|
||||
temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
|
||||
temp_val.XF = XFs[temp_val.ixfe];
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
break;
|
||||
case 'Blank': if(options.sheetStubs) {
|
||||
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'};
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
} break;
|
||||
@ -431,6 +440,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
for(var _j = val.c; _j <= val.C; ++_j) {
|
||||
var _ixfe = val.ixfe[_j-val.c];
|
||||
temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'};
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:_j, r:val.r}, temp_val, options);
|
||||
}
|
||||
@ -439,6 +449,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
case 'Label': case 'BIFF2STR':
|
||||
temp_val=make_cell(val.val, val.ixfe, 's');
|
||||
temp_val.XF = XFs[temp_val.ixfe];
|
||||
if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F];
|
||||
safe_format_xf(temp_val, options, wb.opts.Date1904);
|
||||
addcell({c:val.c, r:val.r}, temp_val, options);
|
||||
break;
|
||||
@ -453,20 +464,23 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
SSF.load(val[1], val[0]);
|
||||
} break;
|
||||
case 'BIFF2FORMAT': {
|
||||
SSF.load(val, BIFF2Fmt++);
|
||||
BIFF2FmtTable[BIFF2Fmt++] = val;
|
||||
for(var b2idx = 0; b2idx < BIFF2Fmt + 163; ++b2idx) if(SSF._table[b2idx] == val) break;
|
||||
if(b2idx >= 163) SSF.load(val, BIFF2Fmt + 163);
|
||||
} break;
|
||||
|
||||
case 'MergeCells': mergecells = mergecells.concat(val); break;
|
||||
|
||||
case 'Obj': objects[val.cmo[0]] = opts.lastobj = val; break;
|
||||
case 'TxO': opts.lastobj.TxO = val; break;
|
||||
case 'ImData': opts.lastobj.ImData = val; break;
|
||||
|
||||
case 'HLink': {
|
||||
for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
|
||||
for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
|
||||
cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})];
|
||||
if(cc) cc.l = val[1];
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case 'HLinkTooltip': {
|
||||
for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
|
||||
@ -611,24 +625,24 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
//console.log("Zoom Level:", val[0]/val[1],val);
|
||||
} break;
|
||||
case 'SheetExt': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
case 'SheetExtOptional': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
|
||||
/* VBA */
|
||||
case 'ObNoMacros': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
case 'ObProj': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
case 'CodeName': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
case 'GUIDTypeLib': {
|
||||
|
||||
/* empty */
|
||||
} break;
|
||||
|
||||
case 'WOpt': break; // TODO: WTF?
|
||||
@ -657,7 +671,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
/* Explicitly Ignored */
|
||||
case 'Excel9File': break;
|
||||
case 'Units': break;
|
||||
case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount':
|
||||
case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount': break;
|
||||
/* View Stuff */
|
||||
case 'Window1': case 'Window2': case 'HideObj': case 'GridSet': case 'Guts':
|
||||
case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd':
|
||||
@ -724,13 +738,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
/* Drawing */
|
||||
case 'ShapePropsStream': break;
|
||||
case 'MsoDrawing': case 'MsoDrawingGroup': case 'MsoDrawingSelection': break;
|
||||
case 'ImData': break;
|
||||
/* Pub Stuff */
|
||||
case 'WebPub': case 'AutoWebPub':
|
||||
case 'WebPub': case 'AutoWebPub': break;
|
||||
|
||||
/* Print Stuff */
|
||||
case 'HeaderFooter': case 'HFPicture': case 'PLV':
|
||||
case 'HorizontalPageBreaks': case 'VerticalPageBreaks':
|
||||
case 'HorizontalPageBreaks': case 'VerticalPageBreaks': break;
|
||||
/* Behavioral */
|
||||
case 'Backup': case 'CompressPictures': case 'Compat12': break;
|
||||
|
||||
@ -779,11 +792,11 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
function parse_props(cfb) {
|
||||
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
|
||||
var DSI = cfb.find('!DocumentSummaryInformation');
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {}
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
|
||||
var SI = cfb.find('!SummaryInformation');
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {}
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
|
||||
}
|
||||
|
||||
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
@ -1192,9 +1192,10 @@ var XLSRecordEnum = {
|
||||
/*::[*/0x0007/*::]*/: { n:"String", f:parse_BIFF2STRING },
|
||||
/*::[*/0x0008/*::]*/: { n:"BIFF2ROW", f:parsenoop },
|
||||
/*::[*/0x000b/*::]*/: { n:"Index", f:parse_Index },
|
||||
/*::[*/0x0016/*::]*/: { n:"ExternCount", f:parsenoop },
|
||||
/*::[*/0x001e/*::]*/: { n:"BIFF2FORMAT", f:parse_BIFF2Format },
|
||||
/*::[*/0x001f/*::]*/: { n:"BIFF2FMTCNT", f:parsenoop }, /* 16-bit cnt of BIFF2FORMAT records */
|
||||
/*::[*/0x0016/*::]*/: { n:"ExternCount", f:parsenoop },
|
||||
/*::[*/0x0020/*::]*/: { n:"BIFF2COLINFO", f:parsenoop },
|
||||
/*::[*/0x0021/*::]*/: { n:"Array", f:parse_Array },
|
||||
/*::[*/0x0025/*::]*/: { n:"DefaultRowHeight", f:parse_DefaultRowHeight },
|
||||
/*::[*/0x0032/*::]*/: { n:"BIFF2FONTXTRA", f:parse_BIFF2FONTXTRA },
|
||||
@ -1202,7 +1203,7 @@ var XLSRecordEnum = {
|
||||
/*::[*/0x0045/*::]*/: { n:"BIFF2FONTCLR", f:parsenoop },
|
||||
/*::[*/0x0056/*::]*/: { n:"BIFF4FMTCNT", f:parsenoop }, /* 16-bit cnt, similar to BIFF2 */
|
||||
/*::[*/0x007e/*::]*/: { n:"RK", f:parsenoop }, /* Not necessarily same as 0x027e */
|
||||
/*::[*/0x007f/*::]*/: { n:"ImData", f:parsenoop },
|
||||
/*::[*/0x007f/*::]*/: { n:"ImData", f:parse_ImData },
|
||||
/*::[*/0x0087/*::]*/: { n:"Addin", f:parsenoop },
|
||||
/*::[*/0x0088/*::]*/: { n:"Edg", f:parsenoop },
|
||||
/*::[*/0x0089/*::]*/: { n:"Pub", f:parsenoop },
|
||||
|
@ -312,7 +312,7 @@ var parse_content_xml = (function() {
|
||||
try {
|
||||
var AutoFilter = ods_to_csf_range_3D(parsexmltag(Rn[0])['target-range-address']);
|
||||
Sheets[AutoFilter[0]]['!autofilter'] = { ref: AutoFilter[1] };
|
||||
} catch(e) { }
|
||||
} catch(e) {/* empty */}
|
||||
break;
|
||||
|
||||
case 's': break; // <text:s>
|
||||
@ -362,7 +362,8 @@ var parse_content_xml = (function() {
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
case 'event-listener': // TODO
|
||||
case 'event-listener':
|
||||
break;
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creation-date':
|
||||
|
@ -9,6 +9,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
make_ssf(SSF); SSF.load_table(wb.SSF);
|
||||
// $FlowIgnore
|
||||
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
|
||||
opts.ssf = wb.SSF;
|
||||
}
|
||||
opts.rels = {}; opts.wbrels = {};
|
||||
opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
|
||||
@ -37,7 +38,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
|
||||
/*::if(!wb.Props) throw "unreachable"; */
|
||||
f = "docProps/app.xml";
|
||||
if(wb.Props && wb.Props.SheetNames){}
|
||||
if(wb.Props && wb.Props.SheetNames){/* empty */}
|
||||
else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
|
||||
// $FlowIgnore
|
||||
else wb.Props.SheetNames = wb.SheetNames.map(function(x,i) { return [(wb.Workbook.Sheets[i]||{}).Hidden != 2, x];}).filter(function(x) { return x[0]; }).map(function(x) { return x[1]; });
|
||||
@ -126,5 +127,7 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
zip.file("[Content_Types].xml", write_ct(ct, opts));
|
||||
zip.file('_rels/.rels', write_rels(opts.rels));
|
||||
zip.file('xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||
|
||||
delete opts.revssf; delete opts.ssf;
|
||||
return zip;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ function get_radio_value( radioName ) {
|
||||
function to_json(workbook) {
|
||||
var result = {};
|
||||
workbook.SheetNames.forEach(function(sheetName) {
|
||||
var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
|
||||
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
|
||||
if(roa.length > 0){
|
||||
result[sheetName] = roa;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ function get_radio_value( radioName ) {
|
||||
function to_json(workbook) {
|
||||
var result = {};
|
||||
workbook.SheetNames.forEach(function(sheetName) {
|
||||
var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
|
||||
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
|
||||
if(roa.length > 0){
|
||||
result[sheetName] = roa;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ function get_radio_value( radioName ) {
|
||||
function to_json(workbook) {
|
||||
var result = {};
|
||||
workbook.SheetNames.forEach(function(sheetName) {
|
||||
var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
|
||||
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
|
||||
if(roa.length > 0){
|
||||
result[sheetName] = roa;
|
||||
}
|
||||
|
28
dist/xlsx.core.min.js
vendored
28
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
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
1286
dist/xlsx.js
vendored
1286
dist/xlsx.js
vendored
File diff suppressed because it is too large
Load Diff
28
dist/xlsx.min.js
vendored
28
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
@ -6,7 +6,8 @@ Emphasis on parsing and writing robustness, cross-format feature compatibility
|
||||
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
|
||||
|
||||
This is the community version. We also offer a pro version with performance
|
||||
enhancements and additional features by request.
|
||||
enhancements, additional features by request, and dedicated support.
|
||||
|
||||
|
||||
[**Pro Version**](http://sheetjs.com/pro)
|
||||
|
||||
@ -18,14 +19,30 @@ enhancements and additional features by request.
|
||||
|
||||
[**Source Code**](http://git.io/xlsx)
|
||||
|
||||
[**Issues and Bug Reports**](https://github.com/sheetjs/js-xlsx/issues)
|
||||
|
||||
[**Other General Support Issues**](https://discourse.sheetjs.com)
|
||||
|
||||
[**File format support for known spreadsheet data formats:**](#file-formats)
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
<details>
|
||||
<summary>Graph Legend</summary>
|
||||
<summary><b>Graph of supported formats</b> (click to show)</summary>
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
![graph legend](legend.png)
|
||||
|
||||
</details>
|
||||
|
||||
[**Browser Test**](http://oss.sheetjs.com/js-xlsx/tests/)
|
||||
|
||||
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
|
||||
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
|
||||
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
|
||||
[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
## Installation
|
||||
|
||||
In the browser, just add a script tag:
|
||||
|
||||
```html
|
||||
<script lang="javascript" src="dist/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
With [npm](https://www.npmjs.org/package/xlsx):
|
||||
|
||||
```bash
|
||||
$ npm install xlsx
|
||||
```
|
||||
|
||||
In the browser:
|
||||
|
||||
```html
|
||||
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
|
||||
```
|
||||
|
||||
With [bower](http://bower.io/search/?q=js-xlsx):
|
||||
|
||||
```bash
|
||||
|
35
docbits/15_phil.md
Normal file
35
docbits/15_phil.md
Normal file
@ -0,0 +1,35 @@
|
||||
## Philosophy
|
||||
|
||||
<details>
|
||||
<summary><b>Philosophy</b> (click to show)</summary>
|
||||
|
||||
Prior to SheetJS, APIs for processing spreadsheet files were format-specific.
|
||||
Third-party libraries either supported one format, or they involved a separate
|
||||
set of classes for each supported file type. Even though XLSB was introduced in
|
||||
Excel 2007, nothing outside of SheetJS or Excel supported the format.
|
||||
|
||||
To promote a format-agnostic view, js-xlsx starts from a pure-JS representation
|
||||
that we call the ["Common Spreadsheet Format"](#common-spreadsheet-format).
|
||||
Emphasizing a uniform object representation enables radical features like format
|
||||
conversion (e.g. reading an XLSX template and saving as XLS) and circumvents the
|
||||
"class trap". By abstracting the complexities of the various formats, tools
|
||||
need not worry about the specific file type!
|
||||
|
||||
A simple object representation combined with careful coding practices enables
|
||||
use cases in older browsers and in alternative environments like ExtendScript
|
||||
and Web Workers. It is always tempting to use the latest and greatest features,
|
||||
but they tend to require the latest versions of browsers, limiting usability.
|
||||
|
||||
Utility functions capture common use cases like generating JS objects or HTML.
|
||||
Most simple operations should only require a few lines of code. More complex
|
||||
operations generally should be straightforward to implement.
|
||||
|
||||
Excel pushes the XLSX format as default starting in Excel 2007. However, there
|
||||
are other formats with more appealing properties. For example, the XLSB format
|
||||
is spiritually similar to XLSX but files often tend up taking less than half the
|
||||
space and open much faster! Even though an XLSX writer is available, other
|
||||
format writers are available so users can take advantage of the unique
|
||||
characteristics of each format.
|
||||
|
||||
</details>
|
||||
|
@ -38,7 +38,6 @@ Utilities are available in the `XLSX.utils` object:
|
||||
**Exporting:**
|
||||
|
||||
- `sheet_to_json` converts a worksheet object to an array of JSON objects.
|
||||
`sheet_to_row_object_array` is an alias that will be removed in the future.
|
||||
- `sheet_to_csv` generates delimiter-separated-values output.
|
||||
- `sheet_to_formulae` generates a list of the formulae (with value fallbacks).
|
||||
|
||||
|
@ -15,17 +15,14 @@ at index 164. The following example creates a custom format from scratch:
|
||||
|
||||
```js
|
||||
var tbl = {};
|
||||
XLSX.SSF.init_table(tbl); // <-- load builtin formats
|
||||
tbl[164] = "\"T\"\ #0.00";
|
||||
var wb = {
|
||||
SSF: tbl,
|
||||
SheetNames: ["Sheet1"],
|
||||
Sheets: {
|
||||
Sheet1: {
|
||||
"!ref":"A1:C1",
|
||||
A1: { t:"n", v:10000 }, // <-- General format
|
||||
B1: { t:"n", v:10000, z: tbl[4] }, // <-- Builtin format
|
||||
C1: { t:"n", v:10000, z: tbl[164] } // <-- Custom format
|
||||
A1: { t:"n", v:10000 }, // <-- General format
|
||||
B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format
|
||||
C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ the output will be encoded in codepage `1200` and the BOM will be prepended.
|
||||
|
||||
### JSON
|
||||
|
||||
`XLSX.utils.sheet_to_json` and the alias `XLSX.utils.sheet_to_row_object_array`
|
||||
generate different types of JS objects. The function takes an options argument:
|
||||
`XLSX.utils.sheet_to_json` generates different types of JS objects. The function
|
||||
takes an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|
@ -61,6 +61,9 @@ $ open -a Chromium.app http://localhost:8000/stress.html
|
||||
|
||||
### Tested Environments
|
||||
|
||||
<details>
|
||||
<summary>(click to show)</summary>
|
||||
|
||||
- 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 (IE6-9 browsers require shims for interacting with client)
|
||||
- Chrome 24+
|
||||
@ -74,6 +77,8 @@ Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
|
||||
- <https://travis-ci.org/SheetJS/SheetJS.github.io> for XLS\* modules
|
||||
- <https://saucelabs.com/u/sheetjs> for XLS\* modules using Sauce Labs
|
||||
|
||||
</details>
|
||||
|
||||
### Test Files
|
||||
|
||||
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
|
||||
|
@ -1,17 +0,0 @@
|
||||
## Badges
|
||||
|
||||
[![Build Status](https://saucelabs.com/browser-matrix/sheetjs.svg)](https://saucelabs.com/u/sheetjs)
|
||||
|
||||
[![Build Status](https://travis-ci.org/SheetJS/js-xlsx.svg?branch=master)](https://travis-ci.org/SheetJS/js-xlsx)
|
||||
|
||||
[![Build Status](https://semaphoreci.com/api/v1/sheetjs/js-xlsx/branches/master/shields_badge.svg)](https://semaphoreci.com/sheetjs/js-xlsx)
|
||||
|
||||
[![Coverage Status](http://img.shields.io/coveralls/SheetJS/js-xlsx/master.svg)](https://coveralls.io/r/SheetJS/js-xlsx?branch=master)
|
||||
|
||||
[![NPM Downloads](https://img.shields.io/npm/dt/xlsx.svg)](https://npmjs.org/package/xlsx)
|
||||
|
||||
[![Dependencies Status](https://david-dm.org/sheetjs/js-xlsx/status.svg)](https://david-dm.org/sheetjs/js-xlsx)
|
||||
|
||||
[![ghit.me](https://ghit.me/badge.svg?repo=sheetjs/js-xlsx)](https://ghit.me/repo/sheetjs/js-xlsx)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
24
index.html
24
index.html
@ -54,6 +54,9 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
|
||||
<script src="xlsx.js"></script>
|
||||
<script>
|
||||
/*jshint browser:true */
|
||||
/* eslint-env browser */
|
||||
/* eslint no-use-before-define:0 */
|
||||
/*global Uint8Array, Uint16Array, ArrayBuffer */
|
||||
/*global XLSX */
|
||||
var X = XLSX;
|
||||
var XW = {
|
||||
@ -124,7 +127,7 @@ function xw_xfer(data, cb) {
|
||||
switch(e.data.t) {
|
||||
case 'ready': break;
|
||||
case 'e': console.error(e.data.d); break;
|
||||
default: xx=ab2str(e.data).replace(/\n/g,"\\n").replace(/\r/g,"\\r"); console.log("done"); cb(JSON.parse(xx)); break;
|
||||
default: var xx=ab2str(e.data).replace(/\n/g,"\\n").replace(/\r/g,"\\r"); console.log("done"); cb(JSON.parse(xx)); break;
|
||||
}
|
||||
};
|
||||
if(rABS) {
|
||||
@ -153,7 +156,7 @@ function get_radio_value( radioName ) {
|
||||
function to_json(workbook) {
|
||||
var result = {};
|
||||
workbook.SheetNames.forEach(function(sheetName) {
|
||||
var roa = X.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
|
||||
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
|
||||
if(roa.length > 0){
|
||||
result[sheetName] = roa;
|
||||
}
|
||||
@ -187,12 +190,12 @@ function to_formulae(workbook) {
|
||||
return result.join("\n");
|
||||
}
|
||||
|
||||
var HTMLOUT = document.getElementById('htmlout');
|
||||
function to_html(workbook) {
|
||||
document.getElementById('htmlout').innerHTML = "";
|
||||
var result = [];
|
||||
HTMLOUT.innerHTML = "";
|
||||
workbook.SheetNames.forEach(function(sheetName) {
|
||||
var htmlstr = X.write(workbook, {sheet:sheetName, type:'binary', bookType:'html'});
|
||||
document.getElementById('htmlout').innerHTML += htmlstr;
|
||||
HTMLOUT.innerHTML += htmlstr;
|
||||
});
|
||||
}
|
||||
|
||||
@ -202,7 +205,9 @@ function b64it() {
|
||||
var wb = X.read(tarea.value, {type: 'base64',WTF:wtf_mode});
|
||||
process_wb(wb);
|
||||
}
|
||||
window.b64it = b64it;
|
||||
|
||||
var OUT = document.getElementById('out');
|
||||
var global_wb;
|
||||
function process_wb(wb) {
|
||||
global_wb = wb;
|
||||
@ -218,11 +223,12 @@ function process_wb(wb) {
|
||||
default:
|
||||
output = to_csv(wb);
|
||||
}
|
||||
if(out.innerText === undefined) out.textContent = output;
|
||||
else out.innerText = output;
|
||||
if(OUT.innerText === undefined) OUT.textContent = output;
|
||||
else OUT.innerText = output;
|
||||
if(typeof console !== 'undefined') console.log("output", new Date());
|
||||
}
|
||||
function setfmt() {if(global_wb) process_wb(global_wb); }
|
||||
window.setfmt = setfmt;
|
||||
|
||||
var drop = document.getElementById('drop');
|
||||
function handleDrop(e) {
|
||||
@ -234,7 +240,7 @@ function handleDrop(e) {
|
||||
var f = files[0];
|
||||
{
|
||||
var reader = new FileReader();
|
||||
var name = f.name;
|
||||
//var name = f.name;
|
||||
reader.onload = function(e) {
|
||||
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
|
||||
var data = e.target.result;
|
||||
@ -277,7 +283,7 @@ function handleFile(e) {
|
||||
var f = files[0];
|
||||
{
|
||||
var reader = new FileReader();
|
||||
var name = f.name;
|
||||
//var name = f.name;
|
||||
reader.onload = function(e) {
|
||||
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
|
||||
var data = e.target.result;
|
||||
|
@ -5,6 +5,7 @@
|
||||
* [JS Ecosystem Demos](README.md#js-ecosystem-demos)
|
||||
* [Optional Modules](README.md#optional-modules)
|
||||
* [ECMAScript 5 Compatibility](README.md#ecmascript-5-compatibility)
|
||||
- [Philosophy](README.md#philosophy)
|
||||
- [Parsing Workbooks](README.md#parsing-workbooks)
|
||||
* [Complete Examples](README.md#complete-examples)
|
||||
* [Note on Streaming Read](README.md#note-on-streaming-read)
|
||||
@ -79,4 +80,3 @@
|
||||
* [Windows](README.md#windows)
|
||||
- [License](README.md#license)
|
||||
- [References](README.md#references)
|
||||
- [Badges](README.md#badges)
|
||||
|
21
misc/flow.js
21
misc/flow.js
@ -76,12 +76,23 @@ type SST = {
|
||||
|
||||
type Comment = any;
|
||||
|
||||
type ColInfo = {
|
||||
MDW?:number; // Excel's "Max Digit Width" unit, always integral
|
||||
width:number; // width in Excel's "Max Digit Width", width*256 is integral
|
||||
wpx?:number; // width in screen pixels
|
||||
wch?:number; // intermediate character calculation
|
||||
type RowInfo = {
|
||||
hidden:?boolean; // if true, the row is hidden
|
||||
|
||||
hpx?:number; // height in screen pixels
|
||||
hpt?:number; // height in points
|
||||
};
|
||||
|
||||
type ColInfo = {
|
||||
hidden:?boolean; // if true, the column is hidden
|
||||
|
||||
wpx?:number; // width in screen pixels
|
||||
width:number; // width in Excel's "Max Digit Width", width*256 is integral
|
||||
wch?:number; // width in characters
|
||||
|
||||
MDW?:number; // Excel's "Max Digit Width" unit, always integral
|
||||
};
|
||||
|
||||
|
||||
type AOA = Array<Array<any> >;
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.9.13",
|
||||
"version": "0.10.0",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ],
|
||||
@ -17,7 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"exit-on-epipe":"~1.0.0",
|
||||
"ssf":"~0.9.1",
|
||||
"ssf":"~0.9.2",
|
||||
"codepage":"~1.8.0",
|
||||
"cfb":"~0.11.1",
|
||||
"crc-32":"~1.0.2",
|
||||
|
13
test.js
13
test.js
@ -12,7 +12,7 @@ if(process.env.WTF) {
|
||||
opts.WTF = true;
|
||||
opts.cellStyles = true;
|
||||
}
|
||||
var fullex = [".xlsb", ".xlsm", ".xlsx"/*, ".xlml"*/];
|
||||
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml"*/];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml", "sylk", "dif"];
|
||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
|
||||
if(process.env.FMTS === "full") process.env.FMTS = ex.join(":");
|
||||
@ -1607,7 +1607,7 @@ describe('json output', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('csv output', function() {
|
||||
describe('csv', function() {
|
||||
var data, ws;
|
||||
var bef = (function() {
|
||||
data = [
|
||||
@ -1648,6 +1648,15 @@ describe('csv output', function() {
|
||||
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
|
||||
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
|
||||
});
|
||||
it('should handle various line endings', function() {
|
||||
var data = ["1,a", "2,b", "3,c"];
|
||||
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
|
||||
var wb = X.read(data.join(RS), {type:'binary'});
|
||||
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
|
||||
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
|
||||
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('js -> file -> js', function() {
|
||||
|
@ -9,7 +9,7 @@ var DIF_XL = true;
|
||||
|
||||
var opts = {cellNF: true};
|
||||
opts.type = "binary";
|
||||
var fullex = [".xlsb", ".xlsm", ".xlsx"/*, ".xlml"*/];
|
||||
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml"*/];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml", "sylk", "dif"];
|
||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
|
||||
var exp = ex.map(function(x){ return x + ".pending"; });
|
||||
@ -1005,7 +1005,7 @@ describe('parse features', function() {
|
||||
for(var i = 0; i < names.length; ++i) if(names[i].Name == "SheetJS") break;
|
||||
assert(i < names.length, "Missing name");
|
||||
assert.equal(names[i].Sheet, null);
|
||||
//assert.equal(names[i].Ref, "Sheet1!$A$1");
|
||||
assert.equal(names[i].Ref, "Sheet1!$A$1");
|
||||
if(m[2]) assert.equal(names[i].Comment, "defined names just suck excel formulae are bad MS should feel bad");
|
||||
|
||||
for(i = 0; i < names.length; ++i) if(names[i].Name == "SHEETjs") break;
|
||||
@ -1481,7 +1481,7 @@ describe('json output', function() {
|
||||
data = [
|
||||
[1,2,3],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo","bar", parseDate("2014-02-19T14:30:00.000Z"), "0.3"],
|
||||
["foo", "bar", parseDate("2014-02-19T14:30:00.000Z"), "0.3"],
|
||||
["baz", undefined, "qux"]
|
||||
];
|
||||
ws = X.utils.aoa_to_sheet(data);
|
||||
@ -1610,7 +1610,7 @@ describe('json output', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('csv output', function() {
|
||||
describe('csv', function() {
|
||||
var data, ws;
|
||||
var bef = (function() {
|
||||
data = [
|
||||
@ -1651,6 +1651,15 @@ describe('csv output', function() {
|
||||
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n";
|
||||
assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false}));
|
||||
});
|
||||
it('should handle various line endings', function() {
|
||||
var data = ["1,a", "2,b", "3,c"];
|
||||
[ "\r", "\n", "\r\n" ].forEach(function(RS) {
|
||||
var wb = X.read(data.join(RS), {type:'binary'});
|
||||
assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1);
|
||||
assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c");
|
||||
assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('js -> file -> js', function() {
|
||||
|
@ -46,7 +46,7 @@
|
||||
<script src="mocha.js"></script>
|
||||
<script>
|
||||
window.initMochaPhantomJS && window.initMochaPhantomJS();
|
||||
mocha.setup('bdd');
|
||||
mocha.setup({ui:'bdd', timeout:10000});
|
||||
</script>
|
||||
<script src="core.js"></script>
|
||||
<script>
|
||||
|
@ -76,8 +76,8 @@ ws['A3'].l = { Target: "http://sheetjs.com", Tooltip: "Visit us <SheetJS.com!>"
|
||||
ws['B1'].z = "0%"; // Format Code 9
|
||||
|
||||
/* TEST: custom format */
|
||||
wb.SSF = XLSX.SSF.get_table(); // <-- this will change in the future
|
||||
ws['C2'].z = "0.0"; wb.SSF[60] = "0.0"; // Custom
|
||||
var custfmt = "\"This is \"\\ 0.0";
|
||||
ws['C2'].z = custfmt;
|
||||
|
||||
/* TEST: page margins */
|
||||
ws['!margins'] = { left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5, footer:0.5 };
|
||||
@ -122,30 +122,29 @@ ws['!protect'] = {
|
||||
console.log("Worksheet Model:")
|
||||
console.log(ws);
|
||||
|
||||
/* write file */
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsx', {bookSST:true});
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsm');
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsb'); // no formula
|
||||
XLSX.writeFile(wb, 'sheetjs.xls', {bookType:'biff2'}); // no formula
|
||||
XLSX.writeFile(wb, 'sheetjs.xml.xls', {bookType:'xlml'});
|
||||
XLSX.writeFile(wb, 'sheetjs.ods');
|
||||
XLSX.writeFile(wb, 'sheetjs.fods');
|
||||
XLSX.writeFile(wb, 'sheetjs.slk');
|
||||
XLSX.writeFile(wb, 'sheetjs.csv');
|
||||
XLSX.writeFile(wb, 'sheetjs.txt');
|
||||
XLSX.writeFile(wb, 'sheetjs.prn');
|
||||
XLSX.writeFile(wb, 'sheetjs.dif');
|
||||
|
||||
/* test by reading back files */
|
||||
XLSX.readFile('sheetjs.xlsx');
|
||||
XLSX.readFile('sheetjs.xlsm');
|
||||
XLSX.readFile('sheetjs.xlsb');
|
||||
XLSX.readFile('sheetjs.xls');
|
||||
XLSX.readFile('sheetjs.xml.xls');
|
||||
XLSX.readFile('sheetjs.ods');
|
||||
XLSX.readFile('sheetjs.fods');
|
||||
XLSX.readFile('sheetjs.slk');
|
||||
XLSX.readFile('sheetjs.csv');
|
||||
XLSX.readFile('sheetjs.txt');
|
||||
XLSX.readFile('sheetjs.prn');
|
||||
XLSX.readFile('sheetjs.dif');
|
||||
[
|
||||
['sheetjs.xlsx', {bookSST:true}],
|
||||
'sheetjs.xlsm',
|
||||
'sheetjs.xlsb',
|
||||
['sheetjs.xls', {bookType:'biff2'}],
|
||||
['sheetjs.xml.xls', {bookType:'xlml'}],
|
||||
'sheetjs.ods',
|
||||
'sheetjs.fods',
|
||||
'sheetjs.slk',
|
||||
'sheetjs.csv',
|
||||
'sheetjs.txt',
|
||||
'sheetjs.prn',
|
||||
'sheetjs.dif'
|
||||
].forEach(function(r) {
|
||||
if(typeof r == 'string') {
|
||||
/* write file */
|
||||
XLSX.writeFile(wb, r);
|
||||
/* test by reading back files */
|
||||
XLSX.readFile(r);
|
||||
} else {
|
||||
/* write file */
|
||||
XLSX.writeFile(wb, r[0], r[1]);
|
||||
/* test by reading back files */
|
||||
XLSX.readFile(r[0]);
|
||||
}
|
||||
});
|
||||
|
1297
xlsx.flow.js
1297
xlsx.flow.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user