version bump 0.11.17: sheet_add_{aoa,json}
- Skip extraneous trailing records (fixes #938 h/t @benjaminleetmaa) - XLS -> XLML oddities (fixes #678 h/t @buserror) - ionic demo - sheet_add_aoa and sheet_add_json Issues: - fixes #947 h/t @fpasxos - fixes #666 h/t @samuelkavin - fixes #301 h/t @acgentry - fixes #561 h/t @Ideandro
This commit is contained in:
parent
a7d3779724
commit
1d74977718
143
README.md
143
README.md
|
@ -190,7 +190,7 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](demos/angular/)
|
||||
- [`angular 2.x / 4.x / 5.x`](demos/angular2/)
|
||||
- [`angular 2 / 4 / 5 and ionic`](demos/angular2/)
|
||||
- [`meteor`](demos/meteor/)
|
||||
- [`react and react-native`](demos/react/)
|
||||
- [`vue 2.x and weex`](demos/vue/)
|
||||
|
@ -721,6 +721,8 @@ Utilities are available in the `XLSX.utils` object and are described in the
|
|||
- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet.
|
||||
- `json_to_sheet` converts an array of JS objects to a worksheet.
|
||||
- `table_to_sheet` converts a DOM TABLE element to a worksheet.
|
||||
- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet.
|
||||
- `sheet_add_json` adds an array of JS objects to an existing worksheet.
|
||||
|
||||
|
||||
**Exporting:**
|
||||
|
@ -1742,6 +1744,61 @@ var ws = XLSX.utils.aoa_to_sheet([
|
|||
```
|
||||
</details>
|
||||
|
||||
`XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an
|
||||
existing worksheet object. It follows the same process as `aoa_to_sheet` and
|
||||
accepts an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Array of Objects Input
|
||||
|
||||
`XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet
|
||||
|
@ -1754,19 +1811,95 @@ default column order is determined by the first appearance of the field using
|
|||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
The original sheet cannot be reproduced because JS object keys must be unique.
|
||||
After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
The original sheet cannot be reproduced in the obvious way since JS object keys
|
||||
must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7},
|
||||
{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8}
|
||||
{ S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 },
|
||||
{ S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 }
|
||||
], {header:["S","h","e","e_1","t","J","S_1"]});
|
||||
```
|
||||
|
||||
Alternatively, the header row can be skipped:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" },
|
||||
{ A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 },
|
||||
{ A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 }
|
||||
], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
`XLSX.utils.sheet_add_json` takes an array of objects and updates an existing
|
||||
worksheet object. It follows the same process as `json_to_sheet` and accepts
|
||||
an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }
|
||||
], {skipHeader: true, origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }
|
||||
], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### HTML Table Input
|
||||
|
|
|
@ -1 +1 @@
|
|||
XLSX.version = '0.11.16';
|
||||
XLSX.version = '0.11.17';
|
||||
|
|
|
@ -62,11 +62,16 @@ function escapexml(text/*:string*/, xml/*:?boolean*/)/*:string*/{
|
|||
function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replace(/ /g,"_x0020_"); }
|
||||
|
||||
var htmlcharegex = /[\u0000-\u001f]/g;
|
||||
function escapehtml(text){
|
||||
function escapehtml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
|
||||
}
|
||||
|
||||
function escapexlml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
var xlml_fixstr/*:StringConv*/ = (function() {
|
||||
var entregex = /&#(\d+);/g;
|
||||
|
|
|
@ -5,8 +5,8 @@ function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:Cell
|
|||
if(out.cRel) out.c += tgt.s.c;
|
||||
if(out.rRel) out.r += tgt.s.r;
|
||||
} else {
|
||||
out.c += tgt.c;
|
||||
out.r += tgt.r;
|
||||
if(out.cRel) out.c += tgt.c;
|
||||
if(out.rRel) out.r += tgt.r;
|
||||
}
|
||||
if(!opts || opts.biff < 12) {
|
||||
while(out.c >= 0x100) out.c -= 0x100;
|
||||
|
|
|
@ -80,20 +80,38 @@ function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ {
|
|||
return { SheetNames: [n], Sheets: sheets };
|
||||
}
|
||||
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
||||
function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
|
||||
var dense = _ws ? Array.isArray(_ws) : o.dense;
|
||||
if(DENSE != null && dense == null) dense = DENSE;
|
||||
var ws/*:Worksheet*/ = _ws || (dense ? ([]/*:any*/) : ({}/*:any*/));
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var range/*:Range*/ = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}}/*:any*/);
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.s.c = _range.s.c;
|
||||
range.s.r = _range.s.r;
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) range.e.r = _R = _range.e.r + 1;
|
||||
}
|
||||
for(var R = 0; R != data.length; ++R) {
|
||||
for(var C = 0; C != data[R].length; ++C) {
|
||||
if(typeof data[R][C] === 'undefined') continue;
|
||||
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
|
||||
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
var __R = _R + R, __C = _C + C;
|
||||
if(range.s.r > __R) range.s.r = __R;
|
||||
if(range.s.c > __C) range.s.c = __C;
|
||||
if(range.e.r < __R) range.e.r = __R;
|
||||
if(range.e.c < __C) range.e.c = __C;
|
||||
if(cell.v === null) { if(cell.f) cell.t = 'n'; else if(!o.cellStubs) continue; else cell.t = 'z'; }
|
||||
else if(typeof cell.v === 'number') cell.t = 'n';
|
||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||
|
@ -103,11 +121,11 @@ function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
|||
else { cell.t = 'n'; cell.v = datenum(cell.v); cell.w = SSF.format(cell.z, cell.v); }
|
||||
}
|
||||
else cell.t = 's';
|
||||
if(o.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = cell;
|
||||
if(dense) {
|
||||
if(!ws[__R]) ws[__R] = [];
|
||||
ws[__R][__C] = cell;
|
||||
} else {
|
||||
var cell_ref = encode_cell(({c:C,r:R}/*:any*/));
|
||||
var cell_ref = encode_cell(({c:__C,r:__R}/*:any*/));
|
||||
ws[cell_ref] = cell;
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +133,5 @@ function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
|||
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ function xlml_write_custprops(Props, Custprops, opts) {
|
|||
if(Custprops) keys(Custprops).forEach(function(k) {
|
||||
/*:: if(!Custprops) return; */
|
||||
if(!Custprops.hasOwnProperty(k)) return;
|
||||
if(Props && Props.hasOwnProperty(k)) return;
|
||||
var m = Custprops[k];
|
||||
var t = "string";
|
||||
if(typeof m == 'number') { t = "float"; m = String(m); }
|
||||
|
|
|
@ -673,7 +673,7 @@ function parse_ShrFmla(blob, length, opts) {
|
|||
blob.l++;
|
||||
var cUse = blob.read_shift(1);
|
||||
length -= 8;
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse];
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
|
||||
}
|
||||
|
||||
/* 2.4.4 TODO */
|
||||
|
|
|
@ -62,10 +62,8 @@ function parse_DataSpaceDefinition(blob, length)/*:Array<string>*/ {
|
|||
function parse_TransformInfoHeader(blob, length) {
|
||||
var o = {};
|
||||
var len = blob.read_shift(4);
|
||||
var tgt = blob.l + len - 4;
|
||||
blob.l += 4; // must be 0x1
|
||||
o.id = blob.read_shift(0, 'lpp4');
|
||||
if(tgt != blob.l) throw new Error("Bad TransformInfoHeader record: " + blob.l + " != " + tgt);
|
||||
o.name = blob.read_shift(0, 'lpp4');
|
||||
o.R = parse_CRYPTOVersion(blob, 4);
|
||||
o.U = parse_CRYPTOVersion(blob, 4);
|
||||
|
|
|
@ -18,12 +18,13 @@ var rc_to_a1 = (function(){
|
|||
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
var a1_to_rc =(function(){
|
||||
return function a1_to_rc(fstr, base) {
|
||||
return function a1_to_rc(fstr/*:string*/, base/*:CellAddress*/) {
|
||||
return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
/* TODO: handle fixcol / fixrow */
|
||||
var c = decode_col($3) - base.c;
|
||||
var r = decode_row($5) - base.r;
|
||||
return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
|
||||
var c = decode_col($3) - ($2 ? 0 : base.c);
|
||||
var r = decode_row($5) - ($4 ? 0 : base.r);
|
||||
var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
|
||||
var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
|
||||
return $1 + "R" + R + "C" + C;
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -67,7 +67,7 @@ function parse_RgceLocRel(blob, length, opts) {
|
|||
if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
|
||||
var r = blob.read_shift(biff >= 12 ? 4 : 2);
|
||||
var cl = blob.read_shift(2);
|
||||
var cRel = (cl & 0x8000) >> 15, rRel = (cl & 0x4000) >> 14;
|
||||
var cRel = (cl & 0x4000) >> 14, rRel = (cl & 0x8000) >> 15;
|
||||
cl &= 0x3FFF;
|
||||
if(rRel == 1) while(r > 0x7FFFF) r -= 0x100000;
|
||||
if(cRel == 1) while(cl > 0x1FFF) cl = cl - 0x4000;
|
||||
|
@ -840,7 +840,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
|||
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);
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts);
|
||||
stack.push(encode_range_xls((r/*:any*/), opts));
|
||||
break;
|
||||
case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
|
||||
|
|
|
@ -334,7 +334,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
|||
var _NamedRange = parsexmltag(Rn[0]);
|
||||
var _DefinedName/*:DefinedName*/ = ({
|
||||
Name: _NamedRange.Name,
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1), {r:0, c:0})
|
||||
}/*:any*/);
|
||||
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
|
||||
/*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName);
|
||||
|
@ -864,6 +864,37 @@ function write_sty_xlml(wb, opts)/*:string*/ {
|
|||
});
|
||||
return writextag("Styles", styles.join(""));
|
||||
}
|
||||
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
|
||||
function write_names_xlml(wb, opts)/*:string*/ {
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
/*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
|
||||
var names/*:Array<any>*/ = wb.Workbook.Names;
|
||||
var out/*:Array<string>*/ = [];
|
||||
for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != null) continue;
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return writextag("Names", out.join(""));
|
||||
}
|
||||
function write_ws_xlml_names(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||
if(!ws) return "";
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
/*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
|
||||
var names/*:Array<any>*/ = wb.Workbook.Names;
|
||||
var out/*:Array<string>*/ = [];
|
||||
outer: for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != idx) continue;
|
||||
/*switch(n.Name) {
|
||||
case "_": continue;
|
||||
}*/
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return out.join("");
|
||||
}
|
||||
/* WorksheetOptions */
|
||||
function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||
if(!ws) return "";
|
||||
|
@ -982,7 +1013,7 @@ function write_ws_xlml_comment(comments/*:Array<any>*/)/*:string*/ {
|
|||
}).join("");
|
||||
}
|
||||
function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb, addr)/*:string*/{
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "";
|
||||
|
||||
var attr = {};
|
||||
if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
|
||||
|
@ -1012,11 +1043,12 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
|
|||
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
|
||||
case 'e': t = 'Error'; p = BErr[cell.v]; break;
|
||||
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || SSF._table[14]; break;
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
case 's': t = 'String'; p = escapexlml(cell.v||""); break;
|
||||
}
|
||||
/* TODO: cell style */
|
||||
var os = get_cell_style(opts.cellXfs, cell, opts);
|
||||
attr["ss:StyleID"] = "s" + (21+os);
|
||||
attr["ss:Index"] = addr.c + 1;
|
||||
var _v = (cell.v != null ? p : "");
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
|
@ -1076,8 +1108,11 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
|
|||
var s = wb.SheetNames[idx];
|
||||
var ws = wb.Sheets[s];
|
||||
|
||||
var t/*:string*/ = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Names>" + t + "</Names>");
|
||||
|
||||
/* Table */
|
||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||
|
||||
/* WorksheetOptions */
|
||||
|
@ -1100,9 +1135,11 @@ function write_xlml(wb, opts)/*:string*/ {
|
|||
d.push(write_props_xlml(wb, opts));
|
||||
d.push(write_wb_xlml(wb, opts));
|
||||
d.push("");
|
||||
d.push("");
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i)
|
||||
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
|
||||
d[2] = write_sty_xlml(wb, opts);
|
||||
d[3] = write_names_xlml(wb, opts);
|
||||
return XML_HEADER + writextag("Workbook", d.join(""), {
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
|
|
|
@ -105,7 +105,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
var cur_sheet = "";
|
||||
var Preamble = {};
|
||||
var lastcell, last_cell = "", cc, cmnt, rngC, rngR;
|
||||
var shared_formulae = {};
|
||||
var sharedf = {};
|
||||
var arrayf/*:Array<[Range, string]>*/ = [];
|
||||
var temp_val/*:Cell*/;
|
||||
var country;
|
||||
|
@ -144,13 +144,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
}
|
||||
if(options.cellFormula && line.f) {
|
||||
for(var afi = 0; afi < arrayf.length; ++afi) {
|
||||
if(arrayf[afi][0].s.c > cell.c) continue;
|
||||
if(arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c) continue;
|
||||
if(arrayf[afi][0].e.r < cell.r) continue;
|
||||
if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
|
||||
line.F = encode_range(arrayf[afi][0]);
|
||||
if(arrayf[afi][0].s.c != cell.c) delete line.f;
|
||||
if(arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
|
||||
break;
|
||||
}
|
||||
|
@ -167,7 +164,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
enc: false, // encrypted
|
||||
sbcch: 0, // cch in the preceding SupBook
|
||||
snames: [], // sheetnames
|
||||
sharedf: shared_formulae, // shared formulae by address
|
||||
sharedf: sharedf, // shared formulae by address
|
||||
arrayf: arrayf, // array formulae array
|
||||
rrtabid: [], // RRTabId
|
||||
lastuser: "", // Last User from WriteAccess
|
||||
|
@ -223,6 +220,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(R.n === 'EOF') val = R.f(blob, length, opts);
|
||||
else val = slurp(R, blob, length, opts);
|
||||
var Rn = R.n;
|
||||
if(file_depth == 0 && Rn != 'BOF') continue;
|
||||
/* nested switch statements to workaround V8 128 limit */
|
||||
switch(Rn) {
|
||||
/* Workbook Options */
|
||||
|
@ -253,16 +251,17 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
case 'RRTabId': opts.rrtabid = val; break;
|
||||
case 'WinProtect': opts.winlocked = val; break;
|
||||
case 'Template': break; // TODO
|
||||
case 'RefreshAll': wb.opts.RefreshAll = val; break;
|
||||
case 'BookBool': break; // TODO
|
||||
case 'UsesELFs': break;
|
||||
case 'MTRSettings': break;
|
||||
case 'CalcCount': wb.opts.CalcCount = val; break;
|
||||
case 'CalcDelta': wb.opts.CalcDelta = val; break;
|
||||
case 'CalcIter': wb.opts.CalcIter = val; break;
|
||||
case 'CalcMode': wb.opts.CalcMode = val; break;
|
||||
case 'CalcPrecision': wb.opts.CalcPrecision = val; break;
|
||||
case 'CalcSaveRecalc': wb.opts.CalcSaveRecalc = val; break;
|
||||
case 'RefreshAll':
|
||||
case 'CalcCount':
|
||||
case 'CalcDelta':
|
||||
case 'CalcIter':
|
||||
case 'CalcMode':
|
||||
case 'CalcPrecision':
|
||||
case 'CalcSaveRecalc':
|
||||
wb.opts[Rn] = val; break;
|
||||
case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1
|
||||
case 'Uncalced': break;
|
||||
case 'ForceFullCalculation': wb.opts.FullCalc = val; break;
|
||||
|
@ -404,7 +403,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
|
||||
var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
|
||||
var _fe = encode_cell({r:_fr, c:_fc});
|
||||
if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
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);
|
||||
}
|
||||
|
@ -444,7 +443,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(last_cell) {
|
||||
/* TODO: capture range */
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
shared_formulae[encode_cell(last_formula.cell)]= val[0];
|
||||
sharedf[encode_cell(last_formula.cell)]= val[0];
|
||||
cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
|
||||
(cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
|
||||
}
|
||||
|
|
|
@ -168,14 +168,29 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
|
|||
return cmds;
|
||||
}
|
||||
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
var ws = ({}/*:any*/);
|
||||
var offset = +!o.skipHeader;
|
||||
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var cell/*:Cell*/;
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/);
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}}/*:any*/);
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) { _R = range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
|
||||
}
|
||||
var hdr/*:Array<string>*/ = o.header || [], C = 0;
|
||||
|
||||
js.forEach(function (JS, R) {
|
||||
js.forEach(function (JS, R/*:number*/) {
|
||||
keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = JS[k];
|
||||
|
@ -189,15 +204,17 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
|||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v}/*:any*/);
|
||||
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v}/*:any*/);
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
});
|
||||
range.e.c = hdr.length - 1;
|
||||
for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]};
|
||||
range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
|
||||
var __R = encode_row(_R);
|
||||
if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { return sheet_add_json(null, js, opts); }
|
||||
|
||||
var utils/*:any*/ = {
|
||||
encode_col: encode_col,
|
||||
|
@ -214,6 +231,8 @@ var utils/*:any*/ = {
|
|||
make_csv: sheet_to_csv,
|
||||
make_json: sheet_to_json,
|
||||
make_formulae: sheet_to_formulae,
|
||||
sheet_add_aoa: sheet_add_aoa,
|
||||
sheet_add_json: sheet_add_json,
|
||||
aoa_to_sheet: aoa_to_sheet,
|
||||
json_to_sheet: json_to_sheet,
|
||||
table_to_sheet: parse_dom_table,
|
||||
|
|
|
@ -19,7 +19,7 @@ can be installed with Bash on Windows or with `cygwin`.
|
|||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](angular/)
|
||||
- [`angular 2.x / 4.x / 5.x`](angular2/)
|
||||
- [`angular 2 / 4 / 5 and ionic`](angular2/)
|
||||
- [`meteor`](meteor/)
|
||||
- [`react and react-native`](react/)
|
||||
- [`vue 2.x and weex`](vue/)
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
dist
|
||||
SheetJSIonic
|
||||
|
|
|
@ -21,3 +21,11 @@ angular:
|
|||
if [ ! -e node_modules/xlsx ]; then cd node_modules; ln -s ../../../ xlsx; cd -; fi
|
||||
ng build
|
||||
|
||||
.PHONY: ionic
|
||||
ionic:
|
||||
bash ./ionic.sh
|
||||
|
||||
.PHONY: ios android browser
|
||||
ios android browser: ionic
|
||||
cd SheetJSIonic; ionic cordova emulate $@ </dev/null; cd -
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ This demo uses an array of arrays (type `Array<Array<any>>`) as the core state.
|
|||
The component template includes a file input element, a table that updates with
|
||||
the data, and a button to export the data.
|
||||
|
||||
Other scripts in this demo show:
|
||||
- `ionic` deployment for iOS, android, and browser
|
||||
|
||||
## Array of Arrays
|
||||
|
||||
`Array<Array<any>>` neatly maps to a table with `ngFor`:
|
||||
|
@ -114,4 +117,39 @@ SystemJS.config({
|
|||
});
|
||||
```
|
||||
|
||||
## Ionic
|
||||
|
||||
<img src="screen.png" width="400px"/>
|
||||
|
||||
Reproducing the full project is a little bit tricky. The included `ionic.sh`
|
||||
script performs the necessary installation steps.
|
||||
|
||||
`Array<Array<any>>` neatly maps to a table with `ngFor`:
|
||||
|
||||
```html
|
||||
<ion-grid>
|
||||
<ion-row *ngFor="let row of data">
|
||||
<ion-col *ngFor="let val of row">
|
||||
{{val}}
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
```
|
||||
|
||||
|
||||
`@ionic-native/file` reads and writes files on devices. `readAsBinaryString`
|
||||
returns strings that can be parsed with the `binary` type, and `array` type can
|
||||
easily be converted to blobs that can be exported with `writeFile`:
|
||||
|
||||
```typescript
|
||||
/* read a workbook */
|
||||
const bstr: string = await this.file.readAsBinaryString(url, filename);
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
|
||||
/* write a workbook */
|
||||
const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
|
||||
let blob = new Blob([wbout], {type: 'application/octet-stream'});
|
||||
this.file.writeFile(url, filename, blob, {replace: true});
|
||||
```
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
if [ ! -e SheetJSIonic ]; then
|
||||
ionic start SheetJSIonic blank --cordova --no-git --no-link </dev/null
|
||||
cd SheetJSIonic
|
||||
ionic cordova platform add browser </dev/null
|
||||
ionic cordova platform add ios </dev/null
|
||||
ionic cordova plugin add cordova-plugin-file </dev/null
|
||||
npm install --save @ionic-native/file file-saver
|
||||
npm install --save xlsx
|
||||
|
||||
cp src/app/app.module.ts{,.bak}
|
||||
cat src/app/app.module.ts.bak | awk 'BEGIN{p=0} !/import/ && !p { ++p; print "import { File } from '"'"'@ionic-native/file'"'"';"; } 1; /providers: \[/ {print " File,"}' > src/app/app.module.ts
|
||||
cd -
|
||||
fi
|
||||
|
||||
cp ionic.ts SheetJSIonic/src/pages/home/home.ts
|
||||
rm -f SheetJSIonic/src/pages/home/home.html
|
|
@ -0,0 +1,109 @@
|
|||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
import { File } from '@ionic-native/file';
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
type AOA = any[][];
|
||||
|
||||
@Component({
|
||||
selector: 'page-home',
|
||||
template: `
|
||||
<ion-header><ion-navbar><ion-title>SheetJS Ionic Demo</ion-title></ion-navbar></ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-grid>
|
||||
<ion-row *ngFor="let row of data">
|
||||
<ion-col *ngFor="let val of row">
|
||||
{{val}}
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<input type="file" (change)="onFileChange($event)" multiple="false" />
|
||||
<button ion-button color="secondary" (click)="import()">Import Data</button>
|
||||
<button ion-button color="secondary" (click)="export()">Export Data</button>
|
||||
</ion-footer>
|
||||
`
|
||||
})
|
||||
|
||||
export class HomePage {
|
||||
data: any[][] = [[1,2,3],[4,5,6]];
|
||||
constructor(public file: File) {};
|
||||
|
||||
read(bstr: string) {
|
||||
/* read workbook */
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
|
||||
/* grab first sheet */
|
||||
const wsname: string = wb.SheetNames[0];
|
||||
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
|
||||
|
||||
/* save data */
|
||||
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
|
||||
};
|
||||
|
||||
write(): ArrayBuffer {
|
||||
/* generate worksheet */
|
||||
const ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(this.data);
|
||||
|
||||
/* generate workbook and add the worksheet */
|
||||
const wb: XLSX.WorkBook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
|
||||
|
||||
/* save to ArrayBuffer */
|
||||
const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
|
||||
return wbout;
|
||||
};
|
||||
|
||||
/* File Input element for browser */
|
||||
onFileChange(evt: any) {
|
||||
/* wire up file reader */
|
||||
const target: DataTransfer = <DataTransfer>(evt.target);
|
||||
if (target.files.length !== 1) throw new Error('Cannot use multiple files');
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onload = (e: any) => {
|
||||
const bstr: string = e.target.result;
|
||||
this.read(bstr);
|
||||
};
|
||||
reader.readAsBinaryString(target.files[0]);
|
||||
};
|
||||
|
||||
/* Import button for mobile */
|
||||
async import() {
|
||||
try {
|
||||
const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
|
||||
const dentry = await this.file.resolveDirectoryUrl(target);
|
||||
const url: string = dentry.nativeURL || '';
|
||||
alert(`Attempting to read SheetJSIonic.xlsx from ${url}`)
|
||||
const bstr: string = await this.file.readAsBinaryString(url, "SheetJSIonic.xlsx");
|
||||
this.read(bstr);
|
||||
} catch(e) {
|
||||
const m: string = e.message;
|
||||
alert(m.match(/It was determined/) ? "Use File Input control" : `Error: ${m}`);
|
||||
}
|
||||
};
|
||||
|
||||
/* Export button */
|
||||
async export() {
|
||||
const wbout: ArrayBuffer = this.write();
|
||||
const filename: string = "SheetJSIonic.xlsx";
|
||||
const blob: Blob = new Blob([wbout], {type: 'application/octet-stream'});
|
||||
try {
|
||||
const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
|
||||
const dentry = await this.file.resolveDirectoryUrl(target);
|
||||
const url: string = dentry.nativeURL || '';
|
||||
await this.file.writeFile(url, filename, blob, {replace: true});
|
||||
alert(`Wrote to SheetJSIonic.xlsx in ${url}`);
|
||||
} catch(e) {
|
||||
if(e.message.match(/It was determined/)) saveAs(blob, filename);
|
||||
else alert(`Error: ${e.message}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
|
@ -6,7 +6,7 @@ import * as XLSX from 'xlsx';
|
|||
|
||||
import { saveAs } from 'file-saver';
|
||||
|
||||
type AOA = Array<Array<any>>;
|
||||
type AOA = any[][];
|
||||
|
||||
@Component({
|
||||
selector: 'sheetjs',
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@
|
|||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.16';
|
||||
XLSX.version = '0.11.17';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
|
@ -2051,6 +2051,11 @@ function escapehtml(text){
|
|||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
|
||||
}
|
||||
|
||||
function escapexlml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
var xlml_fixstr = (function() {
|
||||
var entregex = /&#(\d+);/g;
|
||||
|
@ -2255,7 +2260,7 @@ function write_double_le(b, v, idx) {
|
|||
b[idx + 7] = (e >> 4) | bs;
|
||||
}
|
||||
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var __toBuffer = function(bufs) { var x=[],w=10240; for(var i=0;i<bufs[0].length;++i) for(var j=0,L=bufs[0][i].length;j<L;j+=w) x.push.apply(x, bufs[0][i].slice(j,j+w)); return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };
|
||||
var ___utf16le = __utf16le;
|
||||
|
@ -2538,8 +2543,8 @@ function shift_cell_xls(cell, tgt, opts) {
|
|||
if(out.cRel) out.c += tgt.s.c;
|
||||
if(out.rRel) out.r += tgt.s.r;
|
||||
} else {
|
||||
out.c += tgt.c;
|
||||
out.r += tgt.r;
|
||||
if(out.cRel) out.c += tgt.c;
|
||||
if(out.rRel) out.r += tgt.r;
|
||||
}
|
||||
if(!opts || opts.biff < 12) {
|
||||
while(out.c >= 0x100) out.c -= 0x100;
|
||||
|
@ -2689,20 +2694,38 @@ function sheet_to_workbook(sheet, opts) {
|
|||
return { SheetNames: [n], Sheets: sheets };
|
||||
}
|
||||
|
||||
function aoa_to_sheet(data, opts) {
|
||||
function sheet_add_aoa(_ws, data, opts) {
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var ws = o.dense ? ([]) : ({});
|
||||
var dense = _ws ? Array.isArray(_ws) : o.dense;
|
||||
if(DENSE != null && dense == null) dense = DENSE;
|
||||
var ws = _ws || (dense ? ([]) : ({}));
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var range = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}});
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.s.c = _range.s.c;
|
||||
range.s.r = _range.s.r;
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) range.e.r = _R = _range.e.r + 1;
|
||||
}
|
||||
for(var R = 0; R != data.length; ++R) {
|
||||
for(var C = 0; C != data[R].length; ++C) {
|
||||
if(typeof data[R][C] === 'undefined') continue;
|
||||
var cell = ({v: data[R][C] });
|
||||
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
var __R = _R + R, __C = _C + C;
|
||||
if(range.s.r > __R) range.s.r = __R;
|
||||
if(range.s.c > __C) range.s.c = __C;
|
||||
if(range.e.r < __R) range.e.r = __R;
|
||||
if(range.e.c < __C) range.e.c = __C;
|
||||
if(cell.v === null) { if(cell.f) cell.t = 'n'; else if(!o.cellStubs) continue; else cell.t = 'z'; }
|
||||
else if(typeof cell.v === 'number') cell.t = 'n';
|
||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||
|
@ -2712,11 +2735,11 @@ function aoa_to_sheet(data, opts) {
|
|||
else { cell.t = 'n'; cell.v = datenum(cell.v); cell.w = SSF.format(cell.z, cell.v); }
|
||||
}
|
||||
else cell.t = 's';
|
||||
if(o.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = cell;
|
||||
if(dense) {
|
||||
if(!ws[__R]) ws[__R] = [];
|
||||
ws[__R][__C] = cell;
|
||||
} else {
|
||||
var cell_ref = encode_cell(({c:C,r:R}));
|
||||
var cell_ref = encode_cell(({c:__C,r:__R}));
|
||||
ws[cell_ref] = cell;
|
||||
}
|
||||
}
|
||||
|
@ -2724,6 +2747,7 @@ function aoa_to_sheet(data, opts) {
|
|||
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
function write_UInt32LE(x, o) {
|
||||
if(!o) o = new_buf(4);
|
||||
|
@ -4047,6 +4071,7 @@ if(!Props.hasOwnProperty(k)) return;
|
|||
});
|
||||
if(Custprops) keys(Custprops).forEach(function(k) {
|
||||
if(!Custprops.hasOwnProperty(k)) return;
|
||||
if(Props && Props.hasOwnProperty(k)) return;
|
||||
var m = Custprops[k];
|
||||
var t = "string";
|
||||
if(typeof m == 'number') { t = "float"; m = String(m); }
|
||||
|
@ -5224,7 +5249,7 @@ function parse_ShrFmla(blob, length, opts) {
|
|||
blob.l++;
|
||||
var cUse = blob.read_shift(1);
|
||||
length -= 8;
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse];
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
|
||||
}
|
||||
|
||||
/* 2.4.4 TODO */
|
||||
|
@ -7097,10 +7122,8 @@ function parse_DataSpaceDefinition(blob, length) {
|
|||
function parse_TransformInfoHeader(blob, length) {
|
||||
var o = {};
|
||||
var len = blob.read_shift(4);
|
||||
var tgt = blob.l + len - 4;
|
||||
blob.l += 4; // must be 0x1
|
||||
o.id = blob.read_shift(0, 'lpp4');
|
||||
if(tgt != blob.l) throw new Error("Bad TransformInfoHeader record: " + blob.l + " != " + tgt);
|
||||
o.name = blob.read_shift(0, 'lpp4');
|
||||
o.R = parse_CRYPTOVersion(blob, 4);
|
||||
o.U = parse_CRYPTOVersion(blob, 4);
|
||||
|
@ -9089,10 +9112,11 @@ var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A
|
|||
var a1_to_rc =(function(){
|
||||
return function a1_to_rc(fstr, base) {
|
||||
return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
/* TODO: handle fixcol / fixrow */
|
||||
var c = decode_col($3) - base.c;
|
||||
var r = decode_row($5) - base.r;
|
||||
return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
|
||||
var c = decode_col($3) - ($2 ? 0 : base.c);
|
||||
var r = decode_row($5) - ($4 ? 0 : base.r);
|
||||
var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
|
||||
var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
|
||||
return $1 + "R" + R + "C" + C;
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
@ -9188,7 +9212,7 @@ function parse_RgceLocRel(blob, length, opts) {
|
|||
if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
|
||||
var r = blob.read_shift(biff >= 12 ? 4 : 2);
|
||||
var cl = blob.read_shift(2);
|
||||
var cRel = (cl & 0x8000) >> 15, rRel = (cl & 0x4000) >> 14;
|
||||
var cRel = (cl & 0x4000) >> 14, rRel = (cl & 0x8000) >> 15;
|
||||
cl &= 0x3FFF;
|
||||
if(rRel == 1) while(r > 0x7FFFF) r -= 0x100000;
|
||||
if(cRel == 1) while(cl > 0x1FFF) cl = cl - 0x4000;
|
||||
|
@ -9960,7 +9984,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
|||
case 'PtgErr': /* 2.5.198.57 */
|
||||
stack.push(f[1]); break;
|
||||
case 'PtgAreaN': /* 2.5.198.31 TODO */
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts);
|
||||
stack.push(encode_range_xls((r), opts));
|
||||
break;
|
||||
case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
|
||||
|
@ -14263,7 +14287,7 @@ for(var cma = c; cma <= cc; ++cma) {
|
|||
var _NamedRange = parsexmltag(Rn[0]);
|
||||
var _DefinedName = ({
|
||||
Name: _NamedRange.Name,
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1), {r:0, c:0})
|
||||
});
|
||||
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
|
||||
Workbook.Names.push(_DefinedName);
|
||||
|
@ -14791,6 +14815,35 @@ function write_sty_xlml(wb, opts) {
|
|||
});
|
||||
return writextag("Styles", styles.join(""));
|
||||
}
|
||||
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
|
||||
function write_names_xlml(wb, opts) {
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
var names = wb.Workbook.Names;
|
||||
var out = [];
|
||||
for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != null) continue;
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return writextag("Names", out.join(""));
|
||||
}
|
||||
function write_ws_xlml_names(ws, opts, idx, wb) {
|
||||
if(!ws) return "";
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
var names = wb.Workbook.Names;
|
||||
var out = [];
|
||||
outer: for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != idx) continue;
|
||||
/*switch(n.Name) {
|
||||
case "_": continue;
|
||||
}*/
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return out.join("");
|
||||
}
|
||||
/* WorksheetOptions */
|
||||
function write_ws_xlml_wsopts(ws, opts, idx, wb) {
|
||||
if(!ws) return "";
|
||||
|
@ -14909,7 +14962,7 @@ function write_ws_xlml_comment(comments) {
|
|||
}).join("");
|
||||
}
|
||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "";
|
||||
|
||||
var attr = {};
|
||||
if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
|
||||
|
@ -14939,11 +14992,12 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
|||
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
|
||||
case 'e': t = 'Error'; p = BErr[cell.v]; break;
|
||||
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || SSF._table[14]; break;
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
case 's': t = 'String'; p = escapexlml(cell.v||""); break;
|
||||
}
|
||||
/* TODO: cell style */
|
||||
var os = get_cell_style(opts.cellXfs, cell, opts);
|
||||
attr["ss:StyleID"] = "s" + (21+os);
|
||||
attr["ss:Index"] = addr.c + 1;
|
||||
var _v = (cell.v != null ? p : "");
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
|
@ -15003,8 +15057,11 @@ function write_ws_xlml(idx, opts, wb) {
|
|||
var s = wb.SheetNames[idx];
|
||||
var ws = wb.Sheets[s];
|
||||
|
||||
var t = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Names>" + t + "</Names>");
|
||||
|
||||
/* Table */
|
||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||
|
||||
/* WorksheetOptions */
|
||||
|
@ -15027,9 +15084,11 @@ function write_xlml(wb, opts) {
|
|||
d.push(write_props_xlml(wb, opts));
|
||||
d.push(write_wb_xlml(wb, opts));
|
||||
d.push("");
|
||||
d.push("");
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i)
|
||||
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
|
||||
d[2] = write_sty_xlml(wb, opts);
|
||||
d[3] = write_names_xlml(wb, opts);
|
||||
return XML_HEADER + writextag("Workbook", d.join(""), {
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
|
@ -15144,7 +15203,7 @@ function parse_workbook(blob, options) {
|
|||
var cur_sheet = "";
|
||||
var Preamble = {};
|
||||
var lastcell, last_cell = "", cc, cmnt, rngC, rngR;
|
||||
var shared_formulae = {};
|
||||
var sharedf = {};
|
||||
var arrayf = [];
|
||||
var temp_val;
|
||||
var country;
|
||||
|
@ -15183,13 +15242,10 @@ function parse_workbook(blob, options) {
|
|||
}
|
||||
if(options.cellFormula && line.f) {
|
||||
for(var afi = 0; afi < arrayf.length; ++afi) {
|
||||
if(arrayf[afi][0].s.c > cell.c) continue;
|
||||
if(arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c) continue;
|
||||
if(arrayf[afi][0].e.r < cell.r) continue;
|
||||
if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
|
||||
line.F = encode_range(arrayf[afi][0]);
|
||||
if(arrayf[afi][0].s.c != cell.c) delete line.f;
|
||||
if(arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
|
||||
break;
|
||||
}
|
||||
|
@ -15206,7 +15262,7 @@ function parse_workbook(blob, options) {
|
|||
enc: false, // encrypted
|
||||
sbcch: 0, // cch in the preceding SupBook
|
||||
snames: [], // sheetnames
|
||||
sharedf: shared_formulae, // shared formulae by address
|
||||
sharedf: sharedf, // shared formulae by address
|
||||
arrayf: arrayf, // array formulae array
|
||||
rrtabid: [], // RRTabId
|
||||
lastuser: "", // Last User from WriteAccess
|
||||
|
@ -15262,6 +15318,7 @@ function parse_workbook(blob, options) {
|
|||
if(R.n === 'EOF') val = R.f(blob, length, opts);
|
||||
else val = slurp(R, blob, length, opts);
|
||||
var Rn = R.n;
|
||||
if(file_depth == 0 && Rn != 'BOF') continue;
|
||||
/* nested switch statements to workaround V8 128 limit */
|
||||
switch(Rn) {
|
||||
/* Workbook Options */
|
||||
|
@ -15291,16 +15348,17 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
case 'RRTabId': opts.rrtabid = val; break;
|
||||
case 'WinProtect': opts.winlocked = val; break;
|
||||
case 'Template': break; // TODO
|
||||
case 'RefreshAll': wb.opts.RefreshAll = val; break;
|
||||
case 'BookBool': break; // TODO
|
||||
case 'UsesELFs': break;
|
||||
case 'MTRSettings': break;
|
||||
case 'CalcCount': wb.opts.CalcCount = val; break;
|
||||
case 'CalcDelta': wb.opts.CalcDelta = val; break;
|
||||
case 'CalcIter': wb.opts.CalcIter = val; break;
|
||||
case 'CalcMode': wb.opts.CalcMode = val; break;
|
||||
case 'CalcPrecision': wb.opts.CalcPrecision = val; break;
|
||||
case 'CalcSaveRecalc': wb.opts.CalcSaveRecalc = val; break;
|
||||
case 'RefreshAll':
|
||||
case 'CalcCount':
|
||||
case 'CalcDelta':
|
||||
case 'CalcIter':
|
||||
case 'CalcMode':
|
||||
case 'CalcPrecision':
|
||||
case 'CalcSaveRecalc':
|
||||
wb.opts[Rn] = val; break;
|
||||
case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1
|
||||
case 'Uncalced': break;
|
||||
case 'ForceFullCalculation': wb.opts.FullCalc = val; break;
|
||||
|
@ -15442,7 +15500,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
|
||||
var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
|
||||
var _fe = encode_cell({r:_fr, c:_fc});
|
||||
if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
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);
|
||||
}
|
||||
|
@ -15482,7 +15540,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
if(last_cell) {
|
||||
/* TODO: capture range */
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
shared_formulae[encode_cell(last_formula.cell)]= val[0];
|
||||
sharedf[encode_cell(last_formula.cell)]= val[0];
|
||||
cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
|
||||
(cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
|
||||
}
|
||||
|
@ -19217,11 +19275,26 @@ function sheet_to_formulae(sheet) {
|
|||
return cmds;
|
||||
}
|
||||
|
||||
function json_to_sheet(js, opts) {
|
||||
function sheet_add_json(_ws, js, opts) {
|
||||
var o = opts || {};
|
||||
var ws = ({});
|
||||
var offset = +!o.skipHeader;
|
||||
var ws = _ws || ({});
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var cell;
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}});
|
||||
var range = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}});
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) { _R = range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
|
||||
}
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
js.forEach(function (JS, R) {
|
||||
|
@ -19238,15 +19311,17 @@ function json_to_sheet(js, opts) {
|
|||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v});
|
||||
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v});
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
});
|
||||
range.e.c = hdr.length - 1;
|
||||
for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]};
|
||||
range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
|
||||
var __R = encode_row(_R);
|
||||
if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function json_to_sheet(js, opts) { return sheet_add_json(null, js, opts); }
|
||||
|
||||
var utils = {
|
||||
encode_col: encode_col,
|
||||
|
@ -19263,6 +19338,8 @@ var utils = {
|
|||
make_csv: sheet_to_csv,
|
||||
make_json: sheet_to_json,
|
||||
make_formulae: sheet_to_formulae,
|
||||
sheet_add_aoa: sheet_add_aoa,
|
||||
sheet_add_json: sheet_add_json,
|
||||
aoa_to_sheet: aoa_to_sheet,
|
||||
json_to_sheet: json_to_sheet,
|
||||
table_to_sheet: parse_dom_table,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](demos/angular/)
|
||||
- [`angular 2.x / 4.x / 5.x`](demos/angular2/)
|
||||
- [`angular 2 / 4 / 5 and ionic`](demos/angular2/)
|
||||
- [`meteor`](demos/meteor/)
|
||||
- [`react and react-native`](demos/react/)
|
||||
- [`vue 2.x and weex`](demos/vue/)
|
||||
|
|
|
@ -37,6 +37,8 @@ Utilities are available in the `XLSX.utils` object and are described in the
|
|||
- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet.
|
||||
- `json_to_sheet` converts an array of JS objects to a worksheet.
|
||||
- `table_to_sheet` converts a DOM TABLE element to a worksheet.
|
||||
- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet.
|
||||
- `sheet_add_json` adds an array of JS objects to an existing worksheet.
|
||||
|
||||
|
||||
**Exporting:**
|
||||
|
|
|
@ -42,6 +42,61 @@ var ws = XLSX.utils.aoa_to_sheet([
|
|||
```
|
||||
</details>
|
||||
|
||||
`XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an
|
||||
existing worksheet object. It follows the same process as `aoa_to_sheet` and
|
||||
accepts an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Array of Objects Input
|
||||
|
||||
`XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet
|
||||
|
@ -54,19 +109,95 @@ default column order is determined by the first appearance of the field using
|
|||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
The original sheet cannot be reproduced because JS object keys must be unique.
|
||||
After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
The original sheet cannot be reproduced in the obvious way since JS object keys
|
||||
must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7},
|
||||
{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8}
|
||||
{ S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 },
|
||||
{ S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 }
|
||||
], {header:["S","h","e","e_1","t","J","S_1"]});
|
||||
```
|
||||
|
||||
Alternatively, the header row can be skipped:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" },
|
||||
{ A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 },
|
||||
{ A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 }
|
||||
], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
`XLSX.utils.sheet_add_json` takes an array of objects and updates an existing
|
||||
worksheet object. It follows the same process as `json_to_sheet` and accepts
|
||||
an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>Examples</b> (click to show)</summary>
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }
|
||||
], {skipHeader: true, origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }
|
||||
], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### HTML Table Input
|
||||
|
|
|
@ -181,7 +181,7 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||
|
||||
**Frameworks and APIs**
|
||||
- [`angular 1.x`](demos/angular/)
|
||||
- [`angular 2.x / 4.x / 5.x`](demos/angular2/)
|
||||
- [`angular 2 / 4 / 5 and ionic`](demos/angular2/)
|
||||
- [`meteor`](demos/meteor/)
|
||||
- [`react and react-native`](demos/react/)
|
||||
- [`vue 2.x and weex`](demos/vue/)
|
||||
|
@ -658,6 +658,8 @@ Utilities are available in the `XLSX.utils` object and are described in the
|
|||
- `aoa_to_sheet` converts an array of arrays of JS data to a worksheet.
|
||||
- `json_to_sheet` converts an array of JS objects to a worksheet.
|
||||
- `table_to_sheet` converts a DOM TABLE element to a worksheet.
|
||||
- `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet.
|
||||
- `sheet_add_json` adds an array of JS objects to an existing worksheet.
|
||||
|
||||
|
||||
**Exporting:**
|
||||
|
@ -1604,6 +1606,58 @@ var ws = XLSX.utils.aoa_to_sheet([
|
|||
]);
|
||||
```
|
||||
|
||||
`XLSX.utils.sheet_add_aoa` takes an array of arrays of JS values and updates an
|
||||
existing worksheet object. It follows the same process as `aoa_to_sheet` and
|
||||
accepts an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`sheetStubs` | false | Create cell objects of type `z` for `null` values |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
```
|
||||
|
||||
|
||||
### Array of Objects Input
|
||||
|
||||
`XLSX.utils.json_to_sheet` takes an array of objects and returns a worksheet
|
||||
|
@ -1616,18 +1670,91 @@ default column order is determined by the first appearance of the field using
|
|||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|
||||
|
||||
The original sheet cannot be reproduced because JS object keys must be unique.
|
||||
After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
The original sheet cannot be reproduced in the obvious way since JS object keys
|
||||
must be unique. After replacing the second `e` and `S` with `e_1` and `S_1`:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7},
|
||||
{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8}
|
||||
{ S:1, h:2, e:3, e_1:4, t:5, J:6, S_1:7 },
|
||||
{ S:2, h:3, e:4, e_1:5, t:6, J:7, S_1:8 }
|
||||
], {header:["S","h","e","e_1","t","J","S_1"]});
|
||||
```
|
||||
|
||||
Alternatively, the header row can be skipped:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" },
|
||||
{ A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 },
|
||||
{ A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 }
|
||||
], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
```
|
||||
|
||||
|
||||
`XLSX.utils.sheet_add_json` takes an array of objects and updates an existing
|
||||
worksheet object. It follows the same process as `json_to_sheet` and accepts
|
||||
an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | :------: | :-------------------------------------------------- |
|
||||
|`header` | | Use specified column order (default `Object.keys`) |
|
||||
|`dateNF` | FMT 14 | Use specified date format in string output |
|
||||
|`cellDates` | false | Store dates as type `d` (default is `n`) |
|
||||
|`skipHeader` | false | If true, do not include header row in output |
|
||||
|`origin` | | Use specified cell as starting point (see below) |
|
||||
|
||||
`origin` is expected to be one of:
|
||||
|
||||
| `origin` | Description |
|
||||
| :--------------- | :-------------------------------------------------------- |
|
||||
| (cell object) | Use specified cell (cell object) |
|
||||
| (string) | Use specified cell (A1-style cell) |
|
||||
| (number >= 0) | Start from the first column at specified row (0-indexed) |
|
||||
| -1 | Append to bottom of worksheet starting on first column |
|
||||
| (default) | Start from cell A1 |
|
||||
|
||||
|
||||
|
||||
Consider the worksheet:
|
||||
|
||||
```
|
||||
XXX| A | B | C | D | E | F | G |
|
||||
---+---+---+---+---+---+---+---+
|
||||
1 | S | h | e | e | t | J | S |
|
||||
2 | 1 | 2 | | | 5 | 6 | 7 |
|
||||
3 | 2 | 3 | | | 6 | 7 | 8 |
|
||||
4 | 3 | 4 | | | 7 | 8 | 9 |
|
||||
5 | 4 | 5 | 6 | 7 | 8 | 9 | 0 |
|
||||
```
|
||||
|
||||
This worksheet can be built up in the order `A1:G1, A2:B4, E2:G4, A5:G5`:
|
||||
|
||||
```js
|
||||
/* Initial row */
|
||||
var ws = XLSX.utils.json_to_sheet([
|
||||
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});
|
||||
|
||||
/* Write data starting at A2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }
|
||||
], {skipHeader: true, origin: "A2"});
|
||||
|
||||
/* Write data starting at E2 */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }
|
||||
], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});
|
||||
|
||||
/* Append row */
|
||||
XLSX.utils.sheet_add_json(ws, [
|
||||
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});
|
||||
```
|
||||
|
||||
|
||||
### HTML Table Input
|
||||
|
||||
`XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.11.16",
|
||||
"version": "0.11.17",
|
||||
"author": "sheetjs",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [
|
||||
|
|
14
test.js
14
test.js
|
@ -675,6 +675,20 @@ describe('API', function() {
|
|||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
|
||||
eqarr(wb.SheetNames, ["A","Sheet1","Sheet2","B","Sheet3"]);
|
||||
});
|
||||
it('sheet_add_json', function() {
|
||||
var ws = X.utils.json_to_sheet([{A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S"}], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
X.utils.sheet_add_json(ws, [{A:1, B:2}, {A:2, B:3}, {A:3, B:4}], {skipHeader:true, origin:"A2"});
|
||||
X.utils.sheet_add_json(ws, [{A:5, B:6, C:7}, {A:6, B:7, C:8}, {A:7, B:8, C:9}], {skipHeader:true, origin:{r:1, c:4}, header:["A","B","C"]});
|
||||
X.utils.sheet_add_json(ws, [{A:4, B:5, C:6, D:7, E:8, F:9, G:0}], {header:["A","B","C","D","E","F","G"], skipHeader:true, origin:-1});
|
||||
assert.equal(X.utils.sheet_to_csv(ws).trim(), "S,h,e,e,t,J,S\n1,2,,,5,6,7\n2,3,,,6,7,8\n3,4,,,7,8,9\n4,5,6,7,8,9,0");
|
||||
});
|
||||
it('sheet_add_aoa', function() {
|
||||
var ws = X.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
X.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
X.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
X.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
assert.equal(X.utils.sheet_to_csv(ws).trim(), "S,h,e,e,t,J,S\n1,2,,,5,6,7\n2,3,,,6,7,8\n3,4,,,7,8,9\n4,5,6,7,8,9,0");
|
||||
});
|
||||
});
|
||||
|
||||
function coreprop(props) {
|
||||
|
|
|
@ -675,6 +675,20 @@ describe('API', function() {
|
|||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]));
|
||||
eqarr(wb.SheetNames, ["A","Sheet1","Sheet2","B","Sheet3"]);
|
||||
});
|
||||
it('sheet_add_json', function() {
|
||||
var ws = X.utils.json_to_sheet([{A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S"}], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
X.utils.sheet_add_json(ws, [{A:1, B:2}, {A:2, B:3}, {A:3, B:4}], {skipHeader:true, origin:"A2"});
|
||||
X.utils.sheet_add_json(ws, [{A:5, B:6, C:7}, {A:6, B:7, C:8}, {A:7, B:8, C:9}], {skipHeader:true, origin:{r:1, c:4}, header:["A","B","C"]});
|
||||
X.utils.sheet_add_json(ws, [{A:4, B:5, C:6, D:7, E:8, F:9, G:0}], {header:["A","B","C","D","E","F","G"], skipHeader:true, origin:-1});
|
||||
assert.equal(X.utils.sheet_to_csv(ws).trim(), "S,h,e,e,t,J,S\n1,2,,,5,6,7\n2,3,,,6,7,8\n3,4,,,7,8,9\n4,5,6,7,8,9,0");
|
||||
});
|
||||
it('sheet_add_aoa', function() {
|
||||
var ws = X.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
X.utils.sheet_add_aoa(ws, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
X.utils.sheet_add_aoa(ws, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
X.utils.sheet_add_aoa(ws, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
assert.equal(X.utils.sheet_to_csv(ws).trim(), "S,h,e,e,t,J,S\n1,2,,,5,6,7\n2,3,,,6,7,8\n3,4,,,7,8,9\n4,5,6,7,8,9,0");
|
||||
});
|
||||
});
|
||||
|
||||
function coreprop(props) {
|
||||
|
|
24
types/doc.ts
24
types/doc.ts
|
@ -64,6 +64,11 @@ const ws1 = XLSX.utils.aoa_to_sheet([
|
|||
sheetStubs: false
|
||||
});
|
||||
|
||||
const ws1b = XLSX.utils.aoa_to_sheet([ "SheetJS".split("") ]);
|
||||
XLSX.utils.sheet_add_aoa(ws1b, [[1,2], [2,3], [3,4]], {origin: "A2"});
|
||||
XLSX.utils.sheet_add_aoa(ws1b, [[5,6,7], [6,7,8], [7,8,9]], {origin:{r:1, c:4}});
|
||||
XLSX.utils.sheet_add_aoa(ws1b, [[4,5,6,7,8,9,0]], {origin: -1});
|
||||
|
||||
const ws2 = XLSX.utils.json_to_sheet([
|
||||
{S:1,h:2,e:3,e_1:4,t:5,J:6,S_1:7},
|
||||
{S:2,h:3,e:4,e_1:5,t:6,J:7,S_1:8}
|
||||
|
@ -73,6 +78,25 @@ const ws2 = XLSX.utils.json_to_sheet([
|
|||
dateNF: "yyyy-mm-dd"
|
||||
});
|
||||
|
||||
const ws2b = XLSX.utils.json_to_sheet([
|
||||
{ A:"S", B:"h", C:"e", D:"e", E:"t", F:"J", G:"S" },
|
||||
{ A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7 },
|
||||
{ A: 2, B: 3, C: 4, D: 5, E: 6, F: 7, G: 8 }
|
||||
], {header:["A","B","C","D","E","F","G"], skipHeader:true});
|
||||
|
||||
const ws2c = XLSX.utils.json_to_sheet([
|
||||
{ A: "S", B: "h", C: "e", D: "e", E: "t", F: "J", G: "S" }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true});
|
||||
XLSX.utils.sheet_add_json(ws2c, [
|
||||
{ A: 1, B: 2 }, { A: 2, B: 3 }, { A: 3, B: 4 }
|
||||
], {skipHeader: true, origin: "A2"});
|
||||
XLSX.utils.sheet_add_json(ws2c, [
|
||||
{ A: 5, B: 6, C: 7 }, { A: 6, B: 7, C: 8 }, { A: 7, B: 8, C: 9 }
|
||||
], {skipHeader: true, origin: { r: 1, c: 4 }, header: [ "A", "B", "C" ]});
|
||||
XLSX.utils.sheet_add_json(ws2c, [
|
||||
{ A: 4, B: 5, C: 6, D: 7, E: 8, F: 9, G: 0 }
|
||||
], {header: ["A", "B", "C", "D", "E", "F", "G"], skipHeader: true, origin: -1});
|
||||
|
||||
const tbl = {}; /* document.getElementById('table'); */
|
||||
const ws3 = XLSX.utils.table_to_sheet(tbl, {
|
||||
raw: true,
|
||||
|
|
|
@ -596,6 +596,11 @@ export interface Sheet2CSVOpts extends DateNFOption {
|
|||
skipHidden?: boolean;
|
||||
}
|
||||
|
||||
export interface OriginOption {
|
||||
/** Top-Left cell for operation (CellAddress or A1 string or row) */
|
||||
origin?: number | string | CellAddress;
|
||||
}
|
||||
|
||||
export interface Sheet2HTMLOpts {
|
||||
/** Add contenteditable to every cell */
|
||||
editable?: boolean;
|
||||
|
@ -632,11 +637,18 @@ export interface AOA2SheetOpts extends CommonOptions, DateNFOption {
|
|||
sheetStubs?: boolean;
|
||||
}
|
||||
|
||||
export interface SheetAOAOpts extends AOA2SheetOpts, OriginOption {}
|
||||
|
||||
export interface JSON2SheetOpts extends CommonOptions, DateNFOption {
|
||||
/** Use specified column order */
|
||||
header?: string[];
|
||||
|
||||
/** Skip header row in generated sheet */
|
||||
skipHeader?: boolean;
|
||||
}
|
||||
|
||||
export interface SheetJSONOpts extends JSON2SheetOpts, OriginOption {}
|
||||
|
||||
export interface Table2SheetOpts extends CommonOptions, DateNFOption {
|
||||
/* If true, plaintext parsing will not parse values */
|
||||
raw?: boolean;
|
||||
|
@ -739,6 +751,15 @@ export interface XLSX$Utils {
|
|||
/** Assign an Array Formula to a range */
|
||||
sheet_set_array_formula(ws: WorkSheet, range: Range|string, formula: string): WorkSheet;
|
||||
|
||||
/** Add an array of arrays of JS data to a worksheet */
|
||||
sheet_add_aoa<T>(ws: WorkSheet, data: T[][], opts?: SheetAOAOpts): WorkSheet;
|
||||
sheet_add_aoa(ws: WorkSheet, data: any[][], opts?: SheetAOAOpts): WorkSheet;
|
||||
|
||||
/** Add an array of JS objects to a worksheet */
|
||||
sheet_add_json(ws: WorkSheet, data: any[], opts?: SheetJSONOpts): WorkSheet;
|
||||
sheet_add_json<T>(ws: WorkSheet, data: T[], opts?: SheetJSONOpts): WorkSheet;
|
||||
|
||||
|
||||
consts: XLSX$Consts;
|
||||
}
|
||||
|
||||
|
|
185
xlsx.flow.js
185
xlsx.flow.js
|
@ -4,7 +4,7 @@
|
|||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.16';
|
||||
XLSX.version = '0.11.17';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
|
@ -2118,11 +2118,16 @@ function escapexml(text/*:string*/, xml/*:?boolean*/)/*:string*/{
|
|||
function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replace(/ /g,"_x0020_"); }
|
||||
|
||||
var htmlcharegex = /[\u0000-\u001f]/g;
|
||||
function escapehtml(text){
|
||||
function escapehtml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
|
||||
}
|
||||
|
||||
function escapexlml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
var xlml_fixstr/*:StringConv*/ = (function() {
|
||||
var entregex = /&#(\d+);/g;
|
||||
|
@ -2615,8 +2620,8 @@ function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:Cell
|
|||
if(out.cRel) out.c += tgt.s.c;
|
||||
if(out.rRel) out.r += tgt.s.r;
|
||||
} else {
|
||||
out.c += tgt.c;
|
||||
out.r += tgt.r;
|
||||
if(out.cRel) out.c += tgt.c;
|
||||
if(out.rRel) out.r += tgt.r;
|
||||
}
|
||||
if(!opts || opts.biff < 12) {
|
||||
while(out.c >= 0x100) out.c -= 0x100;
|
||||
|
@ -2772,20 +2777,38 @@ function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ {
|
|||
return { SheetNames: [n], Sheets: sheets };
|
||||
}
|
||||
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
||||
function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
|
||||
var dense = _ws ? Array.isArray(_ws) : o.dense;
|
||||
if(DENSE != null && dense == null) dense = DENSE;
|
||||
var ws/*:Worksheet*/ = _ws || (dense ? ([]/*:any*/) : ({}/*:any*/));
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var range/*:Range*/ = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}}/*:any*/);
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.s.c = _range.s.c;
|
||||
range.s.r = _range.s.r;
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) range.e.r = _R = _range.e.r + 1;
|
||||
}
|
||||
for(var R = 0; R != data.length; ++R) {
|
||||
for(var C = 0; C != data[R].length; ++C) {
|
||||
if(typeof data[R][C] === 'undefined') continue;
|
||||
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
|
||||
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
var __R = _R + R, __C = _C + C;
|
||||
if(range.s.r > __R) range.s.r = __R;
|
||||
if(range.s.c > __C) range.s.c = __C;
|
||||
if(range.e.r < __R) range.e.r = __R;
|
||||
if(range.e.c < __C) range.e.c = __C;
|
||||
if(cell.v === null) { if(cell.f) cell.t = 'n'; else if(!o.cellStubs) continue; else cell.t = 'z'; }
|
||||
else if(typeof cell.v === 'number') cell.t = 'n';
|
||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||
|
@ -2795,11 +2818,11 @@ function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
|||
else { cell.t = 'n'; cell.v = datenum(cell.v); cell.w = SSF.format(cell.z, cell.v); }
|
||||
}
|
||||
else cell.t = 's';
|
||||
if(o.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = cell;
|
||||
if(dense) {
|
||||
if(!ws[__R]) ws[__R] = [];
|
||||
ws[__R][__C] = cell;
|
||||
} else {
|
||||
var cell_ref = encode_cell(({c:C,r:R}/*:any*/));
|
||||
var cell_ref = encode_cell(({c:__C,r:__R}/*:any*/));
|
||||
ws[cell_ref] = cell;
|
||||
}
|
||||
}
|
||||
|
@ -2807,6 +2830,7 @@ function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
|
|||
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
function write_UInt32LE(x/*:number*/, o) {
|
||||
if(!o) o = new_buf(4);
|
||||
|
@ -4132,6 +4156,7 @@ function xlml_write_custprops(Props, Custprops, opts) {
|
|||
if(Custprops) keys(Custprops).forEach(function(k) {
|
||||
/*:: if(!Custprops) return; */
|
||||
if(!Custprops.hasOwnProperty(k)) return;
|
||||
if(Props && Props.hasOwnProperty(k)) return;
|
||||
var m = Custprops[k];
|
||||
var t = "string";
|
||||
if(typeof m == 'number') { t = "float"; m = String(m); }
|
||||
|
@ -5309,7 +5334,7 @@ function parse_ShrFmla(blob, length, opts) {
|
|||
blob.l++;
|
||||
var cUse = blob.read_shift(1);
|
||||
length -= 8;
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse];
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
|
||||
}
|
||||
|
||||
/* 2.4.4 TODO */
|
||||
|
@ -7184,10 +7209,8 @@ function parse_DataSpaceDefinition(blob, length)/*:Array<string>*/ {
|
|||
function parse_TransformInfoHeader(blob, length) {
|
||||
var o = {};
|
||||
var len = blob.read_shift(4);
|
||||
var tgt = blob.l + len - 4;
|
||||
blob.l += 4; // must be 0x1
|
||||
o.id = blob.read_shift(0, 'lpp4');
|
||||
if(tgt != blob.l) throw new Error("Bad TransformInfoHeader record: " + blob.l + " != " + tgt);
|
||||
o.name = blob.read_shift(0, 'lpp4');
|
||||
o.R = parse_CRYPTOVersion(blob, 4);
|
||||
o.U = parse_CRYPTOVersion(blob, 4);
|
||||
|
@ -9176,12 +9199,13 @@ var rc_to_a1 = (function(){
|
|||
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
var a1_to_rc =(function(){
|
||||
return function a1_to_rc(fstr, base) {
|
||||
return function a1_to_rc(fstr/*:string*/, base/*:CellAddress*/) {
|
||||
return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
/* TODO: handle fixcol / fixrow */
|
||||
var c = decode_col($3) - base.c;
|
||||
var r = decode_row($5) - base.r;
|
||||
return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
|
||||
var c = decode_col($3) - ($2 ? 0 : base.c);
|
||||
var r = decode_row($5) - ($4 ? 0 : base.r);
|
||||
var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
|
||||
var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
|
||||
return $1 + "R" + R + "C" + C;
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
@ -9277,7 +9301,7 @@ function parse_RgceLocRel(blob, length, opts) {
|
|||
if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
|
||||
var r = blob.read_shift(biff >= 12 ? 4 : 2);
|
||||
var cl = blob.read_shift(2);
|
||||
var cRel = (cl & 0x8000) >> 15, rRel = (cl & 0x4000) >> 14;
|
||||
var cRel = (cl & 0x4000) >> 14, rRel = (cl & 0x8000) >> 15;
|
||||
cl &= 0x3FFF;
|
||||
if(rRel == 1) while(r > 0x7FFFF) r -= 0x100000;
|
||||
if(cRel == 1) while(cl > 0x1FFF) cl = cl - 0x4000;
|
||||
|
@ -10050,7 +10074,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
|||
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);
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts);
|
||||
stack.push(encode_range_xls((r/*:any*/), opts));
|
||||
break;
|
||||
case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
|
||||
|
@ -14359,7 +14383,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
|||
var _NamedRange = parsexmltag(Rn[0]);
|
||||
var _DefinedName/*:DefinedName*/ = ({
|
||||
Name: _NamedRange.Name,
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1), {r:0, c:0})
|
||||
}/*:any*/);
|
||||
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
|
||||
/*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName);
|
||||
|
@ -14889,6 +14913,37 @@ function write_sty_xlml(wb, opts)/*:string*/ {
|
|||
});
|
||||
return writextag("Styles", styles.join(""));
|
||||
}
|
||||
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
|
||||
function write_names_xlml(wb, opts)/*:string*/ {
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
/*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
|
||||
var names/*:Array<any>*/ = wb.Workbook.Names;
|
||||
var out/*:Array<string>*/ = [];
|
||||
for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != null) continue;
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return writextag("Names", out.join(""));
|
||||
}
|
||||
function write_ws_xlml_names(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||
if(!ws) return "";
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
/*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
|
||||
var names/*:Array<any>*/ = wb.Workbook.Names;
|
||||
var out/*:Array<string>*/ = [];
|
||||
outer: for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != idx) continue;
|
||||
/*switch(n.Name) {
|
||||
case "_": continue;
|
||||
}*/
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return out.join("");
|
||||
}
|
||||
/* WorksheetOptions */
|
||||
function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||
if(!ws) return "";
|
||||
|
@ -15007,7 +15062,7 @@ function write_ws_xlml_comment(comments/*:Array<any>*/)/*:string*/ {
|
|||
}).join("");
|
||||
}
|
||||
function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb, addr)/*:string*/{
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "";
|
||||
|
||||
var attr = {};
|
||||
if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
|
||||
|
@ -15037,11 +15092,12 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
|
|||
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
|
||||
case 'e': t = 'Error'; p = BErr[cell.v]; break;
|
||||
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || SSF._table[14]; break;
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
case 's': t = 'String'; p = escapexlml(cell.v||""); break;
|
||||
}
|
||||
/* TODO: cell style */
|
||||
var os = get_cell_style(opts.cellXfs, cell, opts);
|
||||
attr["ss:StyleID"] = "s" + (21+os);
|
||||
attr["ss:Index"] = addr.c + 1;
|
||||
var _v = (cell.v != null ? p : "");
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
|
@ -15101,8 +15157,11 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
|
|||
var s = wb.SheetNames[idx];
|
||||
var ws = wb.Sheets[s];
|
||||
|
||||
var t/*:string*/ = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Names>" + t + "</Names>");
|
||||
|
||||
/* Table */
|
||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||
|
||||
/* WorksheetOptions */
|
||||
|
@ -15125,9 +15184,11 @@ function write_xlml(wb, opts)/*:string*/ {
|
|||
d.push(write_props_xlml(wb, opts));
|
||||
d.push(write_wb_xlml(wb, opts));
|
||||
d.push("");
|
||||
d.push("");
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i)
|
||||
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
|
||||
d[2] = write_sty_xlml(wb, opts);
|
||||
d[3] = write_names_xlml(wb, opts);
|
||||
return XML_HEADER + writextag("Workbook", d.join(""), {
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
|
@ -15244,7 +15305,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
var cur_sheet = "";
|
||||
var Preamble = {};
|
||||
var lastcell, last_cell = "", cc, cmnt, rngC, rngR;
|
||||
var shared_formulae = {};
|
||||
var sharedf = {};
|
||||
var arrayf/*:Array<[Range, string]>*/ = [];
|
||||
var temp_val/*:Cell*/;
|
||||
var country;
|
||||
|
@ -15283,13 +15344,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
}
|
||||
if(options.cellFormula && line.f) {
|
||||
for(var afi = 0; afi < arrayf.length; ++afi) {
|
||||
if(arrayf[afi][0].s.c > cell.c) continue;
|
||||
if(arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c) continue;
|
||||
if(arrayf[afi][0].e.r < cell.r) continue;
|
||||
if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
|
||||
line.F = encode_range(arrayf[afi][0]);
|
||||
if(arrayf[afi][0].s.c != cell.c) delete line.f;
|
||||
if(arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
|
||||
break;
|
||||
}
|
||||
|
@ -15306,7 +15364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
enc: false, // encrypted
|
||||
sbcch: 0, // cch in the preceding SupBook
|
||||
snames: [], // sheetnames
|
||||
sharedf: shared_formulae, // shared formulae by address
|
||||
sharedf: sharedf, // shared formulae by address
|
||||
arrayf: arrayf, // array formulae array
|
||||
rrtabid: [], // RRTabId
|
||||
lastuser: "", // Last User from WriteAccess
|
||||
|
@ -15362,6 +15420,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(R.n === 'EOF') val = R.f(blob, length, opts);
|
||||
else val = slurp(R, blob, length, opts);
|
||||
var Rn = R.n;
|
||||
if(file_depth == 0 && Rn != 'BOF') continue;
|
||||
/* nested switch statements to workaround V8 128 limit */
|
||||
switch(Rn) {
|
||||
/* Workbook Options */
|
||||
|
@ -15392,16 +15451,17 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
case 'RRTabId': opts.rrtabid = val; break;
|
||||
case 'WinProtect': opts.winlocked = val; break;
|
||||
case 'Template': break; // TODO
|
||||
case 'RefreshAll': wb.opts.RefreshAll = val; break;
|
||||
case 'BookBool': break; // TODO
|
||||
case 'UsesELFs': break;
|
||||
case 'MTRSettings': break;
|
||||
case 'CalcCount': wb.opts.CalcCount = val; break;
|
||||
case 'CalcDelta': wb.opts.CalcDelta = val; break;
|
||||
case 'CalcIter': wb.opts.CalcIter = val; break;
|
||||
case 'CalcMode': wb.opts.CalcMode = val; break;
|
||||
case 'CalcPrecision': wb.opts.CalcPrecision = val; break;
|
||||
case 'CalcSaveRecalc': wb.opts.CalcSaveRecalc = val; break;
|
||||
case 'RefreshAll':
|
||||
case 'CalcCount':
|
||||
case 'CalcDelta':
|
||||
case 'CalcIter':
|
||||
case 'CalcMode':
|
||||
case 'CalcPrecision':
|
||||
case 'CalcSaveRecalc':
|
||||
wb.opts[Rn] = val; break;
|
||||
case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1
|
||||
case 'Uncalced': break;
|
||||
case 'ForceFullCalculation': wb.opts.FullCalc = val; break;
|
||||
|
@ -15543,7 +15603,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
|
||||
var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
|
||||
var _fe = encode_cell({r:_fr, c:_fc});
|
||||
if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
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);
|
||||
}
|
||||
|
@ -15583,7 +15643,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||
if(last_cell) {
|
||||
/* TODO: capture range */
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
shared_formulae[encode_cell(last_formula.cell)]= val[0];
|
||||
sharedf[encode_cell(last_formula.cell)]= val[0];
|
||||
cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
|
||||
(cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
|
||||
}
|
||||
|
@ -19325,14 +19385,29 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
|
|||
return cmds;
|
||||
}
|
||||
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
||||
var o = opts || {};
|
||||
var ws = ({}/*:any*/);
|
||||
var offset = +!o.skipHeader;
|
||||
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var cell/*:Cell*/;
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:js.length}}/*:any*/);
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}}/*:any*/);
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) { _R = range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
|
||||
}
|
||||
var hdr/*:Array<string>*/ = o.header || [], C = 0;
|
||||
|
||||
js.forEach(function (JS, R) {
|
||||
js.forEach(function (JS, R/*:number*/) {
|
||||
keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) {
|
||||
if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
|
||||
var v = JS[k];
|
||||
|
@ -19346,15 +19421,17 @@ function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ {
|
|||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v}/*:any*/);
|
||||
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v}/*:any*/);
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
});
|
||||
range.e.c = hdr.length - 1;
|
||||
for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]};
|
||||
range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
|
||||
var __R = encode_row(_R);
|
||||
if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { return sheet_add_json(null, js, opts); }
|
||||
|
||||
var utils/*:any*/ = {
|
||||
encode_col: encode_col,
|
||||
|
@ -19371,6 +19448,8 @@ var utils/*:any*/ = {
|
|||
make_csv: sheet_to_csv,
|
||||
make_json: sheet_to_json,
|
||||
make_formulae: sheet_to_formulae,
|
||||
sheet_add_aoa: sheet_add_aoa,
|
||||
sheet_add_json: sheet_add_json,
|
||||
aoa_to_sheet: aoa_to_sheet,
|
||||
json_to_sheet: json_to_sheet,
|
||||
table_to_sheet: parse_dom_table,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.16';
|
||||
XLSX.version = '0.11.17';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
|
@ -2051,6 +2051,11 @@ function escapehtml(text){
|
|||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
|
||||
}
|
||||
|
||||
function escapexlml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
var xlml_fixstr = (function() {
|
||||
var entregex = /&#(\d+);/g;
|
||||
|
@ -2538,8 +2543,8 @@ function shift_cell_xls(cell, tgt, opts) {
|
|||
if(out.cRel) out.c += tgt.s.c;
|
||||
if(out.rRel) out.r += tgt.s.r;
|
||||
} else {
|
||||
out.c += tgt.c;
|
||||
out.r += tgt.r;
|
||||
if(out.cRel) out.c += tgt.c;
|
||||
if(out.rRel) out.r += tgt.r;
|
||||
}
|
||||
if(!opts || opts.biff < 12) {
|
||||
while(out.c >= 0x100) out.c -= 0x100;
|
||||
|
@ -2689,20 +2694,38 @@ function sheet_to_workbook(sheet, opts) {
|
|||
return { SheetNames: [n], Sheets: sheets };
|
||||
}
|
||||
|
||||
function aoa_to_sheet(data, opts) {
|
||||
function sheet_add_aoa(_ws, data, opts) {
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var ws = o.dense ? ([]) : ({});
|
||||
var dense = _ws ? Array.isArray(_ws) : o.dense;
|
||||
if(DENSE != null && dense == null) dense = DENSE;
|
||||
var ws = _ws || (dense ? ([]) : ({}));
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var range = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}});
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.s.c = _range.s.c;
|
||||
range.s.r = _range.s.r;
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) range.e.r = _R = _range.e.r + 1;
|
||||
}
|
||||
for(var R = 0; R != data.length; ++R) {
|
||||
for(var C = 0; C != data[R].length; ++C) {
|
||||
if(typeof data[R][C] === 'undefined') continue;
|
||||
var cell = ({v: data[R][C] });
|
||||
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
var __R = _R + R, __C = _C + C;
|
||||
if(range.s.r > __R) range.s.r = __R;
|
||||
if(range.s.c > __C) range.s.c = __C;
|
||||
if(range.e.r < __R) range.e.r = __R;
|
||||
if(range.e.c < __C) range.e.c = __C;
|
||||
if(cell.v === null) { if(cell.f) cell.t = 'n'; else if(!o.cellStubs) continue; else cell.t = 'z'; }
|
||||
else if(typeof cell.v === 'number') cell.t = 'n';
|
||||
else if(typeof cell.v === 'boolean') cell.t = 'b';
|
||||
|
@ -2712,11 +2735,11 @@ function aoa_to_sheet(data, opts) {
|
|||
else { cell.t = 'n'; cell.v = datenum(cell.v); cell.w = SSF.format(cell.z, cell.v); }
|
||||
}
|
||||
else cell.t = 's';
|
||||
if(o.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
ws[R][C] = cell;
|
||||
if(dense) {
|
||||
if(!ws[__R]) ws[__R] = [];
|
||||
ws[__R][__C] = cell;
|
||||
} else {
|
||||
var cell_ref = encode_cell(({c:C,r:R}));
|
||||
var cell_ref = encode_cell(({c:__C,r:__R}));
|
||||
ws[cell_ref] = cell;
|
||||
}
|
||||
}
|
||||
|
@ -2724,6 +2747,7 @@ function aoa_to_sheet(data, opts) {
|
|||
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
function write_UInt32LE(x, o) {
|
||||
if(!o) o = new_buf(4);
|
||||
|
@ -4047,6 +4071,7 @@ if(!Props.hasOwnProperty(k)) return;
|
|||
});
|
||||
if(Custprops) keys(Custprops).forEach(function(k) {
|
||||
if(!Custprops.hasOwnProperty(k)) return;
|
||||
if(Props && Props.hasOwnProperty(k)) return;
|
||||
var m = Custprops[k];
|
||||
var t = "string";
|
||||
if(typeof m == 'number') { t = "float"; m = String(m); }
|
||||
|
@ -5224,7 +5249,7 @@ function parse_ShrFmla(blob, length, opts) {
|
|||
blob.l++;
|
||||
var cUse = blob.read_shift(1);
|
||||
length -= 8;
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse];
|
||||
return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
|
||||
}
|
||||
|
||||
/* 2.4.4 TODO */
|
||||
|
@ -7097,10 +7122,8 @@ function parse_DataSpaceDefinition(blob, length) {
|
|||
function parse_TransformInfoHeader(blob, length) {
|
||||
var o = {};
|
||||
var len = blob.read_shift(4);
|
||||
var tgt = blob.l + len - 4;
|
||||
blob.l += 4; // must be 0x1
|
||||
o.id = blob.read_shift(0, 'lpp4');
|
||||
if(tgt != blob.l) throw new Error("Bad TransformInfoHeader record: " + blob.l + " != " + tgt);
|
||||
o.name = blob.read_shift(0, 'lpp4');
|
||||
o.R = parse_CRYPTOVersion(blob, 4);
|
||||
o.U = parse_CRYPTOVersion(blob, 4);
|
||||
|
@ -9089,10 +9112,11 @@ var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A
|
|||
var a1_to_rc =(function(){
|
||||
return function a1_to_rc(fstr, base) {
|
||||
return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
/* TODO: handle fixcol / fixrow */
|
||||
var c = decode_col($3) - base.c;
|
||||
var r = decode_row($5) - base.r;
|
||||
return $1 + "R" + (r == 0 ? "" : "[" + r + "]") + "C" + (c == 0 ? "" : "[" + c + "]");
|
||||
var c = decode_col($3) - ($2 ? 0 : base.c);
|
||||
var r = decode_row($5) - ($4 ? 0 : base.r);
|
||||
var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
|
||||
var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
|
||||
return $1 + "R" + R + "C" + C;
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
@ -9188,7 +9212,7 @@ function parse_RgceLocRel(blob, length, opts) {
|
|||
if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
|
||||
var r = blob.read_shift(biff >= 12 ? 4 : 2);
|
||||
var cl = blob.read_shift(2);
|
||||
var cRel = (cl & 0x8000) >> 15, rRel = (cl & 0x4000) >> 14;
|
||||
var cRel = (cl & 0x4000) >> 14, rRel = (cl & 0x8000) >> 15;
|
||||
cl &= 0x3FFF;
|
||||
if(rRel == 1) while(r > 0x7FFFF) r -= 0x100000;
|
||||
if(cRel == 1) while(cl > 0x1FFF) cl = cl - 0x4000;
|
||||
|
@ -9960,7 +9984,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
|||
case 'PtgErr': /* 2.5.198.57 */
|
||||
stack.push(f[1]); break;
|
||||
case 'PtgAreaN': /* 2.5.198.31 TODO */
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], _range, opts);
|
||||
type = f[1][0]; r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts);
|
||||
stack.push(encode_range_xls((r), opts));
|
||||
break;
|
||||
case 'PtgArea': /* 2.5.198.27 TODO: fixed points */
|
||||
|
@ -14263,7 +14287,7 @@ for(var cma = c; cma <= cc; ++cma) {
|
|||
var _NamedRange = parsexmltag(Rn[0]);
|
||||
var _DefinedName = ({
|
||||
Name: _NamedRange.Name,
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1))
|
||||
Ref: rc_to_a1(_NamedRange.RefersTo.substr(1), {r:0, c:0})
|
||||
});
|
||||
if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
|
||||
Workbook.Names.push(_DefinedName);
|
||||
|
@ -14791,6 +14815,35 @@ function write_sty_xlml(wb, opts) {
|
|||
});
|
||||
return writextag("Styles", styles.join(""));
|
||||
}
|
||||
function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
|
||||
function write_names_xlml(wb, opts) {
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
var names = wb.Workbook.Names;
|
||||
var out = [];
|
||||
for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != null) continue;
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return writextag("Names", out.join(""));
|
||||
}
|
||||
function write_ws_xlml_names(ws, opts, idx, wb) {
|
||||
if(!ws) return "";
|
||||
if(!((wb||{}).Workbook||{}).Names) return "";
|
||||
var names = wb.Workbook.Names;
|
||||
var out = [];
|
||||
outer: for(var i = 0; i < names.length; ++i) {
|
||||
var n = names[i];
|
||||
if(n.Sheet != idx) continue;
|
||||
/*switch(n.Name) {
|
||||
case "_": continue;
|
||||
}*/
|
||||
if(n.Name.match(/^_xlfn\./)) continue;
|
||||
out.push(write_name_xlml(n));
|
||||
}
|
||||
return out.join("");
|
||||
}
|
||||
/* WorksheetOptions */
|
||||
function write_ws_xlml_wsopts(ws, opts, idx, wb) {
|
||||
if(!ws) return "";
|
||||
|
@ -14909,7 +14962,7 @@ function write_ws_xlml_comment(comments) {
|
|||
}).join("");
|
||||
}
|
||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||
if(!cell || cell.v == undefined && cell.f == undefined) return "";
|
||||
|
||||
var attr = {};
|
||||
if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
|
||||
|
@ -14939,11 +14992,12 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
|||
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
|
||||
case 'e': t = 'Error'; p = BErr[cell.v]; break;
|
||||
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || SSF._table[14]; break;
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
case 's': t = 'String'; p = escapexlml(cell.v||""); break;
|
||||
}
|
||||
/* TODO: cell style */
|
||||
var os = get_cell_style(opts.cellXfs, cell, opts);
|
||||
attr["ss:StyleID"] = "s" + (21+os);
|
||||
attr["ss:Index"] = addr.c + 1;
|
||||
var _v = (cell.v != null ? p : "");
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
|
@ -15003,8 +15057,11 @@ function write_ws_xlml(idx, opts, wb) {
|
|||
var s = wb.SheetNames[idx];
|
||||
var ws = wb.Sheets[s];
|
||||
|
||||
var t = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Names>" + t + "</Names>");
|
||||
|
||||
/* Table */
|
||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||
|
||||
/* WorksheetOptions */
|
||||
|
@ -15027,9 +15084,11 @@ function write_xlml(wb, opts) {
|
|||
d.push(write_props_xlml(wb, opts));
|
||||
d.push(write_wb_xlml(wb, opts));
|
||||
d.push("");
|
||||
d.push("");
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i)
|
||||
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
|
||||
d[2] = write_sty_xlml(wb, opts);
|
||||
d[3] = write_names_xlml(wb, opts);
|
||||
return XML_HEADER + writextag("Workbook", d.join(""), {
|
||||
'xmlns': XLMLNS.ss,
|
||||
'xmlns:o': XLMLNS.o,
|
||||
|
@ -15144,7 +15203,7 @@ function parse_workbook(blob, options) {
|
|||
var cur_sheet = "";
|
||||
var Preamble = {};
|
||||
var lastcell, last_cell = "", cc, cmnt, rngC, rngR;
|
||||
var shared_formulae = {};
|
||||
var sharedf = {};
|
||||
var arrayf = [];
|
||||
var temp_val;
|
||||
var country;
|
||||
|
@ -15183,13 +15242,10 @@ function parse_workbook(blob, options) {
|
|||
}
|
||||
if(options.cellFormula && line.f) {
|
||||
for(var afi = 0; afi < arrayf.length; ++afi) {
|
||||
if(arrayf[afi][0].s.c > cell.c) continue;
|
||||
if(arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c) continue;
|
||||
if(arrayf[afi][0].e.r < cell.r) continue;
|
||||
if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
|
||||
if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
|
||||
line.F = encode_range(arrayf[afi][0]);
|
||||
if(arrayf[afi][0].s.c != cell.c) delete line.f;
|
||||
if(arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
|
||||
if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
|
||||
break;
|
||||
}
|
||||
|
@ -15206,7 +15262,7 @@ function parse_workbook(blob, options) {
|
|||
enc: false, // encrypted
|
||||
sbcch: 0, // cch in the preceding SupBook
|
||||
snames: [], // sheetnames
|
||||
sharedf: shared_formulae, // shared formulae by address
|
||||
sharedf: sharedf, // shared formulae by address
|
||||
arrayf: arrayf, // array formulae array
|
||||
rrtabid: [], // RRTabId
|
||||
lastuser: "", // Last User from WriteAccess
|
||||
|
@ -15262,6 +15318,7 @@ function parse_workbook(blob, options) {
|
|||
if(R.n === 'EOF') val = R.f(blob, length, opts);
|
||||
else val = slurp(R, blob, length, opts);
|
||||
var Rn = R.n;
|
||||
if(file_depth == 0 && Rn != 'BOF') continue;
|
||||
/* nested switch statements to workaround V8 128 limit */
|
||||
switch(Rn) {
|
||||
/* Workbook Options */
|
||||
|
@ -15291,16 +15348,17 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
case 'RRTabId': opts.rrtabid = val; break;
|
||||
case 'WinProtect': opts.winlocked = val; break;
|
||||
case 'Template': break; // TODO
|
||||
case 'RefreshAll': wb.opts.RefreshAll = val; break;
|
||||
case 'BookBool': break; // TODO
|
||||
case 'UsesELFs': break;
|
||||
case 'MTRSettings': break;
|
||||
case 'CalcCount': wb.opts.CalcCount = val; break;
|
||||
case 'CalcDelta': wb.opts.CalcDelta = val; break;
|
||||
case 'CalcIter': wb.opts.CalcIter = val; break;
|
||||
case 'CalcMode': wb.opts.CalcMode = val; break;
|
||||
case 'CalcPrecision': wb.opts.CalcPrecision = val; break;
|
||||
case 'CalcSaveRecalc': wb.opts.CalcSaveRecalc = val; break;
|
||||
case 'RefreshAll':
|
||||
case 'CalcCount':
|
||||
case 'CalcDelta':
|
||||
case 'CalcIter':
|
||||
case 'CalcMode':
|
||||
case 'CalcPrecision':
|
||||
case 'CalcSaveRecalc':
|
||||
wb.opts[Rn] = val; break;
|
||||
case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1
|
||||
case 'Uncalced': break;
|
||||
case 'ForceFullCalculation': wb.opts.FullCalc = val; break;
|
||||
|
@ -15442,7 +15500,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
|
||||
var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
|
||||
var _fe = encode_cell({r:_fr, c:_fc});
|
||||
if(shared_formulae[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
|
||||
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);
|
||||
}
|
||||
|
@ -15482,7 +15540,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
if(last_cell) {
|
||||
/* TODO: capture range */
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
shared_formulae[encode_cell(last_formula.cell)]= val[0];
|
||||
sharedf[encode_cell(last_formula.cell)]= val[0];
|
||||
cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
|
||||
(cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
|
||||
}
|
||||
|
@ -19217,11 +19275,26 @@ function sheet_to_formulae(sheet) {
|
|||
return cmds;
|
||||
}
|
||||
|
||||
function json_to_sheet(js, opts) {
|
||||
function sheet_add_json(_ws, js, opts) {
|
||||
var o = opts || {};
|
||||
var ws = ({});
|
||||
var offset = +!o.skipHeader;
|
||||
var ws = _ws || ({});
|
||||
var _R = 0, _C = 0;
|
||||
if(ws && o.origin != null) {
|
||||
if(typeof o.origin == 'number') _R = o.origin;
|
||||
else {
|
||||
var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
}
|
||||
var cell;
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:js.length}});
|
||||
var range = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}});
|
||||
if(ws['!ref']) {
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) { _R = range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
|
||||
}
|
||||
var hdr = o.header || [], C = 0;
|
||||
|
||||
js.forEach(function (JS, R) {
|
||||
|
@ -19238,15 +19311,17 @@ function json_to_sheet(js, opts) {
|
|||
if(!o.cellDates) { t = 'n'; v = datenum(v); }
|
||||
z = o.dateNF || SSF._table[14];
|
||||
}
|
||||
ws[encode_cell({c:C,r:R+1})] = cell = ({t:t, v:v});
|
||||
ws[encode_cell({c:_C + C,r:_R + R + offset})] = cell = ({t:t, v:v});
|
||||
if(z) cell.z = z;
|
||||
});
|
||||
});
|
||||
range.e.c = hdr.length - 1;
|
||||
for(C = 0; C < hdr.length; ++C) ws[encode_col(C) + "1"] = {t:'s', v:hdr[C]};
|
||||
range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
|
||||
var __R = encode_row(_R);
|
||||
if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
|
||||
ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function json_to_sheet(js, opts) { return sheet_add_json(null, js, opts); }
|
||||
|
||||
var utils = {
|
||||
encode_col: encode_col,
|
||||
|
@ -19263,6 +19338,8 @@ var utils = {
|
|||
make_csv: sheet_to_csv,
|
||||
make_json: sheet_to_json,
|
||||
make_formulae: sheet_to_formulae,
|
||||
sheet_add_aoa: sheet_add_aoa,
|
||||
sheet_add_json: sheet_add_json,
|
||||
aoa_to_sheet: aoa_to_sheet,
|
||||
json_to_sheet: json_to_sheet,
|
||||
table_to_sheet: parse_dom_table,
|
||||
|
|
Loading…
Reference in New Issue