forked from sheetjs/sheetjs
version bump 0.18.5: basic NUMBERS write
This commit is contained in:
parent
e69ecd42a6
commit
0400a87e62
13
CHANGELOG.md
13
CHANGELOG.md
@ -4,7 +4,20 @@ This log is intended to keep track of backwards-incompatible changes, including
|
||||
but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
## v0.18.5
|
||||
|
||||
* Enabled `sideEffects: false` in package.json
|
||||
* Basic NUMBERS write support
|
||||
|
||||
## v0.18.4
|
||||
|
||||
* CSV output omits trailing record separator
|
||||
* Properly terminate NodeJS Streams
|
||||
* DBF preserve column types on import and use when applicable on export
|
||||
|
||||
## v0.18.3
|
||||
|
||||
* Removed references to `require` and `process` in browser builds
|
||||
|
||||
## v0.18.2
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -95,6 +95,8 @@ dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
|
||||
misc/strip_sourcemap.sh dist/$(LIB).mini.min.js
|
||||
@# extendscript
|
||||
cat <(head -n 1 bits/00_header.js) shim.js $(DISTHDR) $(REQS) dist/$(TARGET) > dist/$(LIB).extendscript.js
|
||||
@# zahl
|
||||
cp modules/xlsx.zahl.js modules/xlsx.zahl.mjs dist/
|
||||
@#
|
||||
rm dist/$(TARGET) dist/$(MINITGT)
|
||||
|
||||
|
63
README.md
63
README.md
@ -1764,6 +1764,61 @@ stream.pipe(conv); conv.pipe(process.stdout);
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Exporting NUMBERS files</b> (click to show)</summary>
|
||||
|
||||
The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl`
|
||||
scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS
|
||||
use, while `xlsx.zahl.mjs` is suitable for ESM.
|
||||
|
||||
_Browser_
|
||||
|
||||
```html
|
||||
<meta charset="utf8">
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script src="xlsx.zahl.js"></script>
|
||||
<script>
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
</script>
|
||||
```
|
||||
|
||||
_Node_
|
||||
|
||||
```js
|
||||
var XLSX = require("./xlsx.flow");
|
||||
var XLSX_ZAHL = require("./dist/xlsx.zahl");
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
_Deno_
|
||||
|
||||
```ts
|
||||
import * as XLSX from './xlsx.mjs';
|
||||
import XLSX_ZAHL from './dist/xlsx.zahl.mjs';
|
||||
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.
|
||||
|
||||
### Generating JSON and JS Data
|
||||
@ -3366,6 +3421,7 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
|`Props` | | Override workbook properties when writing ** |
|
||||
|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** |
|
||||
|`ignoreEC` | `true` | Suppress "number as text" errors ** |
|
||||
|`numbers` | | Payload for NUMBERS export ** |
|
||||
|
||||
- `bookSST` is slower and more memory intensive, but has better compatibility
|
||||
with older versions of iOS Numbers
|
||||
@ -3381,6 +3437,8 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
- Due to a bug in the program, some features like "Text to Columns" will crash
|
||||
Excel on worksheets where error conditions are ignored. The writer will mark
|
||||
files to ignore the error by default. Set `ignoreEC` to `false` to suppress.
|
||||
- Due to the size of the data, the NUMBERS data is not included by default. The
|
||||
included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data.
|
||||
|
||||
### Supported Output Formats
|
||||
|
||||
@ -3398,6 +3456,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) |
|
||||
@ -3950,7 +4009,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Lotus Formatted Text (PRN) | ✔ | ✔ |
|
||||
| UTF-16 Unicode Text (TXT) | ✔ | ✔ |
|
||||
| **Other Workbook/Worksheet Formats** |:-----:|:-----:|
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | |
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | ✔ |
|
||||
| OpenDocument Spreadsheet (ODS) | ✔ | ✔ |
|
||||
| Flat XML ODF Spreadsheet (FODS) | ✔ | ✔ |
|
||||
| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | ✔ | |
|
||||
@ -4099,6 +4158,8 @@ The parser focuses on extracting raw data from tables. Numbers technically
|
||||
supports multiple tables in a logical worksheet, including custom titles. This
|
||||
parser will generate one worksheet per Numbers table.
|
||||
|
||||
The writer currently exports a small range from the first worksheet.
|
||||
|
||||
- **OpenDocument Spreadsheet (ODS/FODS)**
|
||||
|
||||
ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
||||
|
@ -44,6 +44,7 @@ program
|
||||
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
|
||||
.option('--wk3', 'emit WK3 to <sheetname> or <file>.txt (Lotus WK3)')
|
||||
.option('--numbers', 'emit NUMBERS to <sheetname> or <file>.numbers')
|
||||
|
||||
.option('-S, --formulae', 'emit list of values and formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
@ -90,6 +91,7 @@ var workbook_formats = [
|
||||
['xls', 'xls', 'xls'],
|
||||
['xla', 'xla', 'xla'],
|
||||
['biff5', 'biff5', 'xls'],
|
||||
['numbers', 'numbers', 'numbers'],
|
||||
['ods', 'ods', 'ods'],
|
||||
['fods', 'fods', 'fods'],
|
||||
['wk3', 'wk3', 'wk3']
|
||||
@ -192,6 +194,10 @@ if(program.props) {
|
||||
/* full workbook formats */
|
||||
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
|
||||
wopts.bookType = m[1];
|
||||
if(wopts.bookType == "numbers") try {
|
||||
var XLSX_ZAHL = require("../dist/xlsx.zahl");
|
||||
wopts.numbers = XLSX_ZAHL;
|
||||
} catch(e) {}
|
||||
if(wb) X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m[2]), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.18.4';
|
||||
XLSX.version = '0.18.5';
|
||||
|
@ -5,6 +5,19 @@ function u8_to_dataview(array) {
|
||||
function u8str(u8) {
|
||||
return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
|
||||
}
|
||||
function stru8(str) {
|
||||
return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
|
||||
}
|
||||
function u8contains(body, search) {
|
||||
outer:
|
||||
for (var L = 0; L <= body.length - search.length; ++L) {
|
||||
for (var j = 0; j < search.length; ++j)
|
||||
if (body[L + j] != search[j])
|
||||
continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function u8concat(u8a) {
|
||||
var len = u8a.reduce(function(acc, x) {
|
||||
return acc + x.length;
|
||||
@ -29,6 +42,15 @@ function readDecimal128LE(buf, offset) {
|
||||
mantissa = mantissa * 256 + buf[j];
|
||||
return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
|
||||
}
|
||||
function writeDecimal128LE(buf, offset, value) {
|
||||
var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
|
||||
var mantissa = value / Math.pow(10, exp - 6176);
|
||||
buf[offset + 15] |= exp >> 7;
|
||||
buf[offset + 14] |= (exp & 127) << 1;
|
||||
for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
|
||||
buf[offset + i] = mantissa & 255;
|
||||
buf[offset + 15] |= value >= 0 ? 0 : 128;
|
||||
}
|
||||
function parse_varint49(buf, ptr) {
|
||||
var l = ptr ? ptr[0] : 0;
|
||||
var usz = buf[l] & 127;
|
||||
@ -154,7 +176,7 @@ function parse_shallow(buf) {
|
||||
default:
|
||||
throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
|
||||
}
|
||||
var v = { offset: off, data: res, type: type };
|
||||
var v = { data: res, type: type };
|
||||
if (out[num] == null)
|
||||
out[num] = [v];
|
||||
else
|
||||
@ -166,6 +188,8 @@ function write_shallow(proto) {
|
||||
var out = [];
|
||||
proto.forEach(function(field, idx) {
|
||||
field.forEach(function(item) {
|
||||
if (!item.data)
|
||||
return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if (item.type == 2)
|
||||
out.push(write_varint49(item.data.length));
|
||||
@ -175,21 +199,12 @@ function write_shallow(proto) {
|
||||
return u8concat(out);
|
||||
}
|
||||
function mappa(data, cb) {
|
||||
if (!data)
|
||||
return [];
|
||||
return data.map(function(d) {
|
||||
var _a;
|
||||
try {
|
||||
return (data == null ? void 0 : data.map(function(d) {
|
||||
return cb(d.data);
|
||||
} catch (e) {
|
||||
var m = (_a = e.message) == null ? void 0 : _a.match(/at offset (\d+)/);
|
||||
if (m)
|
||||
e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})) || [];
|
||||
}
|
||||
function parse_iwa_file(buf) {
|
||||
var _a;
|
||||
var out = [], ptr = [0];
|
||||
while (ptr[0] < buf.length) {
|
||||
var len = parse_varint49(buf, ptr);
|
||||
@ -208,10 +223,35 @@ function parse_iwa_file(buf) {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if ((_a = ai[3]) == null ? void 0 : _a[0])
|
||||
res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function write_iwa_file(ias) {
|
||||
var bufs = [];
|
||||
ias.forEach(function(ia) {
|
||||
var ai = [];
|
||||
ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
|
||||
ai[2] = [];
|
||||
if (ia.merge != null)
|
||||
ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
|
||||
var midata = [];
|
||||
ia.messages.forEach(function(mi) {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
|
||||
ai[2].push({ data: write_shallow(mi.meta), type: 2 });
|
||||
});
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(function(mid) {
|
||||
return bufs.push(mid);
|
||||
});
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
function parse_snappy_chunk(type, buf) {
|
||||
if (type != 0)
|
||||
throw new Error("Unexpected Snappy chunk type ".concat(type));
|
||||
@ -366,7 +406,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -388,7 +428,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function parse_storage(buf, sst, rsst) {
|
||||
function parse_new_storage(buf, sst, rsst) {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
var data_offset = 12;
|
||||
@ -430,7 +470,7 @@ function parse_storage(buf, sst, rsst) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -451,6 +491,66 @@ function parse_storage(buf, sst, rsst) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function write_new_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[1] = 2;
|
||||
writeDecimal128LE(out, l, cell.v);
|
||||
flags |= 1;
|
||||
l += 16;
|
||||
break;
|
||||
case "b":
|
||||
out[1] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 2;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[1] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 8;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[2] = 2;
|
||||
dv.setFloat64(l, cell.v, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "b":
|
||||
out[2] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[2] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 16;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function parse_cell_storage(buf, sst, rsst) {
|
||||
switch (buf[0]) {
|
||||
case 0:
|
||||
@ -459,7 +559,7 @@ function parse_cell_storage(buf, sst, rsst) {
|
||||
case 3:
|
||||
return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5:
|
||||
return parse_storage(buf, sst, rsst);
|
||||
return parse_new_storage(buf, sst, rsst);
|
||||
default:
|
||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||
}
|
||||
@ -468,6 +568,11 @@ function parse_TSP_Reference(buf) {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx) {
|
||||
var out = [];
|
||||
out[1] = [{ type: 0, data: write_varint49(idx) }];
|
||||
return write_shallow(out);
|
||||
}
|
||||
function parse_TST_TableDataList(M, root) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var type = varint_to_i32(pb[1][0].data);
|
||||
@ -526,6 +631,7 @@ function parse_TST_TileRowInfo(u8, type) {
|
||||
var cells = [];
|
||||
for (C = 0; C < offsets.length - 1; ++C)
|
||||
cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
|
||||
if (offsets.length >= 1)
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R: R, cells: cells };
|
||||
}
|
||||
@ -632,7 +738,7 @@ function parse_TN_DocumentArchive(M, root) {
|
||||
}
|
||||
function parse_numbers_iwa(cfb) {
|
||||
var _a, _b, _c, _d;
|
||||
var out = {}, indices = [];
|
||||
var M = {}, indices = [];
|
||||
cfb.FullPaths.forEach(function(p) {
|
||||
if (p.match(/\.iwpv2/))
|
||||
throw new Error("Unsupported password protection");
|
||||
@ -653,16 +759,16 @@ function parse_numbers_iwa(cfb) {
|
||||
return console.log("## " + (e.message || e));
|
||||
}
|
||||
packets.forEach(function(packet) {
|
||||
out[packet.id] = packet.messages;
|
||||
M[packet.id] = packet.messages;
|
||||
indices.push(packet.id);
|
||||
});
|
||||
});
|
||||
if (!indices.length)
|
||||
throw new Error("File has no messages");
|
||||
var docroot = ((_d = (_c = (_b = (_a = out == null ? void 0 : out[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if (!docroot)
|
||||
indices.forEach(function(idx) {
|
||||
out[idx].forEach(function(iwam) {
|
||||
M[idx].forEach(function(iwam) {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if (mtype == 1) {
|
||||
if (!docroot)
|
||||
@ -674,5 +780,323 @@ function parse_numbers_iwa(cfb) {
|
||||
});
|
||||
if (!docroot)
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({ t: "s", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "s", v: data[C] }, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({ t: "n", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "n", v: data[C] }, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({ t: "b", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "b", v: data[C] }, SST);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if (wb.SheetNames.length > 1)
|
||||
console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
var data = sheet_to_json(ws, { range: range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(function(row) {
|
||||
return row.forEach(function(cell) {
|
||||
if (typeof cell == "string")
|
||||
SST.push(cell);
|
||||
});
|
||||
});
|
||||
var dependents = {};
|
||||
var indices = [];
|
||||
var cfb = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (fi.type != 2)
|
||||
return;
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content);
|
||||
var x2 = parse_iwa_file(raw1);
|
||||
x2.forEach(function(packet2) {
|
||||
indices.push(packet2.id);
|
||||
dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
indices.sort(function(x2, y2) {
|
||||
return x2 - y2;
|
||||
});
|
||||
var indices_varint = indices.filter(function(x2) {
|
||||
return x2 > 1;
|
||||
}).map(function(x2) {
|
||||
return [x2, write_varint49(x2)];
|
||||
});
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
|
||||
x2.forEach(function(ia) {
|
||||
ia.messages.forEach(function(m) {
|
||||
indices_varint.forEach(function(ivi) {
|
||||
if (ia.messages.some(function(mess) {
|
||||
return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
|
||||
})) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function get_unique_msgid() {
|
||||
for (var i = 927262; i < 2e6; ++i)
|
||||
if (!dependents[i])
|
||||
return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
var docroot;
|
||||
for (var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if (packet.id == 1)
|
||||
docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
for (var j = 0; j < _x.length; ++j) {
|
||||
if (_x[j].id == cruidsref)
|
||||
break;
|
||||
}
|
||||
if (_x[j].id != cruidsref)
|
||||
throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = [];
|
||||
cruids[2] = [], cruids[3] = [];
|
||||
for (var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
|
||||
cruids[1].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[2].push({ type: 0, data: write_varint49(C) });
|
||||
cruids[3].push({ type: 0, data: write_varint49(C) });
|
||||
}
|
||||
cruids[4] = [];
|
||||
cruids[5] = [], cruids[6] = [];
|
||||
for (var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
|
||||
cruids[4].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[5].push({ type: 0, data: write_varint49(R) });
|
||||
cruids[6].push({ type: 0, data: write_varint49(R) });
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != col_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(function() {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
|
||||
var sstroot;
|
||||
for (var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet2 = sx[sxi];
|
||||
if (packet2.id == sstref)
|
||||
sstroot = packet2;
|
||||
}
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst = [];
|
||||
SST.forEach(function(str, i) {
|
||||
newsst[1] = [{ type: 0, data: write_varint49(i) }];
|
||||
newsst[2] = [{ type: 0, data: write_varint49(1) }];
|
||||
newsst[3] = [{ type: 2, data: stru8(str) }];
|
||||
sstdata[3].push({ type: 2, data: write_shallow(newsst) });
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw32 = compress_iwa_file(sy);
|
||||
sentry.content = raw32;
|
||||
sentry.size = sentry.content.length;
|
||||
})();
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(function() {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
|
||||
var tileroot;
|
||||
for (var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet2 = tx[sxi];
|
||||
if (packet2.id == tileref)
|
||||
tileroot = packet2;
|
||||
}
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6];
|
||||
delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw32 = compress_iwa_file(ty);
|
||||
tentry.content = raw32;
|
||||
tentry.size = tentry.content.length;
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3;
|
||||
entry.size = entry.content.length;
|
||||
return cfb;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
|
||||
if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
|
||||
return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
|
@ -149,6 +149,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'xlsm':
|
||||
case 'xlam':
|
||||
case 'xlsb':
|
||||
case 'numbers':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
|
28
dist/xlsx.core.min.js
generated
vendored
28
dist/xlsx.core.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
generated
vendored
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
1720
dist/xlsx.extendscript.js
generated
vendored
1720
dist/xlsx.extendscript.js
generated
vendored
File diff suppressed because it is too large
Load Diff
30
dist/xlsx.full.min.js
generated
vendored
30
dist/xlsx.full.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
generated
vendored
2
dist/xlsx.full.min.map
generated
vendored
File diff suppressed because one or more lines are too long
16
dist/xlsx.mini.min.js
generated
vendored
16
dist/xlsx.mini.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.mini.min.map
generated
vendored
2
dist/xlsx.mini.min.map
generated
vendored
File diff suppressed because one or more lines are too long
4
dist/xlsx.zahl.js
generated
vendored
Normal file
4
dist/xlsx.zahl.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/xlsx.zahl.mjs
generated
vendored
Normal file
2
dist/xlsx.zahl.mjs
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -258,5 +258,60 @@ stream.pipe(conv); conv.pipe(process.stdout);
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Exporting NUMBERS files</b> (click to show)</summary>
|
||||
|
||||
The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl`
|
||||
scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS
|
||||
use, while `xlsx.zahl.mjs` is suitable for ESM.
|
||||
|
||||
_Browser_
|
||||
|
||||
```html
|
||||
<meta charset="utf8">
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script src="xlsx.zahl.js"></script>
|
||||
<script>
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
</script>
|
||||
```
|
||||
|
||||
_Node_
|
||||
|
||||
```js
|
||||
var XLSX = require("./xlsx.flow");
|
||||
var XLSX_ZAHL = require("./dist/xlsx.zahl");
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
_Deno_
|
||||
|
||||
```ts
|
||||
import * as XLSX from './xlsx.mjs';
|
||||
import XLSX_ZAHL from './dist/xlsx.zahl.mjs';
|
||||
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.
|
||||
|
||||
|
@ -13,6 +13,7 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
|`Props` | | Override workbook properties when writing ** |
|
||||
|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** |
|
||||
|`ignoreEC` | `true` | Suppress "number as text" errors ** |
|
||||
|`numbers` | | Payload for NUMBERS export ** |
|
||||
|
||||
- `bookSST` is slower and more memory intensive, but has better compatibility
|
||||
with older versions of iOS Numbers
|
||||
@ -28,6 +29,8 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
- Due to a bug in the program, some features like "Text to Columns" will crash
|
||||
Excel on worksheets where error conditions are ignored. The writer will mark
|
||||
files to ignore the error by default. Set `ignoreEC` to `false` to suppress.
|
||||
- Due to the size of the data, the NUMBERS data is not included by default. The
|
||||
included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data.
|
||||
|
||||
### Supported Output Formats
|
||||
|
||||
@ -45,6 +48,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) |
|
||||
|
@ -20,7 +20,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Lotus Formatted Text (PRN) | ✔ | ✔ |
|
||||
| UTF-16 Unicode Text (TXT) | ✔ | ✔ |
|
||||
| **Other Workbook/Worksheet Formats** |:-----:|:-----:|
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | |
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | ✔ |
|
||||
| OpenDocument Spreadsheet (ODS) | ✔ | ✔ |
|
||||
| Flat XML ODF Spreadsheet (FODS) | ✔ | ✔ |
|
||||
| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | ✔ | |
|
||||
@ -169,6 +169,8 @@ The parser focuses on extracting raw data from tables. Numbers technically
|
||||
supports multiple tables in a logical worksheet, including custom titles. This
|
||||
parser will generate one worksheet per Numbers table.
|
||||
|
||||
The writer currently exports a small range from the first worksheet.
|
||||
|
||||
- **OpenDocument Spreadsheet (ODS/FODS)**
|
||||
|
||||
ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
||||
|
BIN
formats.png
BIN
formats.png
Binary file not shown.
Before ![]() (image error) Size: 203 KiB After ![]() (image error) Size: 204 KiB ![]() ![]() |
@ -1656,6 +1656,58 @@ stream.pipe(conv); conv.pipe(process.stdout);
|
||||
```
|
||||
|
||||
|
||||
|
||||
The NUMBERS writer requires a fairly large base. The supplementary `xlsx.zahl`
|
||||
scripts provide support. `xlsx.zahl.js` is designed for standalone and NodeJS
|
||||
use, while `xlsx.zahl.mjs` is suitable for ESM.
|
||||
|
||||
_Browser_
|
||||
|
||||
```html
|
||||
<meta charset="utf8">
|
||||
<script src="xlsx.full.min.js"></script>
|
||||
<script src="xlsx.zahl.js"></script>
|
||||
<script>
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
</script>
|
||||
```
|
||||
|
||||
_Node_
|
||||
|
||||
```js
|
||||
var XLSX = require("./xlsx.flow");
|
||||
var XLSX_ZAHL = require("./dist/xlsx.zahl");
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textport.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
_Deno_
|
||||
|
||||
```ts
|
||||
import * as XLSX from './xlsx.mjs';
|
||||
import XLSX_ZAHL from './dist/xlsx.zahl.mjs';
|
||||
|
||||
var wb = XLSX.utils.book_new(); var ws = XLSX.utils.aoa_to_sheet([
|
||||
["SheetJS", "<3","விரிதாள்"],
|
||||
[72,,"Arbeitsblätter"],
|
||||
[,62,"数据"],
|
||||
[true,false,],
|
||||
]); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "textports.numbers", {numbers: XLSX_ZAHL, compression: true});
|
||||
```
|
||||
|
||||
|
||||
<https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response.
|
||||
|
||||
### Generating JSON and JS Data
|
||||
@ -3171,6 +3223,7 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
|`Props` | | Override workbook properties when writing ** |
|
||||
|`themeXLSX` | | Override theme XML when writing XLSX/XLSB/XLSM ** |
|
||||
|`ignoreEC` | `true` | Suppress "number as text" errors ** |
|
||||
|`numbers` | | Payload for NUMBERS export ** |
|
||||
|
||||
- `bookSST` is slower and more memory intensive, but has better compatibility
|
||||
with older versions of iOS Numbers
|
||||
@ -3186,6 +3239,8 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
- Due to a bug in the program, some features like "Text to Columns" will crash
|
||||
Excel on worksheets where error conditions are ignored. The writer will mark
|
||||
files to ignore the error by default. Set `ignoreEC` to `false` to suppress.
|
||||
- Due to the size of the data, the NUMBERS data is not included by default. The
|
||||
included `xlsx.zahl.js` and `xlsx.zahl.mjs` scripts include the data.
|
||||
|
||||
### Supported Output Formats
|
||||
|
||||
@ -3203,6 +3258,7 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `biff3` | `.xls` | none | single | Excel 3.0 Worksheet Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `numbers` |`.numbers`| ZIP | single | Numbers 3.0+ Spreadsheet |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
| `wk3` | `.wk3` | none | multi | Lotus Workbook (WK3) |
|
||||
@ -3725,7 +3781,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Lotus Formatted Text (PRN) | ✔ | ✔ |
|
||||
| UTF-16 Unicode Text (TXT) | ✔ | ✔ |
|
||||
| **Other Workbook/Worksheet Formats** |:-----:|:-----:|
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | |
|
||||
| Numbers 3.0+ / iWork 2013+ Spreadsheet (NUMBERS) | ✔ | ✔ |
|
||||
| OpenDocument Spreadsheet (ODS) | ✔ | ✔ |
|
||||
| Flat XML ODF Spreadsheet (FODS) | ✔ | ✔ |
|
||||
| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | ✔ | |
|
||||
@ -3872,6 +3928,8 @@ The parser focuses on extracting raw data from tables. Numbers technically
|
||||
supports multiple tables in a logical worksheet, including custom titles. This
|
||||
parser will generate one worksheet per Numbers table.
|
||||
|
||||
The writer currently exports a small range from the first worksheet.
|
||||
|
||||
- **OpenDocument Spreadsheet (ODS/FODS)**
|
||||
|
||||
ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
||||
|
@ -65,6 +65,7 @@ digraph G {
|
||||
123 -> csf
|
||||
qpw -> csf
|
||||
nums -> csf
|
||||
csf -> nums
|
||||
}
|
||||
subgraph WORKSHEET {
|
||||
edge [color=aquamarine4];
|
||||
|
2
modules/.gitignore
vendored
2
modules/.gitignore
vendored
@ -5,3 +5,5 @@ test_files
|
||||
*.[Jj][Pp][Gg]
|
||||
*.[Pp][Ll][Ii][Ss][Tt]
|
||||
DocumentIdentifier
|
||||
xlsx.zahl.*
|
||||
src/numbers.ts
|
||||
|
@ -5,6 +5,19 @@ function u8_to_dataview(array) {
|
||||
function u8str(u8) {
|
||||
return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
|
||||
}
|
||||
function stru8(str) {
|
||||
return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
|
||||
}
|
||||
function u8contains(body, search) {
|
||||
outer:
|
||||
for (var L = 0; L <= body.length - search.length; ++L) {
|
||||
for (var j = 0; j < search.length; ++j)
|
||||
if (body[L + j] != search[j])
|
||||
continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function u8concat(u8a) {
|
||||
var len = u8a.reduce(function(acc, x) {
|
||||
return acc + x.length;
|
||||
@ -29,6 +42,15 @@ function readDecimal128LE(buf, offset) {
|
||||
mantissa = mantissa * 256 + buf[j];
|
||||
return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
|
||||
}
|
||||
function writeDecimal128LE(buf, offset, value) {
|
||||
var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
|
||||
var mantissa = value / Math.pow(10, exp - 6176);
|
||||
buf[offset + 15] |= exp >> 7;
|
||||
buf[offset + 14] |= (exp & 127) << 1;
|
||||
for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
|
||||
buf[offset + i] = mantissa & 255;
|
||||
buf[offset + 15] |= value >= 0 ? 0 : 128;
|
||||
}
|
||||
function parse_varint49(buf, ptr) {
|
||||
var l = ptr ? ptr[0] : 0;
|
||||
var usz = buf[l] & 127;
|
||||
@ -154,7 +176,7 @@ function parse_shallow(buf) {
|
||||
default:
|
||||
throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
|
||||
}
|
||||
var v = { offset: off, data: res, type: type };
|
||||
var v = { data: res, type: type };
|
||||
if (out[num] == null)
|
||||
out[num] = [v];
|
||||
else
|
||||
@ -166,6 +188,8 @@ function write_shallow(proto) {
|
||||
var out = [];
|
||||
proto.forEach(function(field, idx) {
|
||||
field.forEach(function(item) {
|
||||
if (!item.data)
|
||||
return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if (item.type == 2)
|
||||
out.push(write_varint49(item.data.length));
|
||||
@ -175,21 +199,12 @@ function write_shallow(proto) {
|
||||
return u8concat(out);
|
||||
}
|
||||
function mappa(data, cb) {
|
||||
if (!data)
|
||||
return [];
|
||||
return data.map(function(d) {
|
||||
var _a;
|
||||
try {
|
||||
return (data == null ? void 0 : data.map(function(d) {
|
||||
return cb(d.data);
|
||||
} catch (e) {
|
||||
var m = (_a = e.message) == null ? void 0 : _a.match(/at offset (\d+)/);
|
||||
if (m)
|
||||
e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})) || [];
|
||||
}
|
||||
function parse_iwa_file(buf) {
|
||||
var _a;
|
||||
var out = [], ptr = [0];
|
||||
while (ptr[0] < buf.length) {
|
||||
var len = parse_varint49(buf, ptr);
|
||||
@ -208,10 +223,35 @@ function parse_iwa_file(buf) {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if ((_a = ai[3]) == null ? void 0 : _a[0])
|
||||
res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function write_iwa_file(ias) {
|
||||
var bufs = [];
|
||||
ias.forEach(function(ia) {
|
||||
var ai = [];
|
||||
ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
|
||||
ai[2] = [];
|
||||
if (ia.merge != null)
|
||||
ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
|
||||
var midata = [];
|
||||
ia.messages.forEach(function(mi) {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
|
||||
ai[2].push({ data: write_shallow(mi.meta), type: 2 });
|
||||
});
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(function(mid) {
|
||||
return bufs.push(mid);
|
||||
});
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
function parse_snappy_chunk(type, buf) {
|
||||
if (type != 0)
|
||||
throw new Error("Unexpected Snappy chunk type ".concat(type));
|
||||
@ -366,7 +406,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -388,7 +428,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function parse_storage(buf, sst, rsst) {
|
||||
function parse_new_storage(buf, sst, rsst) {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
var data_offset = 12;
|
||||
@ -430,7 +470,7 @@ function parse_storage(buf, sst, rsst) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -451,6 +491,66 @@ function parse_storage(buf, sst, rsst) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function write_new_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[1] = 2;
|
||||
writeDecimal128LE(out, l, cell.v);
|
||||
flags |= 1;
|
||||
l += 16;
|
||||
break;
|
||||
case "b":
|
||||
out[1] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 2;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[1] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 8;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[2] = 2;
|
||||
dv.setFloat64(l, cell.v, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "b":
|
||||
out[2] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[2] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 16;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function parse_cell_storage(buf, sst, rsst) {
|
||||
switch (buf[0]) {
|
||||
case 0:
|
||||
@ -459,7 +559,7 @@ function parse_cell_storage(buf, sst, rsst) {
|
||||
case 3:
|
||||
return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5:
|
||||
return parse_storage(buf, sst, rsst);
|
||||
return parse_new_storage(buf, sst, rsst);
|
||||
default:
|
||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||
}
|
||||
@ -468,6 +568,11 @@ function parse_TSP_Reference(buf) {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx) {
|
||||
var out = [];
|
||||
out[1] = [{ type: 0, data: write_varint49(idx) }];
|
||||
return write_shallow(out);
|
||||
}
|
||||
function parse_TST_TableDataList(M, root) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var type = varint_to_i32(pb[1][0].data);
|
||||
@ -526,6 +631,7 @@ function parse_TST_TileRowInfo(u8, type) {
|
||||
var cells = [];
|
||||
for (C = 0; C < offsets.length - 1; ++C)
|
||||
cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
|
||||
if (offsets.length >= 1)
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R: R, cells: cells };
|
||||
}
|
||||
@ -632,7 +738,7 @@ function parse_TN_DocumentArchive(M, root) {
|
||||
}
|
||||
function parse_numbers_iwa(cfb) {
|
||||
var _a, _b, _c, _d;
|
||||
var out = {}, indices = [];
|
||||
var M = {}, indices = [];
|
||||
cfb.FullPaths.forEach(function(p) {
|
||||
if (p.match(/\.iwpv2/))
|
||||
throw new Error("Unsupported password protection");
|
||||
@ -653,16 +759,16 @@ function parse_numbers_iwa(cfb) {
|
||||
return console.log("## " + (e.message || e));
|
||||
}
|
||||
packets.forEach(function(packet) {
|
||||
out[packet.id] = packet.messages;
|
||||
M[packet.id] = packet.messages;
|
||||
indices.push(packet.id);
|
||||
});
|
||||
});
|
||||
if (!indices.length)
|
||||
throw new Error("File has no messages");
|
||||
var docroot = ((_d = (_c = (_b = (_a = out == null ? void 0 : out[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if (!docroot)
|
||||
indices.forEach(function(idx) {
|
||||
out[idx].forEach(function(iwam) {
|
||||
M[idx].forEach(function(iwam) {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if (mtype == 1) {
|
||||
if (!docroot)
|
||||
@ -674,5 +780,323 @@ function parse_numbers_iwa(cfb) {
|
||||
});
|
||||
if (!docroot)
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({ t: "s", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "s", v: data[C] }, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({ t: "n", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "n", v: data[C] }, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({ t: "b", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "b", v: data[C] }, SST);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if (wb.SheetNames.length > 1)
|
||||
console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
var data = sheet_to_json(ws, { range: range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(function(row) {
|
||||
return row.forEach(function(cell) {
|
||||
if (typeof cell == "string")
|
||||
SST.push(cell);
|
||||
});
|
||||
});
|
||||
var dependents = {};
|
||||
var indices = [];
|
||||
var cfb = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (fi.type != 2)
|
||||
return;
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content);
|
||||
var x2 = parse_iwa_file(raw1);
|
||||
x2.forEach(function(packet2) {
|
||||
indices.push(packet2.id);
|
||||
dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
indices.sort(function(x2, y2) {
|
||||
return x2 - y2;
|
||||
});
|
||||
var indices_varint = indices.filter(function(x2) {
|
||||
return x2 > 1;
|
||||
}).map(function(x2) {
|
||||
return [x2, write_varint49(x2)];
|
||||
});
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
|
||||
x2.forEach(function(ia) {
|
||||
ia.messages.forEach(function(m) {
|
||||
indices_varint.forEach(function(ivi) {
|
||||
if (ia.messages.some(function(mess) {
|
||||
return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
|
||||
})) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function get_unique_msgid() {
|
||||
for (var i = 927262; i < 2e6; ++i)
|
||||
if (!dependents[i])
|
||||
return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
var docroot;
|
||||
for (var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if (packet.id == 1)
|
||||
docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
for (var j = 0; j < _x.length; ++j) {
|
||||
if (_x[j].id == cruidsref)
|
||||
break;
|
||||
}
|
||||
if (_x[j].id != cruidsref)
|
||||
throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = [];
|
||||
cruids[2] = [], cruids[3] = [];
|
||||
for (var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
|
||||
cruids[1].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[2].push({ type: 0, data: write_varint49(C) });
|
||||
cruids[3].push({ type: 0, data: write_varint49(C) });
|
||||
}
|
||||
cruids[4] = [];
|
||||
cruids[5] = [], cruids[6] = [];
|
||||
for (var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
|
||||
cruids[4].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[5].push({ type: 0, data: write_varint49(R) });
|
||||
cruids[6].push({ type: 0, data: write_varint49(R) });
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != col_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(function() {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
|
||||
var sstroot;
|
||||
for (var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet2 = sx[sxi];
|
||||
if (packet2.id == sstref)
|
||||
sstroot = packet2;
|
||||
}
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst = [];
|
||||
SST.forEach(function(str, i) {
|
||||
newsst[1] = [{ type: 0, data: write_varint49(i) }];
|
||||
newsst[2] = [{ type: 0, data: write_varint49(1) }];
|
||||
newsst[3] = [{ type: 2, data: stru8(str) }];
|
||||
sstdata[3].push({ type: 2, data: write_shallow(newsst) });
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw32 = compress_iwa_file(sy);
|
||||
sentry.content = raw32;
|
||||
sentry.size = sentry.content.length;
|
||||
})();
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(function() {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
|
||||
var tileroot;
|
||||
for (var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet2 = tx[sxi];
|
||||
if (packet2.id == tileref)
|
||||
tileroot = packet2;
|
||||
}
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6];
|
||||
delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw32 = compress_iwa_file(ty);
|
||||
tentry.content = raw32;
|
||||
tentry.size = tentry.content.length;
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3;
|
||||
entry.size = entry.content.length;
|
||||
return cfb;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
/// <reference path="src/types.ts"/>
|
||||
|
||||
/* these are type imports and do not show up in the generated JS */
|
||||
import { CFB$Container } from 'cfb';
|
||||
import { CFB$Container, CFB$Entry } from 'cfb';
|
||||
import { WorkBook, WorkSheet, Range, CellObject } from '../';
|
||||
import type { utils } from "../";
|
||||
|
||||
@ -10,12 +10,28 @@ declare var encode_cell: typeof utils.encode_cell;
|
||||
declare var encode_range: typeof utils.encode_range;
|
||||
declare var book_new: typeof utils.book_new;
|
||||
declare var book_append_sheet: typeof utils.book_append_sheet;
|
||||
declare var sheet_to_json: typeof utils.sheet_to_json;
|
||||
declare var decode_range: typeof utils.decode_range;
|
||||
import * as _CFB from 'cfb';
|
||||
declare var CFB: typeof _CFB;
|
||||
//<<import { utils } from "../../";
|
||||
//<<const { encode_cell, encode_range, book_new, book_append_sheet } = utils;
|
||||
|
||||
function u8_to_dataview(array: Uint8Array): DataView { return new DataView(array.buffer, array.byteOffset, array.byteLength); }
|
||||
//<<export { u8_to_dataview };
|
||||
|
||||
function u8str(u8: Uint8Array): string { return /* Buffer.isBuffer(u8) ? u8.toString() :*/ typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8)); }
|
||||
function stru8(str: string): Uint8Array { return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str)) as Uint8Array; }
|
||||
//<<export { u8str, stru8 };
|
||||
|
||||
function u8contains(body: Uint8Array, search: Uint8Array): boolean {
|
||||
outer: for(var L = 0; L <= body.length - search.length; ++L) {
|
||||
for(var j = 0; j < search.length; ++j) if(body[L+j] != search[j]) continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//<<export { u8contains }
|
||||
|
||||
/** Concatenate Uint8Arrays */
|
||||
function u8concat(u8a: Uint8Array[]): Uint8Array {
|
||||
@ -41,6 +57,17 @@ function readDecimal128LE(buf: Uint8Array, offset: number): number {
|
||||
for(var j = offset + 13; j >= offset; --j) mantissa = mantissa * 256 + buf[j];
|
||||
return ((buf[offset+15] & 0x80) ? -mantissa : mantissa) * Math.pow(10, exp - 0x1820);
|
||||
}
|
||||
/** Write a 128-bit decimal to the modern cell storage */
|
||||
function writeDecimal128LE(buf: Uint8Array, offset: number, value: number): void {
|
||||
// TODO: something more correct than this
|
||||
var exp = Math.floor(value == 0 ? 0 : /*Math.log10*/Math.LOG10E * Math.log(Math.abs(value))) + 0x1820 - 20;
|
||||
var mantissa = (value / Math.pow(10, exp - 0x1820));
|
||||
buf[offset+15] |= exp >> 7;
|
||||
buf[offset+14] |= (exp & 0x7F) << 1;
|
||||
for(var i = 0; mantissa >= 1; ++i, mantissa /= 256) buf[offset + i] = mantissa & 0xFF;
|
||||
buf[offset+15] |= (value >= 0 ? 0 : 0x80);
|
||||
}
|
||||
|
||||
|
||||
type Ptr = [number];
|
||||
|
||||
@ -78,6 +105,7 @@ function write_varint49(v: number): Uint8Array {
|
||||
}
|
||||
return usz.slice(0, L);
|
||||
}
|
||||
//<<export { parse_varint49, write_varint49 };
|
||||
|
||||
/** Parse a 32-bit signed integer from the raw varint */
|
||||
function varint_to_i32(buf: Uint8Array): number {
|
||||
@ -93,7 +121,6 @@ function varint_to_i32(buf: Uint8Array): number {
|
||||
//<<export { varint_to_i32 };
|
||||
|
||||
interface ProtoItem {
|
||||
offset?: number;
|
||||
data: Uint8Array;
|
||||
type: number;
|
||||
}
|
||||
@ -122,7 +149,7 @@ function parse_shallow(buf: Uint8Array): ProtoMessage {
|
||||
case 4: // End group
|
||||
default: throw new Error(`PB Type ${type} for Field ${num} at offset ${off}`);
|
||||
}
|
||||
var v: ProtoItem = { offset: off, data: res, type };
|
||||
var v: ProtoItem = { data: res, type };
|
||||
if(out[num] == null) out[num] = [v];
|
||||
else out[num].push(v);
|
||||
}
|
||||
@ -133,6 +160,7 @@ function write_shallow(proto: ProtoMessage): Uint8Array {
|
||||
var out: Uint8Array[] = [];
|
||||
proto.forEach((field, idx) => {
|
||||
field.forEach(item => {
|
||||
if(!item.data) return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if(item.type == 2) out.push(write_varint49(item.data.length));
|
||||
out.push(item.data);
|
||||
@ -144,14 +172,7 @@ function write_shallow(proto: ProtoMessage): Uint8Array {
|
||||
|
||||
/** Map over each entry in a repeated (or single-value) field */
|
||||
function mappa<U>(data: ProtoField, cb:(Uint8Array) => U): U[] {
|
||||
if(!data) return [];
|
||||
return data.map((d) => { try {
|
||||
return cb(d.data);
|
||||
} catch(e) {
|
||||
var m = e.message?.match(/at offset (\d+)/);
|
||||
if(m) e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}});
|
||||
return data?.map(d => cb(d.data)) || [];
|
||||
}
|
||||
|
||||
|
||||
@ -162,6 +183,7 @@ interface IWAMessage {
|
||||
}
|
||||
interface IWAArchiveInfo {
|
||||
id?: number;
|
||||
merge?: boolean;
|
||||
messages?: IWAMessage[];
|
||||
}
|
||||
/** Extract all messages from a IWA file */
|
||||
@ -187,11 +209,34 @@ function parse_iwa_file(buf: Uint8Array): IWAArchiveInfo[] {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if(ai[3]?.[0]) res.merge = (varint_to_i32(ai[3][0].data) >>> 0) > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
//<<export { parse_iwa_file };
|
||||
function write_iwa_file(ias: IWAArchiveInfo[]): Uint8Array {
|
||||
var bufs: Uint8Array[] = [];
|
||||
ias.forEach(ia => {
|
||||
var ai: ProtoMessage = [];
|
||||
ai[1] = [{data: write_varint49(ia.id), type: 0}];
|
||||
ai[2] = [];
|
||||
if(ia.merge != null) ai[3] = [ { data: write_varint49(+!!ia.merge), type: 0 } ];
|
||||
var midata: Uint8Array[] = [];
|
||||
|
||||
ia.messages.forEach(mi => {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [ { type: 0, data: write_varint49(mi.data.length) } ];
|
||||
ai[2].push({data: write_shallow(mi.meta), type: 2});
|
||||
});
|
||||
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(mid => bufs.push(mid));
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
//<<export { IWAMessage, IWAArchiveInfo, parse_iwa_file, write_iwa_file };
|
||||
|
||||
/** Decompress a snappy chunk */
|
||||
function parse_snappy_chunk(type: number, buf: Uint8Array): Uint8Array {
|
||||
@ -308,7 +353,7 @@ function parse_old_storage(buf: Uint8Array, sst: string[], rsst: string[], v: 0|
|
||||
case 3: ret = { t: "s", v: sst[sidx] }; break; // string
|
||||
case 5: ret = { t: "d", v: dt }; break; // date-time
|
||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||
case 9: { // "automatic"?
|
||||
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
|
||||
@ -323,7 +368,8 @@ function parse_old_storage(buf: Uint8Array, sst: string[], rsst: string[], v: 0|
|
||||
return ret;
|
||||
}
|
||||
|
||||
function parse_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObject {
|
||||
/** Parse "new storage" (version 5) */
|
||||
function parse_new_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObject {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
|
||||
@ -345,7 +391,7 @@ function parse_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObje
|
||||
case 3: ret = { t: "s", v: sst[sidx] }; break; // string
|
||||
case 5: ret = { t: "d", v: dt }; break; // date-time
|
||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||
case 9: { // "automatic"?
|
||||
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
|
||||
@ -358,12 +404,40 @@ function parse_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObje
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function write_new_storage(cell: CellObject, sst: string[]): Uint8Array {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch(cell.t) {
|
||||
case "n": out[1] = 2; writeDecimal128LE(out, l, cell.v as number); flags |= 1; l += 16; break;
|
||||
case "b": out[1] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); flags |= 2; l += 8; break;
|
||||
case "s":
|
||||
if(sst.indexOf(cell.v as string) == -1) throw new Error(`Value ${cell.v} missing from SST!`);
|
||||
out[1] = 3; dv.setUint32(l, sst.indexOf(cell.v as string), true); flags |= 8; l += 4; break;
|
||||
default: throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell: CellObject, sst: string[]): Uint8Array {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch(cell.t) {
|
||||
case "n": out[2] = 2; dv.setFloat64(l, cell.v as number, true); flags |= 0x20; l += 8; break;
|
||||
case "b": out[2] = 6; dv.setFloat64(l, cell.v ? 1 : 0, true); flags |= 0x20; l += 8; break;
|
||||
case "s":
|
||||
if(sst.indexOf(cell.v as string) == -1) throw new Error(`Value ${cell.v} missing from SST!`);
|
||||
out[2] = 3; dv.setUint32(l, sst.indexOf(cell.v as string), true); flags |= 0x10; l += 4; break;
|
||||
default: throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
//<<export { write_new_storage, write_old_storage };
|
||||
function parse_cell_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObject {
|
||||
switch(buf[0]) {
|
||||
case 0: case 1:
|
||||
case 2: case 3: return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5: return parse_storage(buf, sst, rsst);
|
||||
case 5: return parse_new_storage(buf, sst, rsst);
|
||||
default: throw new Error(`Unsupported payload version ${buf[0]}`);
|
||||
}
|
||||
}
|
||||
@ -378,6 +452,12 @@ function parse_TSP_Reference(buf: Uint8Array): number {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx: number): Uint8Array {
|
||||
var out: ProtoMessage = [];
|
||||
out[1] = [ { type: 0, data: write_varint49(idx) } ];
|
||||
return write_shallow(out)
|
||||
}
|
||||
//<<export { parse_TSP_Reference, write_TSP_Reference };
|
||||
|
||||
type MessageSpace = {[id: number]: IWAMessage[]};
|
||||
|
||||
@ -446,7 +526,7 @@ function parse_TST_TileRowInfo(u8: Uint8Array, type: TileStorageType): TileRowIn
|
||||
|
||||
var cells: Uint8Array[] = [];
|
||||
for(C = 0; C < offsets.length - 1; ++C) cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C+1][1] * width);
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
if(offsets.length >= 1) cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R, cells };
|
||||
}
|
||||
|
||||
@ -472,7 +552,7 @@ function parse_TST_Tile(M: MessageSpace, root: IWAMessage): TileInfo {
|
||||
};
|
||||
}
|
||||
|
||||
/** .TST.TableModelArchive */
|
||||
/** .TST.TableModelArchive (6001) */
|
||||
function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: WorkSheet) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var range: Range = { s: {r:0, c:0}, e: {r:0, c:0} };
|
||||
@ -509,7 +589,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
|
||||
});
|
||||
}
|
||||
|
||||
/** .TST.TableInfoArchive */
|
||||
/** .TST.TableInfoArchive (6000) */
|
||||
function parse_TST_TableInfoArchive(M: MessageSpace, root: IWAMessage): WorkSheet {
|
||||
var pb = parse_shallow(root.data);
|
||||
var out: WorkSheet = { "!ref": "A1" };
|
||||
@ -524,7 +604,7 @@ interface NSheet {
|
||||
name: string;
|
||||
sheets: WorkSheet[];
|
||||
}
|
||||
/** .TN.SheetArchive */
|
||||
/** .TN.SheetArchive (2) */
|
||||
function parse_TN_SheetArchive(M: MessageSpace, root: IWAMessage): NSheet {
|
||||
var pb = parse_shallow(root.data);
|
||||
var out: NSheet = {
|
||||
@ -570,7 +650,7 @@ function parse_TN_DocumentArchive(M: MessageSpace, root: IWAMessage): WorkBook {
|
||||
|
||||
/** Parse NUMBERS file */
|
||||
function parse_numbers_iwa(cfb: CFB$Container): WorkBook {
|
||||
var out: MessageSpace = {}, indices: number[] = [];
|
||||
var M: MessageSpace = {}, indices: number[] = [];
|
||||
cfb.FullPaths.forEach(p => { if(p.match(/\.iwpv2/)) throw new Error(`Unsupported password protection`); });
|
||||
|
||||
/* collect entire message space */
|
||||
@ -580,14 +660,14 @@ function parse_numbers_iwa(cfb: CFB$Container): WorkBook {
|
||||
try { o = decompress_iwa_file(s.content as Uint8Array); } catch(e) { return console.log("?? " + s.content.length + " " + (e.message || e)); }
|
||||
var packets: IWAArchiveInfo[];
|
||||
try { packets = parse_iwa_file(o); } catch(e) { return console.log("## " + (e.message || e)); }
|
||||
packets.forEach(packet => { out[packet.id] = packet.messages; indices.push(packet.id); });
|
||||
packets.forEach(packet => { M[packet.id] = packet.messages; indices.push(packet.id); });
|
||||
});
|
||||
if(!indices.length) throw new Error("File has no messages");
|
||||
|
||||
/* find document root */
|
||||
var docroot: IWAMessage = out?.[1]?.[0]?.meta?.[1]?.[0].data && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot: IWAMessage = M?.[1]?.[0]?.meta?.[1]?.[0].data && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if(!docroot) indices.forEach((idx) => {
|
||||
out[idx].forEach((iwam) => {
|
||||
M[idx].forEach((iwam) => {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if(mtype == 1) {
|
||||
if(!docroot) docroot = iwam;
|
||||
@ -596,7 +676,310 @@ function parse_numbers_iwa(cfb: CFB$Container): WorkBook {
|
||||
});
|
||||
});
|
||||
if(!docroot) throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
|
||||
//<<export { parse_numbers_iwa };
|
||||
|
||||
interface DependentInfo {
|
||||
deps: number[];
|
||||
location: string;
|
||||
type: number;
|
||||
}
|
||||
|
||||
function write_tile_row(tri: ProtoMessage, data: any[], SST: string[]): number {
|
||||
if(!tri[6]?.[0] || !tri[7]?.[0]) throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if(wide_offsets) throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage: Uint8Array[] = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage: Uint8Array[] = [];
|
||||
for(var C = 0; C < data.length; ++C) {
|
||||
if(data[C] == null) { dv.setUint16(C*2, 0xFFFF, true); _dv.setUint16(C*2, 0xFFFF); continue; }
|
||||
dv.setUint16(C*2, last_offset, true);
|
||||
_dv.setUint16(C*2, _last_offset, true);
|
||||
var celload: Uint8Array, _celload: Uint8Array;
|
||||
switch(typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({t: "s", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "s", v: data[C]}, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({t: "n", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "n", v: data[C]}, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({t: "b", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "b", v: data[C]}, SST);
|
||||
break;
|
||||
default: throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload); last_offset += celload.length;
|
||||
_cell_storage.push(_celload); _last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
|
||||
for(; C < tri[7][0].data.length/2; ++C) {
|
||||
dv.setUint16(C*2, 0xFFFF, true);
|
||||
_dv.setUint16(C*2, 0xFFFF, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
if(!opts || !opts.numbers) throw new Error("Must pass a `numbers` option -- check the README");
|
||||
/* TODO: support multiple worksheets, larger ranges, more data types, etc */
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if(wb.SheetNames.length > 1) console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if(range.e.c > 9) { trunc = true; range.e.c = 9; }
|
||||
if(range.e.r > 49) { trunc = true; range.e.r = 49; }
|
||||
if(trunc) console.error(`The Numbers writer is currently limited to ${encode_range(range)}`);
|
||||
var data = sheet_to_json<any>(ws, { range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(row => row.forEach(cell => { if(typeof cell == "string") SST.push(cell); }))
|
||||
|
||||
var dependents: {[x:number]: DependentInfo} = {};
|
||||
var indices: number[] = [];
|
||||
|
||||
var cfb: CFB$Container = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(fi.type != 2) return;
|
||||
if(!fi.name.match(/\.iwa/)) return;
|
||||
|
||||
/* Reframe .iwa files */
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content as Uint8Array);
|
||||
|
||||
var x = parse_iwa_file(raw1);
|
||||
|
||||
x.forEach(packet => {
|
||||
indices.push(packet.id);
|
||||
dependents[packet.id] = { deps: [], location: fp, type: varint_to_i32(packet.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
|
||||
indices.sort((x,y) => x-y);
|
||||
var indices_varint: Array<[number, Uint8Array]> = indices.filter(x => x > 1).map(x => [x, write_varint49(x)] );
|
||||
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(!fi.name.match(/\.iwa/)) return;
|
||||
var x = parse_iwa_file(decompress_iwa_file(fi.content as Uint8Array));
|
||||
|
||||
x.forEach(ia => {
|
||||
ia.messages.forEach(m => {
|
||||
indices_varint.forEach(ivi => {
|
||||
if(ia.messages.some(mess => varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]))) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function get_unique_msgid() {
|
||||
for(var i = 927262; i < 2000000; ++i) if(!dependents[i]) return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
|
||||
/* .TN.DocumentArchive */
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
var docroot: IWAArchiveInfo;
|
||||
for(var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == 1) docroot = packet;
|
||||
}
|
||||
|
||||
/* .TN.SheetArchive */
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
|
||||
/* .TST.TableInfoArchive */
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
|
||||
/* .TST.TableModelArchive */
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
// pb[22] = [ { type: 0, data: write_varint49(1) } ]; // enables table display
|
||||
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content as Uint8Array));
|
||||
{
|
||||
for(var j = 0; j < _x.length; ++j) {
|
||||
if(_x[j].id == cruidsref) break;
|
||||
}
|
||||
if(_x[j].id != cruidsref) throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = []; cruids[2] = [], cruids[3] = [];
|
||||
for(var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid: ProtoMessage = [];
|
||||
uuid[1] = uuid[2] = [ { type: 0, data: write_varint49(C + 420690) } ]
|
||||
cruids[1].push({type: 2, data: write_shallow(uuid)})
|
||||
cruids[2].push({type: 0, data: write_varint49(C)});
|
||||
cruids[3].push({type: 0, data: write_varint49(C)});
|
||||
}
|
||||
cruids[4] = []; cruids[5] = [], cruids[6] = [];
|
||||
for(var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [ { type: 0, data: write_varint49(R + 726270)} ];
|
||||
cruids[4].push({type: 2, data: write_shallow(uuid)})
|
||||
cruids[5].push({type: 0, data: write_varint49(R)});
|
||||
cruids[6].push({type: 0, data: write_varint49(R)});
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x)); oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content as Uint8Array));
|
||||
{
|
||||
if(_x[0].id != row_header_ref) throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for(R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x)); oldbucket.size = oldbucket.content.length;
|
||||
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content as Uint8Array));
|
||||
{
|
||||
if(_x[0].id != col_header_ref) throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for(C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x)); oldbucket.size = oldbucket.content.length;
|
||||
|
||||
|
||||
/* ref to string table */
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(() => {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content as Uint8Array));
|
||||
var sstroot: IWAArchiveInfo;
|
||||
for(var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet = sx[sxi];
|
||||
if(packet.id == sstref) sstroot = packet;
|
||||
}
|
||||
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst: ProtoMessage = [];
|
||||
SST.forEach((str, i) => {
|
||||
newsst[1] = [ { type: 0, data: write_varint49(i) } ];
|
||||
newsst[2] = [ { type: 0, data: write_varint49(1) } ];
|
||||
newsst[3] = [ { type: 2, data: stru8(str) } ];
|
||||
sstdata[3].push({type: 2, data: write_shallow(newsst)});
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw3 = compress_iwa_file(sy);
|
||||
sentry.content = raw3; sentry.size = sentry.content.length;
|
||||
})();
|
||||
|
||||
var tile = parse_shallow(store[3][0].data); // TileStorage
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data); // first Tile
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(() => {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content as Uint8Array));
|
||||
var tileroot: IWAArchiveInfo;
|
||||
for(var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet = tx[sxi];
|
||||
if(packet.id == tileref) tileroot = packet;
|
||||
}
|
||||
|
||||
// .TST.Tile
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6]; delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for(var R = 0; R <= range.e.r; ++R) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R], SST);
|
||||
tilerow[1][0].data = write_varint49(R);
|
||||
tiledata[5].push({data: write_shallow(tilerow), type: 2});
|
||||
}
|
||||
tiledata[1] = [{type: 0, data: write_varint49(range.e.c + 1)}];
|
||||
tiledata[2] = [{type: 0, data: write_varint49(range.e.r + 1)}];
|
||||
tiledata[3] = [{type: 0, data: write_varint49(cnt)}];
|
||||
tiledata[4] = [{type: 0, data: write_varint49(range.e.r + 1)}];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw3 = compress_iwa_file(ty);
|
||||
tentry.content = raw3; tentry.size = tentry.content.length;
|
||||
//throw dependents[tileref];
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3; entry.size = entry.content.length;
|
||||
|
||||
return cfb;
|
||||
}
|
||||
|
@ -6,13 +6,16 @@ ENTRIES=$(subst .ts,.js,$(TSFILES))
|
||||
BAREJS=04_base64.js 51_xlsxmeta.js 51_xlsbmeta.js 59_vba.js 64_ftab.js 83_numbers.js
|
||||
|
||||
.PHONY: all
|
||||
all: $(ENTRIES)
|
||||
all: $(ENTRIES) xlsx.zahl.js
|
||||
|
||||
xlsx.zahl.js: test.numbers reframe.node.js
|
||||
bash -c ./reframe.sh
|
||||
|
||||
$(BAREJS): %.js: %.ts $(LIBFILES)
|
||||
npx esbuild $< --outfile=$@ --platform=browser --target=es5
|
||||
|
||||
%.node.js: %.node.ts $(LIBFILES) src/numbers.ts
|
||||
npx esbuild $< --bundle --external:xlsx --outfile=$@ --minify --platform=node
|
||||
npx esbuild $< --bundle --external:xlsx --outfile=$@ --platform=node
|
||||
sed -i '' 's/ts-node/node/g' $@
|
||||
|
||||
%.js: %.ts $(LIBFILES)
|
||||
|
@ -1,13 +1,22 @@
|
||||
/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
import { decompress_iwa_file, compress_iwa_file, u8concat } from "./src/numbers";
|
||||
import { read, writeFile, utils, find, CFB$Entry } from 'cfb';
|
||||
import { decompress_iwa_file, compress_iwa_file, u8concat, parse_iwa_file, write_iwa_file, varint_to_i32, parse_shallow, write_shallow, u8str, stru8, IWAArchiveInfo, parse_TSP_Reference, write_varint49, u8contains, u8_to_dataview, write_new_storage } from "./src/numbers";
|
||||
import { read, writeFile, utils, find, CFB$Entry, CFB$Container } from 'cfb';
|
||||
|
||||
var f = process.argv[2]; var o = process.argv[3];
|
||||
var cfb = read(f, {type: "file"});
|
||||
|
||||
var FI = cfb.FileIndex;
|
||||
var bufs = [], mode = 0;
|
||||
FI.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var nuevo = utils.cfb_new();
|
||||
|
||||
interface DependentInfo {
|
||||
deps: number[];
|
||||
location: string;
|
||||
type: number;
|
||||
}
|
||||
var dependents: {[x:number]: DependentInfo} = {};
|
||||
var indices: number[] = [];
|
||||
|
||||
/* First Pass: reframe, clean up junk, collect message space */
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
/* blank all plist files */
|
||||
if(fi.name.match(/\.plist/)) {
|
||||
@ -17,6 +26,7 @@ FI.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row
|
||||
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x0a
|
||||
]);
|
||||
utils.cfb_add(nuevo, row[1], fi.content);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -26,28 +36,596 @@ FI.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row
|
||||
if(!fi.name.match(/\.iwa/)) {
|
||||
if(fi.name.match(/Sh33tJ5/)) return;
|
||||
console.error(`Removing file ${fi.name}`);
|
||||
utils.cfb_del(cfb, fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reframe .iwa files */
|
||||
console.error(`Reframing iwa ${fi.name} (${fi.size})`);
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content as Uint8Array);
|
||||
var new_content = compress_iwa_file(raw1);
|
||||
var raw2 = decompress_iwa_file(new_content);
|
||||
for(var i = 0; i < raw1.length; ++i) if(raw1[i] != raw2[i]) throw new Error(`${fi.name} did not properly roundtrip`);
|
||||
bufs.push(raw1);
|
||||
switch(mode) {
|
||||
case 1: utils.cfb_del(cfb, fp); break;
|
||||
/* falls through */
|
||||
case 0: fi.content = new_content; break;
|
||||
|
||||
var x = parse_iwa_file(raw2);
|
||||
x.forEach(ia => {
|
||||
ia.messages.forEach(m => {
|
||||
delete m.meta[2];
|
||||
delete m.meta[4];
|
||||
delete m.meta[5]; // extremely slow open if deleted
|
||||
for(var j = 6; j < m.meta.length; ++j) delete m.meta[j];
|
||||
});
|
||||
});
|
||||
|
||||
x.forEach(packet => {
|
||||
indices.push(packet.id);
|
||||
dependents[packet.id] = { deps: [], location: fp, type: varint_to_i32(packet.messages[0].meta[1][0].data) };
|
||||
});
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
for(var i = 0; i < raw1.length; ++i) if(y[i] != raw1[i]) { console.log(fi.name, i, raw1[i], y[i]); break; }
|
||||
|
||||
var raw3 = compress_iwa_file(y);
|
||||
fi.content = raw3; fi.size = fi.content.length;
|
||||
// utils.cfb_add(nuevo, row[1], fi.content);
|
||||
});
|
||||
|
||||
indices.sort((x,y) => x-y);
|
||||
var indices_varint: Array<[number, Uint8Array]> = indices.filter(x => x > 1).map(x => [x, write_varint49(x)] );
|
||||
|
||||
/* Second pass: build dependency map */
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(!fi?.name?.match(/\.iwa/)) return;
|
||||
var x = parse_iwa_file(decompress_iwa_file(fi.content as Uint8Array));
|
||||
|
||||
x.forEach(ia => {
|
||||
ia.messages.forEach(m => {
|
||||
indices_varint.forEach(([i, vi]) => {
|
||||
if(ia.messages.some(mess => varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, vi))) {
|
||||
dependents[i].deps.push(ia.id);
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var deletables = [];
|
||||
function delete_message(id: number, cfb: CFB$Container) {
|
||||
var dep = dependents[id];
|
||||
if(dep?.deps?.length > 0) return console.error(`Message ${id} has dependents ${dep.deps}`);
|
||||
|
||||
//delete dependents[id];
|
||||
indices = indices.filter(x => x != id);
|
||||
|
||||
/* TODO: this really should be a forward map */
|
||||
indices.map(i => dependents[i]).filter(x => x).forEach(dep => {
|
||||
dep.deps = dep.deps.filter(x => x != id);
|
||||
});
|
||||
if(deletables.indexOf(id) == -1) deletables.push(id);
|
||||
}
|
||||
|
||||
function gc(cfb: CFB$Container) {
|
||||
deletables.forEach(id => {
|
||||
var dep = dependents[id];
|
||||
var entry = find(cfb, dep.location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
|
||||
/* remove packet */
|
||||
console.log(`Removing packet ${id} ${dependents[id]?.type || "NaN"}`);
|
||||
for(var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == id) { x.splice(xi,1); --xi; }
|
||||
}
|
||||
|
||||
delete dependents[id];
|
||||
|
||||
entry.content = compress_iwa_file(write_iwa_file(x));
|
||||
entry.size = entry.content.length;
|
||||
});
|
||||
deletables = [];
|
||||
|
||||
}
|
||||
|
||||
function delete_ref(dmeta: ReturnType<typeof parse_shallow>, j: number, me: number) {
|
||||
if(!dmeta) return;
|
||||
if(dmeta[j]) dmeta[j].forEach(pi => {
|
||||
var target = parse_TSP_Reference(pi.data);
|
||||
dependents[target].deps = dependents[target].deps.filter(x => x != me);
|
||||
if(dependents[target].deps.length == 0) delete_message(target, cfb);
|
||||
});
|
||||
delete dmeta[j];
|
||||
}
|
||||
|
||||
function shake() {
|
||||
var done = false;
|
||||
while(!done) {
|
||||
done = true;
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(fi.name.match(/\.plist/)) return;
|
||||
if(!fi.name.match(/\.iwa/)) return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content as Uint8Array);
|
||||
var x = parse_iwa_file(raw1);
|
||||
|
||||
(()=>{
|
||||
for(var i = 0; i < x.length; ++i) {
|
||||
var w = x[i];
|
||||
var type = varint_to_i32(w.messages[0].meta[1][0].data);
|
||||
if(w.id > 10000 && (!dependents[w.id] || !dependents[w.id]?.deps?.length)) {
|
||||
console.log(`Deleting orphan ${fp} ${w.id}`);
|
||||
delete_message(w.id, cfb);
|
||||
done = false;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
//fi.content = raw3;
|
||||
});
|
||||
gc(cfb);
|
||||
}
|
||||
}
|
||||
|
||||
/* Third pass: trim messages */
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(!fi?.name?.match(/\.iwa/)) return;
|
||||
var x = parse_iwa_file(decompress_iwa_file(fi.content as Uint8Array));
|
||||
|
||||
trim(x, fi);
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
fi.content = raw3;
|
||||
});
|
||||
gc(cfb);
|
||||
|
||||
shake();
|
||||
|
||||
function mutate_row(tri: ReturnType<typeof parse_shallow>) {
|
||||
if(!tri[6]?.[0] || !tri[7]?.[0]) throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if(wide_offsets) throw "Math only works with normal offsets";
|
||||
var dv = u8_to_dataview(tri[7][0].data);
|
||||
var old_sz = 0, sz = 0;
|
||||
for(var i = 0; i < tri[7][0].data.length / 2; ++i) {
|
||||
sz = dv.getUint16(i*2, true);
|
||||
if(sz < 65535) old_sz = sz;
|
||||
if(old_sz) break;
|
||||
}
|
||||
if(!old_sz) old_sz = sz = tri[6][0].data.length;
|
||||
var start = 0,
|
||||
preamble = tri[6][0].data.slice(0, start),
|
||||
intramble = tri[6][0].data.slice(start, old_sz),
|
||||
postamble = tri[6][0].data.slice(old_sz);
|
||||
var sst = []; sst[69] = "SheetJS";
|
||||
//intramble = write_new_storage({t:"n", v:12345}, sst);
|
||||
//intramble = write_new_storage({t:"b", v:false}, sst);
|
||||
intramble = write_new_storage({t:"s", v:"SheetJS"}, sst);
|
||||
tri[6][0].data = u8concat([preamble, intramble, postamble]);
|
||||
var delta = intramble.length - old_sz;
|
||||
for(var i = 0; i < tri[7][0].data.length / 2; ++i) {
|
||||
sz = dv.getUint16(i*2, true);
|
||||
if(sz < 65535 && sz > start) dv.setUint16(i*2, sz + delta, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find first sheet -> first table -> add "SheetJS" to data store and set cell A1 */
|
||||
(function() {
|
||||
var entry = find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
var docroot: IWAArchiveInfo;
|
||||
for(var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == 1) docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
|
||||
entry = find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
|
||||
entry = find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
|
||||
entry = find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content as Uint8Array));
|
||||
for(xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if(packet.id == sheetrootref) docroot = packet;
|
||||
}
|
||||
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
/* ref to string table */
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(() => {
|
||||
var sentry = find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content as Uint8Array));
|
||||
var sstroot: IWAArchiveInfo;
|
||||
for(var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet = sx[sxi];
|
||||
if(packet.id == sstref) sstroot = packet;
|
||||
}
|
||||
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
if(!sstdata[3]) sstdata[3] = [];
|
||||
var newsst: ReturnType<typeof parse_shallow> = [];
|
||||
newsst[1] = [ { type: 0, data: write_varint49(69) } ];
|
||||
newsst[2] = [ { type: 0, data: write_varint49(1) } ];
|
||||
newsst[3] = [ { type: 2, data: stru8("SheetJS") } ];
|
||||
sstdata[3].push({type: 2, data: write_shallow(newsst)});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw3 = compress_iwa_file(sy);
|
||||
sentry.content = raw3; sentry.size = sentry.content.length;
|
||||
})();
|
||||
|
||||
var tile = parse_shallow(store[3][0].data); // TileStorage
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data); // first Tile
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(() => {
|
||||
var tentry = find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content as Uint8Array));
|
||||
var tileroot: IWAArchiveInfo;
|
||||
for(var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet = tx[sxi];
|
||||
if(packet.id == tileref) tileroot = packet;
|
||||
}
|
||||
|
||||
// .TST.Tile
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
tiledata[5].forEach((row, R) => {
|
||||
var tilerow = parse_shallow(row.data);
|
||||
if(R == 0) mutate_row(tilerow);
|
||||
row.data = write_shallow(tilerow);
|
||||
})
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw3 = compress_iwa_file(ty);
|
||||
tentry.content = raw3; tentry.size = tentry.content.length;
|
||||
//throw dependents[tileref];
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3; entry.size = entry.content.length;
|
||||
})();
|
||||
|
||||
//console.log(indices.map(i => [i, dependents[i]]).filter(([i, dep]) => dep?.deps && (dep.deps.length == 0 || dep.deps.length == 1 && dep.deps[0] == 1)));
|
||||
|
||||
/* Last pass: fix metadata and commit to new file */
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(!fi?.name?.match(/\.iwa/)) return;
|
||||
var x = parse_iwa_file(decompress_iwa_file(fi.content as Uint8Array));
|
||||
|
||||
if(fi.name.match(/^Metadata.iwa$/)) {
|
||||
x.forEach((w: IWAArchiveInfo) => {
|
||||
var type = varint_to_i32(w.messages[0].meta[1][0].data);
|
||||
if(type != 11006) return;
|
||||
var package_metadata = parse_shallow(w.messages[0].data);
|
||||
[3,11].forEach(x => {
|
||||
if(!package_metadata[x]) return;
|
||||
for(var pmj = 0; pmj < package_metadata[x].length; ++pmj) {
|
||||
var ci = package_metadata[x][pmj];
|
||||
var comp = parse_shallow(ci.data);
|
||||
var compid = varint_to_i32(comp[1][0].data);
|
||||
if(!dependents[compid]) {
|
||||
console.log(`Removing ${compid} (${u8str(comp[2][0].data)} -> ${comp[3]?.[0] && u8str(comp[3][0].data) || ""}) from metadata`);
|
||||
package_metadata[x].splice(pmj, 1);
|
||||
--pmj; continue;
|
||||
}
|
||||
[13, 14, 15].forEach(j => delete comp[j]);
|
||||
ci.data = write_shallow(comp);
|
||||
}
|
||||
});
|
||||
[2, 4, 6, 8, 9].forEach(j => delete package_metadata[j]);
|
||||
w.messages[0].data = write_shallow(package_metadata);
|
||||
});
|
||||
}
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
fi.content = raw3;
|
||||
if(x.length == 0) {
|
||||
console.log(`Deleting ${fi.name} (no messages)`);
|
||||
return;
|
||||
}
|
||||
if(fi.name.match(/^Metadata.iwa$/)) {
|
||||
console.error(`Reframing iwa ${fi.name} (${fi.size} -> ${fi.content.length})`);
|
||||
fi.size = fi.content.length;
|
||||
utils.cfb_add(nuevo, row[1], fi.content);
|
||||
} else {
|
||||
console.error(`Reframing iwa ${fi.name} (${fi.size} -> ${fi.content.length})`);
|
||||
fi.size = fi.content.length;
|
||||
utils.cfb_add(nuevo, row[1], fi.content);
|
||||
}
|
||||
});
|
||||
|
||||
if(mode == 1) {
|
||||
var res = compress_iwa_file(u8concat(bufs));
|
||||
console.error(`Adding iwa Document.iwa (${res.length})`);
|
||||
utils.cfb_add(cfb, "/Index/Document.iwa", res);
|
||||
writeFile(nuevo, o, { fileType: "zip", compression: true });
|
||||
|
||||
function process_root(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
var tsa = parse_shallow(dmeta[8][0].data);
|
||||
{
|
||||
var tsk = parse_shallow(tsa[1][0].data);
|
||||
{
|
||||
[7, 8, 14].forEach(j => delete_ref(tsk, j, id)); // annotation_author_storage
|
||||
[4, 9, 10, 11, 12, 15, 16, 17].forEach(j => delete tsk[j]);
|
||||
}
|
||||
tsa[1][0].data = write_shallow(tsk);
|
||||
[5, 6, 7, 10, 11, 12, 13].forEach(j => delete_ref(tsa, j, 1));
|
||||
[3, 8, 9, 14, 15, 16].forEach(j => delete tsa[j]);
|
||||
}
|
||||
dmeta[8][0].data = write_shallow(tsa);
|
||||
}
|
||||
|
||||
function process_sheet(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 20, 21, 23, 24].forEach(j => delete dmeta[j]);
|
||||
[15, 16, 17, 18, 19, 22].forEach(j => delete_ref(dmeta, j, id));
|
||||
}
|
||||
|
||||
function process_TST_TableInfoArchive(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[7, 8, 9, 10, 14, 16].forEach(j => delete dmeta[j]);
|
||||
[3, 4, 5, 6, 15, 17].forEach(j => delete_ref(dmeta, j, id));
|
||||
}
|
||||
|
||||
function process_TST_TableModelArchive(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[90, 91, 92].forEach(j => delete dmeta[j]);
|
||||
[34, 35, 38, 49].forEach(j => delete_ref(dmeta, j, id));
|
||||
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69].forEach(j => delete_ref(dmeta, j, id));
|
||||
[70].forEach(j => delete dmeta[j]);
|
||||
[71, 72, 73, 74, 75, 76, 77, 78, 79, 80].forEach(j => delete_ref(dmeta, j, id));
|
||||
[85, 86, 87, 88, 89].forEach(j => delete_ref(dmeta, j, id));
|
||||
var store = parse_shallow(dmeta[4][0].data);
|
||||
{ // .TST.DataStore
|
||||
[12, 13, 15, 16, 17, 18, 19, 20, 21, 22].forEach(j => delete_ref(store, j, id));
|
||||
var tiles = parse_shallow(store[3][0].data);
|
||||
{ // .TST.TileStorage
|
||||
//console.log(parse_TSP_Reference(parse_shallow(tiles[1][0].data)[2][0].data));
|
||||
}
|
||||
store[3][0].data = write_shallow(tiles);
|
||||
// 4 -> sst
|
||||
// 17 -> rsst
|
||||
}
|
||||
dmeta[4][0].data = write_shallow(store);
|
||||
}
|
||||
|
||||
function process_TN_ThemeArchive(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[2].forEach(j => delete_ref(dmeta, j, id));
|
||||
var tssta = parse_shallow(dmeta[1][0].data);
|
||||
{
|
||||
//Object.keys(tssta).filter(x => +x >= 100).forEach(j => delete tssta[j]);
|
||||
}
|
||||
dmeta[1][0].data = write_shallow(tssta);
|
||||
}
|
||||
|
||||
function process_TSS_StylesheetArchive(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[7, 8, 9, 10, 11, 12].forEach(j => {
|
||||
if(!dmeta[j]) return;
|
||||
var vstyle = parse_shallow(dmeta[j][0].data);
|
||||
delete_ref(vstyle, 1, id);
|
||||
if(vstyle[2]) vstyle[2].forEach(ised => {
|
||||
var ise = parse_shallow(ised.data);
|
||||
delete_ref(ise, 2, id);
|
||||
})
|
||||
if(vstyle[3]) vstyle[3].forEach(sced => {
|
||||
var sce = parse_shallow(sced.data);
|
||||
delete_ref(sce, 2, id);
|
||||
delete_ref(sce, 1, id);
|
||||
})
|
||||
delete dmeta[j];
|
||||
});
|
||||
dmeta[4] = [{data: write_varint49(0), type: 0}];
|
||||
[3].forEach(j => delete_ref(dmeta, j, id));
|
||||
dmeta[5]?.forEach(pi => {
|
||||
var sce = parse_shallow(pi.data);
|
||||
delete_ref(sce, 1, id);
|
||||
delete_ref(sce, 2, id);
|
||||
}); delete dmeta[5];
|
||||
var deleted_styles = [];
|
||||
if(dmeta[2]) for(var pij = 0; pij < dmeta[2].length; ++pij) {
|
||||
var ise = parse_shallow(dmeta[2][pij].data);
|
||||
var sname = u8str(ise[1][0].data);
|
||||
if(sname.match(/_\d*$/) || sname.match(/^(captions|chart|image|movie|stickyComment)/) || sname.match(/evel[2-5]|pivot|liststyle/) ) {
|
||||
var deletedid = parse_TSP_Reference(ise[2][0].data);
|
||||
console.log(`Deleting style ${sname} [${deletedid}]`);
|
||||
deleted_styles.push(deletedid);
|
||||
delete_ref(ise, 2, id);
|
||||
dmeta[2].splice(pij,1);
|
||||
--pij; continue;
|
||||
} else console.log(`Keeping style ${sname}`)
|
||||
}
|
||||
if(dmeta[1]) for(var sj = 0; sj < dmeta[1].length; ++sj) {
|
||||
var dsid = parse_TSP_Reference(dmeta[1][sj].data);
|
||||
if(deleted_styles.indexOf(dsid) > -1) {
|
||||
//console.log(`Really deleting style ${dsid}`);
|
||||
dependents[dsid].deps = dependents[dsid].deps.filter(x => x != id);
|
||||
if(dependents[dsid].deps.length == 0) delete_message(dsid, cfb);
|
||||
dmeta[1].splice(sj, 1); --sj; continue;
|
||||
}
|
||||
}
|
||||
[6].forEach(j => delete dmeta[j]);
|
||||
}
|
||||
|
||||
function process_TSCE_CalculationEngineArchive(dmeta: ReturnType<typeof parse_shallow>, id: number) {
|
||||
[3, 12, 14, 15].forEach(j => delete_ref(dmeta, j, id));
|
||||
[1, 4, 5, 6, 7, 9, 10, 11, 13, 16, 17, 18].forEach(i => delete dmeta[i]);
|
||||
var dta = parse_shallow(dmeta[2][0].data);
|
||||
delete dta[5]; delete dta[2]; delete dta[4];
|
||||
delete dta[1]; delete dta[3]; delete_ref(dta, 6, id);
|
||||
dmeta[2][0].data = write_shallow(dta);
|
||||
}
|
||||
|
||||
function trim(x: IWAArchiveInfo[], fi: CFB$Entry) {
|
||||
for(var i = 0; i < x.length; ++i) {
|
||||
var w = x[i];
|
||||
var type = varint_to_i32(w.messages[0].meta[1][0].data);
|
||||
var dmeta = parse_shallow(w.messages[0].data);
|
||||
|
||||
switch(type) {
|
||||
case 222: // .TSK.CustomFormatListArchive
|
||||
case 601: // .TSA.FunctionBrowserStateArchive
|
||||
x.splice(i, 1); --i; continue;
|
||||
case 3047: break; // .TSD.GuideStorageArchive
|
||||
case 205: {
|
||||
} break; // .TSK.TreeNode
|
||||
|
||||
case 1: { // .TN.DocumentArchive
|
||||
process_root(dmeta, w.id);
|
||||
} break;
|
||||
case 2: { // .TN.SheetArchive
|
||||
process_sheet(dmeta, w.id);
|
||||
} break;
|
||||
case 6000: { // .TST.TableInfoArchive
|
||||
process_TST_TableInfoArchive(dmeta, w.id);
|
||||
} break;
|
||||
case 6001: { // .TST.TableModelArchive
|
||||
process_TST_TableModelArchive(dmeta, w.id)
|
||||
} break;
|
||||
case 401: { // .TSS.StylesheetArchive
|
||||
process_TSS_StylesheetArchive(dmeta, w.id);
|
||||
break;
|
||||
}
|
||||
case 11011: { // .TSP.DocumentMetadata
|
||||
[1, 3].forEach(i => delete dmeta[i]);
|
||||
} break;
|
||||
case 6002: {
|
||||
//process_TST_Tile(dmeta, w.id);
|
||||
} break; // .TST.Tile
|
||||
case 6005: break; // .TST.TableDataList
|
||||
case 6006: break; // .TST.HeaderStorageBucket
|
||||
case 2001: break; // .TSWP.StorageArchive
|
||||
case 12009: process_TN_ThemeArchive(dmeta, w.id); break; // .TN.ThemeArchive
|
||||
|
||||
case 3097: break; // .TSD.StandinCaptionArchive
|
||||
case 4000: process_TSCE_CalculationEngineArchive(dmeta, w.id); break; // .TSCE.CalculationEngineArchive
|
||||
case 4003: break; // .TSCE.NamedReferenceManagerArchive
|
||||
case 4004: break; // .TSCE.TrackedReferenceStoreArchive
|
||||
case 4008: { // .TSCE.FormulaOwnerDependenciesArchive
|
||||
[11].forEach(j => delete_ref(dmeta, j, w.id));
|
||||
[3].forEach(i => delete dmeta[i]);
|
||||
} break;
|
||||
case 4009: { // .TSCE.CellRecordTileArchive
|
||||
delete dmeta[4];
|
||||
} break;
|
||||
case 6267: { // .TST.ColumnRowUIDMapArchive
|
||||
// console.log("CRUIDMA", dmeta[1]?.[0], dmeta[2]?.[0], dmeta[3]?.[0]);
|
||||
//[1,2,3,4,5,6].forEach(j => delete dmeta[j]); break;
|
||||
} break;
|
||||
case 6366: break; // .TST.HeaderNameMgrArchive
|
||||
case 6204: break; // .TST.HiddenStateFormulaOwnerArchive
|
||||
case 6220: break; // .TST.FilterSetArchive
|
||||
case 6305: break; // .TST.StrokeSidecarArchive
|
||||
case 6316: break; // .TST.SummaryModelArchive
|
||||
case 6317: break; // .TST.SummaryCellVendorArchive
|
||||
case 6318: break; // .TST.CategoryOrderArchive
|
||||
case 6372: break; // .TST.CategoryOwnerRefArchive
|
||||
case 6373: break; // .TST.GroupByArchive
|
||||
case 2043: [2,3,4].forEach(j => delete dmeta[j]); break; // .TSWP.NumberAttachmentArchive
|
||||
|
||||
case 5020: // .TSCH.ChartStylePreset
|
||||
//[1,2,3,4,5,6].forEach(j => delete_ref(dmeta, j, w.id)); // some part of this is required to auto-save
|
||||
Object.keys(dmeta).filter(x => +x >= 10000).forEach(j => delete dmeta[j]);
|
||||
break;
|
||||
case 5022: // .TSCH.ChartStyleArchive
|
||||
case 5024: // .TSCH.LegendStyleArchive
|
||||
case 5026: // .TSCH.ChartAxisStyleArchive
|
||||
case 5028: // .TSCH.ChartSeriesStyleArchive
|
||||
case 5030: // .TSCH.ReferenceLineStyleArchive
|
||||
Object.keys(dmeta).filter(x => +x >= 10000).forEach(j => delete dmeta[j]);
|
||||
break;
|
||||
case 2021: break;
|
||||
case 2022: [10,11,12].forEach(j => delete dmeta[j]); break; // .TSWP.ParagraphStyleArchive
|
||||
case 2023: [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25].forEach(j => delete dmeta[j]); break; // .TSWP.ListStyleArchive
|
||||
case 3016: [10,11].forEach(j => delete dmeta[j]); break; // .TSD.MediaStyleArchive
|
||||
case 2025: /* [10,11].forEach(j => delete dmeta[j]); */ break; // .TSWP.ShapeStyleArchive
|
||||
case 6003: /* [10,11].forEach(j => delete dmeta[j]); */ break; // .TST.TableStyleArchive
|
||||
case 6004: /* [10,11].forEach(j => delete dmeta[j]); */ break; // .TST.CellStyleArchive
|
||||
case 10024: [10,11,12].forEach(j => delete dmeta[j]); break; // .TN.DropCapStyleArchive
|
||||
case 12050: /* [2,3].forEach(j => delete dmeta[j]); */ break; // .TN.SheetStyleArchive
|
||||
case 3045: break; // .TSD.CanvasSelectionArchive
|
||||
|
||||
case 6008: {
|
||||
[1].forEach(j => delete dmeta[j]);
|
||||
[2].forEach(j => delete_ref(dmeta, j, w.id));
|
||||
// deleting 3 -> -[TSWPLayoutManager initWithStorage:owner:] /Library/Caches/com.apple.xbs/Sources/iWorkDependenciesMacOS/iWorkDependenciesMacOS-7032.0.145/shared/text/TSWPLayoutManager.mm:82 Cannot initialize with a nil storage.
|
||||
} break; // .TST.TableStylePresetArchive
|
||||
|
||||
case 6247: {
|
||||
[ 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ].forEach(j => delete_ref(dmeta, j, w.id));
|
||||
} break; // .TST.TableStyleNetworkArchive
|
||||
|
||||
case 210: { // .TSK.ViewStateArchive
|
||||
[2, 3].forEach(i => delete dmeta[i]);
|
||||
} break;
|
||||
case 12026: { // .TN.UIStateArchive
|
||||
delete dmeta[13];
|
||||
} break;
|
||||
|
||||
case 219: delete dmeta[1]; break; // .DocumentSelectionArchive
|
||||
|
||||
case 12028: break; // .TN.SheetSelectionArchive
|
||||
case 3061: { // .TSD.DrawableSelectionArchive
|
||||
[3].forEach(j => delete_ref(dmeta, j, w.id));
|
||||
} break;
|
||||
case 3091: { // .TSD.FreehandDrawingToolkitUIState
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].forEach(i => delete dmeta[i]);
|
||||
} break;
|
||||
|
||||
/* Metadata.iwa */
|
||||
case 11006: { // .TSP.PackageMetadata
|
||||
[10].forEach(j => delete_ref(dmeta, j, w.id));
|
||||
} break;
|
||||
case 11014: // .TSP.DataMetadata
|
||||
[1].forEach(j => delete dmeta[j]);
|
||||
break;
|
||||
case 11015: // .TSP.DataMetadataMap
|
||||
dmeta?.[1]?.forEach((r, idx) => {
|
||||
var ddmeta = parse_shallow(r.data);
|
||||
[2].forEach(j => delete_ref(ddmeta, j, w.id));
|
||||
});
|
||||
delete dmeta[1];
|
||||
dmeta.length = 0;
|
||||
break;
|
||||
|
||||
/* AnnotationAuthorStorage.iwa */
|
||||
case 213: break; // TSK.AnnotationAuthorStorageArchive
|
||||
|
||||
default:
|
||||
console.log("!!", fi.name, type, w.id, w.messages.length);
|
||||
}
|
||||
w.messages[0].data = write_shallow(dmeta);
|
||||
}
|
||||
}
|
||||
writeFile(cfb, o, {fileType: "zip"});
|
||||
|
22
modules/reframe.sh
Executable file
22
modules/reframe.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
INF=${1:-test.numbers}
|
||||
OUTF=${2:-reframed.numbers}
|
||||
make reframe.node.js
|
||||
node reframe.node.js "$INF" "$OUTF"
|
||||
# cat-numbers "$OUTF"
|
||||
chmod a+w "$OUTF"
|
||||
sleep 0.1
|
||||
# open "$OUTF"
|
||||
unzip -l "$OUTF"
|
||||
base64 "$OUTF" > xlsx.zahl.js
|
||||
sed -i.bak 's/^/var XLSX_ZAHL_PAYLOAD = "/g;s/$/";/g' xlsx.zahl.js
|
||||
cp xlsx.zahl.js xlsx.zahl.mjs
|
||||
cat >> xlsx.zahl.js <<EOF
|
||||
if(typeof module !== "undefined") module.exports = XLSX_ZAHL_PAYLOAD;
|
||||
else if(typeof global !== "undefined") global.XLSX_ZAHL_PAYLOAD = XLSX_ZAHL_PAYLOAD;
|
||||
else if(typeof window !== "undefined") window.XLSX_ZAHL_PAYLOAD = XLSX_ZAHL_PAYLOAD;
|
||||
EOF
|
||||
cat >> xlsx.zahl.mjs <<EOF
|
||||
export default XLSX_ZAHL_PAYLOAD;
|
||||
EOF
|
@ -42,7 +42,10 @@ declare function write_XLWideString(data: string, o?: WritableData): RawData;
|
||||
declare function writeuint16(x: number): RawData;
|
||||
|
||||
declare function utf8read(x: string): string;
|
||||
declare function utf8write(x: string): string;
|
||||
|
||||
declare function a2s(a: RawData): string;
|
||||
declare function s2a(s: string): RawData;
|
||||
|
||||
interface ParseXLMetaOptions {
|
||||
WTF?: number|boolean;
|
||||
|
BIN
modules/test.numbers
Executable file
BIN
modules/test.numbers
Executable file
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.18.4",
|
||||
"version": "0.18.5",
|
||||
"author": "sheetjs",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [
|
||||
|
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@ -260,6 +260,9 @@ export interface WritingOptions extends CommonOptions, SheetOption {
|
||||
|
||||
/** Override workbook properties on save */
|
||||
Props?: Properties;
|
||||
|
||||
/** Base64 encoding of NUMBERS base for exports */
|
||||
numbers?: string;
|
||||
}
|
||||
|
||||
/** Workbook Object */
|
||||
|
472
xlsx.flow.js
472
xlsx.flow.js
@ -4,7 +4,7 @@
|
||||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.4';
|
||||
XLSX.version = '0.18.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true, window */
|
||||
@ -22000,6 +22000,19 @@ function u8_to_dataview(array) {
|
||||
function u8str(u8) {
|
||||
return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
|
||||
}
|
||||
function stru8(str) {
|
||||
return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
|
||||
}
|
||||
function u8contains(body, search) {
|
||||
outer:
|
||||
for (var L = 0; L <= body.length - search.length; ++L) {
|
||||
for (var j = 0; j < search.length; ++j)
|
||||
if (body[L + j] != search[j])
|
||||
continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function u8concat(u8a) {
|
||||
var len = u8a.reduce(function(acc, x) {
|
||||
return acc + x.length;
|
||||
@ -22024,6 +22037,15 @@ function readDecimal128LE(buf, offset) {
|
||||
mantissa = mantissa * 256 + buf[j];
|
||||
return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
|
||||
}
|
||||
function writeDecimal128LE(buf, offset, value) {
|
||||
var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
|
||||
var mantissa = value / Math.pow(10, exp - 6176);
|
||||
buf[offset + 15] |= exp >> 7;
|
||||
buf[offset + 14] |= (exp & 127) << 1;
|
||||
for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
|
||||
buf[offset + i] = mantissa & 255;
|
||||
buf[offset + 15] |= value >= 0 ? 0 : 128;
|
||||
}
|
||||
function parse_varint49(buf, ptr) {
|
||||
var l = ptr ? ptr[0] : 0;
|
||||
var usz = buf[l] & 127;
|
||||
@ -22149,7 +22171,7 @@ function parse_shallow(buf) {
|
||||
default:
|
||||
throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
|
||||
}
|
||||
var v = { offset: off, data: res, type: type };
|
||||
var v = { data: res, type: type };
|
||||
if (out[num] == null)
|
||||
out[num] = [v];
|
||||
else
|
||||
@ -22161,6 +22183,8 @@ function write_shallow(proto) {
|
||||
var out = [];
|
||||
proto.forEach(function(field, idx) {
|
||||
field.forEach(function(item) {
|
||||
if (!item.data)
|
||||
return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if (item.type == 2)
|
||||
out.push(write_varint49(item.data.length));
|
||||
@ -22170,21 +22194,12 @@ function write_shallow(proto) {
|
||||
return u8concat(out);
|
||||
}
|
||||
function mappa(data, cb) {
|
||||
if (!data)
|
||||
return [];
|
||||
return data.map(function(d) {
|
||||
var _a;
|
||||
try {
|
||||
return (data == null ? void 0 : data.map(function(d) {
|
||||
return cb(d.data);
|
||||
} catch (e) {
|
||||
var m = (_a = e.message) == null ? void 0 : _a.match(/at offset (\d+)/);
|
||||
if (m)
|
||||
e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})) || [];
|
||||
}
|
||||
function parse_iwa_file(buf) {
|
||||
var _a;
|
||||
var out = [], ptr = [0];
|
||||
while (ptr[0] < buf.length) {
|
||||
var len = parse_varint49(buf, ptr);
|
||||
@ -22203,10 +22218,35 @@ function parse_iwa_file(buf) {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if ((_a = ai[3]) == null ? void 0 : _a[0])
|
||||
res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function write_iwa_file(ias) {
|
||||
var bufs = [];
|
||||
ias.forEach(function(ia) {
|
||||
var ai = [];
|
||||
ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
|
||||
ai[2] = [];
|
||||
if (ia.merge != null)
|
||||
ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
|
||||
var midata = [];
|
||||
ia.messages.forEach(function(mi) {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
|
||||
ai[2].push({ data: write_shallow(mi.meta), type: 2 });
|
||||
});
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(function(mid) {
|
||||
return bufs.push(mid);
|
||||
});
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
function parse_snappy_chunk(type, buf) {
|
||||
if (type != 0)
|
||||
throw new Error("Unexpected Snappy chunk type ".concat(type));
|
||||
@ -22361,7 +22401,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22383,7 +22423,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function parse_storage(buf, sst, rsst) {
|
||||
function parse_new_storage(buf, sst, rsst) {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
var data_offset = 12;
|
||||
@ -22425,7 +22465,7 @@ function parse_storage(buf, sst, rsst) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22446,6 +22486,66 @@ function parse_storage(buf, sst, rsst) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function write_new_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[1] = 2;
|
||||
writeDecimal128LE(out, l, cell.v);
|
||||
flags |= 1;
|
||||
l += 16;
|
||||
break;
|
||||
case "b":
|
||||
out[1] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 2;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[1] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 8;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[2] = 2;
|
||||
dv.setFloat64(l, cell.v, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "b":
|
||||
out[2] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[2] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 16;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function parse_cell_storage(buf, sst, rsst) {
|
||||
switch (buf[0]) {
|
||||
case 0:
|
||||
@ -22454,7 +22554,7 @@ function parse_cell_storage(buf, sst, rsst) {
|
||||
case 3:
|
||||
return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5:
|
||||
return parse_storage(buf, sst, rsst);
|
||||
return parse_new_storage(buf, sst, rsst);
|
||||
default:
|
||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||
}
|
||||
@ -22463,6 +22563,11 @@ function parse_TSP_Reference(buf) {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx) {
|
||||
var out = [];
|
||||
out[1] = [{ type: 0, data: write_varint49(idx) }];
|
||||
return write_shallow(out);
|
||||
}
|
||||
function parse_TST_TableDataList(M, root) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var type = varint_to_i32(pb[1][0].data);
|
||||
@ -22521,6 +22626,7 @@ function parse_TST_TileRowInfo(u8, type) {
|
||||
var cells = [];
|
||||
for (C = 0; C < offsets.length - 1; ++C)
|
||||
cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
|
||||
if (offsets.length >= 1)
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R: R, cells: cells };
|
||||
}
|
||||
@ -22627,7 +22733,7 @@ function parse_TN_DocumentArchive(M, root) {
|
||||
}
|
||||
function parse_numbers_iwa(cfb) {
|
||||
var _a, _b, _c, _d;
|
||||
var out = {}, indices = [];
|
||||
var M = {}, indices = [];
|
||||
cfb.FullPaths.forEach(function(p) {
|
||||
if (p.match(/\.iwpv2/))
|
||||
throw new Error("Unsupported password protection");
|
||||
@ -22648,16 +22754,16 @@ function parse_numbers_iwa(cfb) {
|
||||
return console.log("## " + (e.message || e));
|
||||
}
|
||||
packets.forEach(function(packet) {
|
||||
out[packet.id] = packet.messages;
|
||||
M[packet.id] = packet.messages;
|
||||
indices.push(packet.id);
|
||||
});
|
||||
});
|
||||
if (!indices.length)
|
||||
throw new Error("File has no messages");
|
||||
var docroot = ((_d = (_c = (_b = (_a = out == null ? void 0 : out[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if (!docroot)
|
||||
indices.forEach(function(idx) {
|
||||
out[idx].forEach(function(iwam) {
|
||||
M[idx].forEach(function(iwam) {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if (mtype == 1) {
|
||||
if (!docroot)
|
||||
@ -22669,7 +22775,325 @@ function parse_numbers_iwa(cfb) {
|
||||
});
|
||||
if (!docroot)
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({ t: "s", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "s", v: data[C] }, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({ t: "n", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "n", v: data[C] }, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({ t: "b", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "b", v: data[C] }, SST);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if (wb.SheetNames.length > 1)
|
||||
console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
var data = sheet_to_json(ws, { range: range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(function(row) {
|
||||
return row.forEach(function(cell) {
|
||||
if (typeof cell == "string")
|
||||
SST.push(cell);
|
||||
});
|
||||
});
|
||||
var dependents = {};
|
||||
var indices = [];
|
||||
var cfb = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (fi.type != 2)
|
||||
return;
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content);
|
||||
var x2 = parse_iwa_file(raw1);
|
||||
x2.forEach(function(packet2) {
|
||||
indices.push(packet2.id);
|
||||
dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
indices.sort(function(x2, y2) {
|
||||
return x2 - y2;
|
||||
});
|
||||
var indices_varint = indices.filter(function(x2) {
|
||||
return x2 > 1;
|
||||
}).map(function(x2) {
|
||||
return [x2, write_varint49(x2)];
|
||||
});
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
|
||||
x2.forEach(function(ia) {
|
||||
ia.messages.forEach(function(m) {
|
||||
indices_varint.forEach(function(ivi) {
|
||||
if (ia.messages.some(function(mess) {
|
||||
return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
|
||||
})) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function get_unique_msgid() {
|
||||
for (var i = 927262; i < 2e6; ++i)
|
||||
if (!dependents[i])
|
||||
return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
var docroot;
|
||||
for (var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if (packet.id == 1)
|
||||
docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
for (var j = 0; j < _x.length; ++j) {
|
||||
if (_x[j].id == cruidsref)
|
||||
break;
|
||||
}
|
||||
if (_x[j].id != cruidsref)
|
||||
throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = [];
|
||||
cruids[2] = [], cruids[3] = [];
|
||||
for (var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
|
||||
cruids[1].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[2].push({ type: 0, data: write_varint49(C) });
|
||||
cruids[3].push({ type: 0, data: write_varint49(C) });
|
||||
}
|
||||
cruids[4] = [];
|
||||
cruids[5] = [], cruids[6] = [];
|
||||
for (var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
|
||||
cruids[4].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[5].push({ type: 0, data: write_varint49(R) });
|
||||
cruids[6].push({ type: 0, data: write_varint49(R) });
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != col_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(function() {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
|
||||
var sstroot;
|
||||
for (var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet2 = sx[sxi];
|
||||
if (packet2.id == sstref)
|
||||
sstroot = packet2;
|
||||
}
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst = [];
|
||||
SST.forEach(function(str, i) {
|
||||
newsst[1] = [{ type: 0, data: write_varint49(i) }];
|
||||
newsst[2] = [{ type: 0, data: write_varint49(1) }];
|
||||
newsst[3] = [{ type: 2, data: stru8(str) }];
|
||||
sstdata[3].push({ type: 2, data: write_shallow(newsst) });
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw32 = compress_iwa_file(sy);
|
||||
sentry.content = raw32;
|
||||
sentry.size = sentry.content.length;
|
||||
})();
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(function() {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
|
||||
var tileroot;
|
||||
for (var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet2 = tx[sxi];
|
||||
if (packet2.id == tileref)
|
||||
tileroot = packet2;
|
||||
}
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6];
|
||||
delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw32 = compress_iwa_file(ty);
|
||||
tentry.content = raw32;
|
||||
tentry.size = tentry.content.length;
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3;
|
||||
entry.size = entry.content.length;
|
||||
return cfb;
|
||||
}
|
||||
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
|
||||
return function fix_opts(opts) {
|
||||
@ -23010,6 +23434,7 @@ function parse_xlsxcfb(cfb, _opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
||||
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
|
||||
if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
|
||||
return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
@ -23578,6 +24003,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'xlsm':
|
||||
case 'xlam':
|
||||
case 'xlsb':
|
||||
case 'numbers':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
|
472
xlsx.js
generated
472
xlsx.js
generated
@ -4,7 +4,7 @@
|
||||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.4';
|
||||
XLSX.version = '0.18.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true, window */
|
||||
var $cptable;
|
||||
@ -21889,6 +21889,19 @@ function u8_to_dataview(array) {
|
||||
function u8str(u8) {
|
||||
return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
|
||||
}
|
||||
function stru8(str) {
|
||||
return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
|
||||
}
|
||||
function u8contains(body, search) {
|
||||
outer:
|
||||
for (var L = 0; L <= body.length - search.length; ++L) {
|
||||
for (var j = 0; j < search.length; ++j)
|
||||
if (body[L + j] != search[j])
|
||||
continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function u8concat(u8a) {
|
||||
var len = u8a.reduce(function(acc, x) {
|
||||
return acc + x.length;
|
||||
@ -21913,6 +21926,15 @@ function readDecimal128LE(buf, offset) {
|
||||
mantissa = mantissa * 256 + buf[j];
|
||||
return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
|
||||
}
|
||||
function writeDecimal128LE(buf, offset, value) {
|
||||
var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
|
||||
var mantissa = value / Math.pow(10, exp - 6176);
|
||||
buf[offset + 15] |= exp >> 7;
|
||||
buf[offset + 14] |= (exp & 127) << 1;
|
||||
for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
|
||||
buf[offset + i] = mantissa & 255;
|
||||
buf[offset + 15] |= value >= 0 ? 0 : 128;
|
||||
}
|
||||
function parse_varint49(buf, ptr) {
|
||||
var l = ptr ? ptr[0] : 0;
|
||||
var usz = buf[l] & 127;
|
||||
@ -22038,7 +22060,7 @@ function parse_shallow(buf) {
|
||||
default:
|
||||
throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
|
||||
}
|
||||
var v = { offset: off, data: res, type: type };
|
||||
var v = { data: res, type: type };
|
||||
if (out[num] == null)
|
||||
out[num] = [v];
|
||||
else
|
||||
@ -22050,6 +22072,8 @@ function write_shallow(proto) {
|
||||
var out = [];
|
||||
proto.forEach(function(field, idx) {
|
||||
field.forEach(function(item) {
|
||||
if (!item.data)
|
||||
return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if (item.type == 2)
|
||||
out.push(write_varint49(item.data.length));
|
||||
@ -22059,21 +22083,12 @@ function write_shallow(proto) {
|
||||
return u8concat(out);
|
||||
}
|
||||
function mappa(data, cb) {
|
||||
if (!data)
|
||||
return [];
|
||||
return data.map(function(d) {
|
||||
var _a;
|
||||
try {
|
||||
return (data == null ? void 0 : data.map(function(d) {
|
||||
return cb(d.data);
|
||||
} catch (e) {
|
||||
var m = (_a = e.message) == null ? void 0 : _a.match(/at offset (\d+)/);
|
||||
if (m)
|
||||
e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})) || [];
|
||||
}
|
||||
function parse_iwa_file(buf) {
|
||||
var _a;
|
||||
var out = [], ptr = [0];
|
||||
while (ptr[0] < buf.length) {
|
||||
var len = parse_varint49(buf, ptr);
|
||||
@ -22092,10 +22107,35 @@ function parse_iwa_file(buf) {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if ((_a = ai[3]) == null ? void 0 : _a[0])
|
||||
res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function write_iwa_file(ias) {
|
||||
var bufs = [];
|
||||
ias.forEach(function(ia) {
|
||||
var ai = [];
|
||||
ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
|
||||
ai[2] = [];
|
||||
if (ia.merge != null)
|
||||
ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
|
||||
var midata = [];
|
||||
ia.messages.forEach(function(mi) {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
|
||||
ai[2].push({ data: write_shallow(mi.meta), type: 2 });
|
||||
});
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(function(mid) {
|
||||
return bufs.push(mid);
|
||||
});
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
function parse_snappy_chunk(type, buf) {
|
||||
if (type != 0)
|
||||
throw new Error("Unexpected Snappy chunk type ".concat(type));
|
||||
@ -22250,7 +22290,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22272,7 +22312,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function parse_storage(buf, sst, rsst) {
|
||||
function parse_new_storage(buf, sst, rsst) {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
var data_offset = 12;
|
||||
@ -22314,7 +22354,7 @@ function parse_storage(buf, sst, rsst) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22335,6 +22375,66 @@ function parse_storage(buf, sst, rsst) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function write_new_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[1] = 2;
|
||||
writeDecimal128LE(out, l, cell.v);
|
||||
flags |= 1;
|
||||
l += 16;
|
||||
break;
|
||||
case "b":
|
||||
out[1] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 2;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[1] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 8;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[2] = 2;
|
||||
dv.setFloat64(l, cell.v, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "b":
|
||||
out[2] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[2] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 16;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function parse_cell_storage(buf, sst, rsst) {
|
||||
switch (buf[0]) {
|
||||
case 0:
|
||||
@ -22343,7 +22443,7 @@ function parse_cell_storage(buf, sst, rsst) {
|
||||
case 3:
|
||||
return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5:
|
||||
return parse_storage(buf, sst, rsst);
|
||||
return parse_new_storage(buf, sst, rsst);
|
||||
default:
|
||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||
}
|
||||
@ -22352,6 +22452,11 @@ function parse_TSP_Reference(buf) {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx) {
|
||||
var out = [];
|
||||
out[1] = [{ type: 0, data: write_varint49(idx) }];
|
||||
return write_shallow(out);
|
||||
}
|
||||
function parse_TST_TableDataList(M, root) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var type = varint_to_i32(pb[1][0].data);
|
||||
@ -22410,6 +22515,7 @@ function parse_TST_TileRowInfo(u8, type) {
|
||||
var cells = [];
|
||||
for (C = 0; C < offsets.length - 1; ++C)
|
||||
cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
|
||||
if (offsets.length >= 1)
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R: R, cells: cells };
|
||||
}
|
||||
@ -22516,7 +22622,7 @@ function parse_TN_DocumentArchive(M, root) {
|
||||
}
|
||||
function parse_numbers_iwa(cfb) {
|
||||
var _a, _b, _c, _d;
|
||||
var out = {}, indices = [];
|
||||
var M = {}, indices = [];
|
||||
cfb.FullPaths.forEach(function(p) {
|
||||
if (p.match(/\.iwpv2/))
|
||||
throw new Error("Unsupported password protection");
|
||||
@ -22537,16 +22643,16 @@ function parse_numbers_iwa(cfb) {
|
||||
return console.log("## " + (e.message || e));
|
||||
}
|
||||
packets.forEach(function(packet) {
|
||||
out[packet.id] = packet.messages;
|
||||
M[packet.id] = packet.messages;
|
||||
indices.push(packet.id);
|
||||
});
|
||||
});
|
||||
if (!indices.length)
|
||||
throw new Error("File has no messages");
|
||||
var docroot = ((_d = (_c = (_b = (_a = out == null ? void 0 : out[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if (!docroot)
|
||||
indices.forEach(function(idx) {
|
||||
out[idx].forEach(function(iwam) {
|
||||
M[idx].forEach(function(iwam) {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if (mtype == 1) {
|
||||
if (!docroot)
|
||||
@ -22558,7 +22664,325 @@ function parse_numbers_iwa(cfb) {
|
||||
});
|
||||
if (!docroot)
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({ t: "s", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "s", v: data[C] }, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({ t: "n", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "n", v: data[C] }, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({ t: "b", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "b", v: data[C] }, SST);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if (wb.SheetNames.length > 1)
|
||||
console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
var data = sheet_to_json(ws, { range: range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(function(row) {
|
||||
return row.forEach(function(cell) {
|
||||
if (typeof cell == "string")
|
||||
SST.push(cell);
|
||||
});
|
||||
});
|
||||
var dependents = {};
|
||||
var indices = [];
|
||||
var cfb = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (fi.type != 2)
|
||||
return;
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content);
|
||||
var x2 = parse_iwa_file(raw1);
|
||||
x2.forEach(function(packet2) {
|
||||
indices.push(packet2.id);
|
||||
dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
indices.sort(function(x2, y2) {
|
||||
return x2 - y2;
|
||||
});
|
||||
var indices_varint = indices.filter(function(x2) {
|
||||
return x2 > 1;
|
||||
}).map(function(x2) {
|
||||
return [x2, write_varint49(x2)];
|
||||
});
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
|
||||
x2.forEach(function(ia) {
|
||||
ia.messages.forEach(function(m) {
|
||||
indices_varint.forEach(function(ivi) {
|
||||
if (ia.messages.some(function(mess) {
|
||||
return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
|
||||
})) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function get_unique_msgid() {
|
||||
for (var i = 927262; i < 2e6; ++i)
|
||||
if (!dependents[i])
|
||||
return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
var docroot;
|
||||
for (var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if (packet.id == 1)
|
||||
docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
for (var j = 0; j < _x.length; ++j) {
|
||||
if (_x[j].id == cruidsref)
|
||||
break;
|
||||
}
|
||||
if (_x[j].id != cruidsref)
|
||||
throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = [];
|
||||
cruids[2] = [], cruids[3] = [];
|
||||
for (var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
|
||||
cruids[1].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[2].push({ type: 0, data: write_varint49(C) });
|
||||
cruids[3].push({ type: 0, data: write_varint49(C) });
|
||||
}
|
||||
cruids[4] = [];
|
||||
cruids[5] = [], cruids[6] = [];
|
||||
for (var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
|
||||
cruids[4].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[5].push({ type: 0, data: write_varint49(R) });
|
||||
cruids[6].push({ type: 0, data: write_varint49(R) });
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != col_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(function() {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
|
||||
var sstroot;
|
||||
for (var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet2 = sx[sxi];
|
||||
if (packet2.id == sstref)
|
||||
sstroot = packet2;
|
||||
}
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst = [];
|
||||
SST.forEach(function(str, i) {
|
||||
newsst[1] = [{ type: 0, data: write_varint49(i) }];
|
||||
newsst[2] = [{ type: 0, data: write_varint49(1) }];
|
||||
newsst[3] = [{ type: 2, data: stru8(str) }];
|
||||
sstdata[3].push({ type: 2, data: write_shallow(newsst) });
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw32 = compress_iwa_file(sy);
|
||||
sentry.content = raw32;
|
||||
sentry.size = sentry.content.length;
|
||||
})();
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(function() {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
|
||||
var tileroot;
|
||||
for (var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet2 = tx[sxi];
|
||||
if (packet2.id == tileref)
|
||||
tileroot = packet2;
|
||||
}
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6];
|
||||
delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw32 = compress_iwa_file(ty);
|
||||
tentry.content = raw32;
|
||||
tentry.size = tentry.content.length;
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3;
|
||||
entry.size = entry.content.length;
|
||||
return cfb;
|
||||
}
|
||||
function fix_opts_func(defaults) {
|
||||
return function fix_opts(opts) {
|
||||
@ -22897,6 +23321,7 @@ if(einfo[0] == 0x02 && typeof decrypt_std76 !== 'undefined') return decrypt_std7
|
||||
|
||||
function write_zip(wb, opts) {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
|
||||
if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
|
||||
return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
@ -23462,6 +23887,7 @@ function writeSync(wb, opts) {
|
||||
case 'xlsm':
|
||||
case 'xlam':
|
||||
case 'xlsb':
|
||||
case 'numbers':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
744
xlsx.mini.js
744
xlsx.mini.js
File diff suppressed because it is too large
Load Diff
472
xlsx.mjs
generated
472
xlsx.mjs
generated
@ -3,7 +3,7 @@
|
||||
/*exported XLSX */
|
||||
/*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
XLSX.version = '0.18.4';
|
||||
XLSX.version = '0.18.5';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
|
||||
@ -21998,6 +21998,19 @@ function u8_to_dataview(array) {
|
||||
function u8str(u8) {
|
||||
return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
|
||||
}
|
||||
function stru8(str) {
|
||||
return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
|
||||
}
|
||||
function u8contains(body, search) {
|
||||
outer:
|
||||
for (var L = 0; L <= body.length - search.length; ++L) {
|
||||
for (var j = 0; j < search.length; ++j)
|
||||
if (body[L + j] != search[j])
|
||||
continue outer;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function u8concat(u8a) {
|
||||
var len = u8a.reduce(function(acc, x) {
|
||||
return acc + x.length;
|
||||
@ -22022,6 +22035,15 @@ function readDecimal128LE(buf, offset) {
|
||||
mantissa = mantissa * 256 + buf[j];
|
||||
return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
|
||||
}
|
||||
function writeDecimal128LE(buf, offset, value) {
|
||||
var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
|
||||
var mantissa = value / Math.pow(10, exp - 6176);
|
||||
buf[offset + 15] |= exp >> 7;
|
||||
buf[offset + 14] |= (exp & 127) << 1;
|
||||
for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
|
||||
buf[offset + i] = mantissa & 255;
|
||||
buf[offset + 15] |= value >= 0 ? 0 : 128;
|
||||
}
|
||||
function parse_varint49(buf, ptr) {
|
||||
var l = ptr ? ptr[0] : 0;
|
||||
var usz = buf[l] & 127;
|
||||
@ -22147,7 +22169,7 @@ function parse_shallow(buf) {
|
||||
default:
|
||||
throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
|
||||
}
|
||||
var v = { offset: off, data: res, type: type };
|
||||
var v = { data: res, type: type };
|
||||
if (out[num] == null)
|
||||
out[num] = [v];
|
||||
else
|
||||
@ -22159,6 +22181,8 @@ function write_shallow(proto) {
|
||||
var out = [];
|
||||
proto.forEach(function(field, idx) {
|
||||
field.forEach(function(item) {
|
||||
if (!item.data)
|
||||
return;
|
||||
out.push(write_varint49(idx * 8 + item.type));
|
||||
if (item.type == 2)
|
||||
out.push(write_varint49(item.data.length));
|
||||
@ -22168,21 +22192,12 @@ function write_shallow(proto) {
|
||||
return u8concat(out);
|
||||
}
|
||||
function mappa(data, cb) {
|
||||
if (!data)
|
||||
return [];
|
||||
return data.map(function(d) {
|
||||
var _a;
|
||||
try {
|
||||
return (data == null ? void 0 : data.map(function(d) {
|
||||
return cb(d.data);
|
||||
} catch (e) {
|
||||
var m = (_a = e.message) == null ? void 0 : _a.match(/at offset (\d+)/);
|
||||
if (m)
|
||||
e.message = e.message.replace(/at offset (\d+)/, "at offset " + (+m[1] + d.offset));
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
})) || [];
|
||||
}
|
||||
function parse_iwa_file(buf) {
|
||||
var _a;
|
||||
var out = [], ptr = [0];
|
||||
while (ptr[0] < buf.length) {
|
||||
var len = parse_varint49(buf, ptr);
|
||||
@ -22201,10 +22216,35 @@ function parse_iwa_file(buf) {
|
||||
});
|
||||
ptr[0] += fl;
|
||||
});
|
||||
if ((_a = ai[3]) == null ? void 0 : _a[0])
|
||||
res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
|
||||
out.push(res);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
function write_iwa_file(ias) {
|
||||
var bufs = [];
|
||||
ias.forEach(function(ia) {
|
||||
var ai = [];
|
||||
ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
|
||||
ai[2] = [];
|
||||
if (ia.merge != null)
|
||||
ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
|
||||
var midata = [];
|
||||
ia.messages.forEach(function(mi) {
|
||||
midata.push(mi.data);
|
||||
mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
|
||||
ai[2].push({ data: write_shallow(mi.meta), type: 2 });
|
||||
});
|
||||
var aipayload = write_shallow(ai);
|
||||
bufs.push(write_varint49(aipayload.length));
|
||||
bufs.push(aipayload);
|
||||
midata.forEach(function(mid) {
|
||||
return bufs.push(mid);
|
||||
});
|
||||
});
|
||||
return u8concat(bufs);
|
||||
}
|
||||
function parse_snappy_chunk(type, buf) {
|
||||
if (type != 0)
|
||||
throw new Error("Unexpected Snappy chunk type ".concat(type));
|
||||
@ -22359,7 +22399,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22381,7 +22421,7 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function parse_storage(buf, sst, rsst) {
|
||||
function parse_new_storage(buf, sst, rsst) {
|
||||
var dv = u8_to_dataview(buf);
|
||||
var flags = dv.getUint32(8, true);
|
||||
var data_offset = 12;
|
||||
@ -22423,7 +22463,7 @@ function parse_storage(buf, sst, rsst) {
|
||||
ret = { t: "b", v: ieee > 0 };
|
||||
break;
|
||||
case 7:
|
||||
ret = { t: "n", v: ieee };
|
||||
ret = { t: "n", v: ieee / 86400 };
|
||||
break;
|
||||
case 8:
|
||||
ret = { t: "e", v: 0 };
|
||||
@ -22444,6 +22484,66 @@ function parse_storage(buf, sst, rsst) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function write_new_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[1] = 2;
|
||||
writeDecimal128LE(out, l, cell.v);
|
||||
flags |= 1;
|
||||
l += 16;
|
||||
break;
|
||||
case "b":
|
||||
out[1] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 2;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[1] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 8;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function write_old_storage(cell, sst) {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
switch (cell.t) {
|
||||
case "n":
|
||||
out[2] = 2;
|
||||
dv.setFloat64(l, cell.v, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "b":
|
||||
out[2] = 6;
|
||||
dv.setFloat64(l, cell.v ? 1 : 0, true);
|
||||
flags |= 32;
|
||||
l += 8;
|
||||
break;
|
||||
case "s":
|
||||
if (sst.indexOf(cell.v) == -1)
|
||||
throw new Error("Value ".concat(cell.v, " missing from SST!"));
|
||||
out[2] = 3;
|
||||
dv.setUint32(l, sst.indexOf(cell.v), true);
|
||||
flags |= 16;
|
||||
l += 4;
|
||||
break;
|
||||
default:
|
||||
throw "unsupported cell type " + cell.t;
|
||||
}
|
||||
dv.setUint32(4, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
function parse_cell_storage(buf, sst, rsst) {
|
||||
switch (buf[0]) {
|
||||
case 0:
|
||||
@ -22452,7 +22552,7 @@ function parse_cell_storage(buf, sst, rsst) {
|
||||
case 3:
|
||||
return parse_old_storage(buf, sst, rsst, buf[0]);
|
||||
case 5:
|
||||
return parse_storage(buf, sst, rsst);
|
||||
return parse_new_storage(buf, sst, rsst);
|
||||
default:
|
||||
throw new Error("Unsupported payload version ".concat(buf[0]));
|
||||
}
|
||||
@ -22461,6 +22561,11 @@ function parse_TSP_Reference(buf) {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
function write_TSP_Reference(idx) {
|
||||
var out = [];
|
||||
out[1] = [{ type: 0, data: write_varint49(idx) }];
|
||||
return write_shallow(out);
|
||||
}
|
||||
function parse_TST_TableDataList(M, root) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var type = varint_to_i32(pb[1][0].data);
|
||||
@ -22519,6 +22624,7 @@ function parse_TST_TileRowInfo(u8, type) {
|
||||
var cells = [];
|
||||
for (C = 0; C < offsets.length - 1; ++C)
|
||||
cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
|
||||
if (offsets.length >= 1)
|
||||
cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
|
||||
return { R: R, cells: cells };
|
||||
}
|
||||
@ -22625,7 +22731,7 @@ function parse_TN_DocumentArchive(M, root) {
|
||||
}
|
||||
function parse_numbers_iwa(cfb) {
|
||||
var _a, _b, _c, _d;
|
||||
var out = {}, indices = [];
|
||||
var M = {}, indices = [];
|
||||
cfb.FullPaths.forEach(function(p) {
|
||||
if (p.match(/\.iwpv2/))
|
||||
throw new Error("Unsupported password protection");
|
||||
@ -22646,16 +22752,16 @@ function parse_numbers_iwa(cfb) {
|
||||
return console.log("## " + (e.message || e));
|
||||
}
|
||||
packets.forEach(function(packet) {
|
||||
out[packet.id] = packet.messages;
|
||||
M[packet.id] = packet.messages;
|
||||
indices.push(packet.id);
|
||||
});
|
||||
});
|
||||
if (!indices.length)
|
||||
throw new Error("File has no messages");
|
||||
var docroot = ((_d = (_c = (_b = (_a = out == null ? void 0 : out[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(out[1][0].meta[1][0].data) == 1 && out[1][0];
|
||||
var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
|
||||
if (!docroot)
|
||||
indices.forEach(function(idx) {
|
||||
out[idx].forEach(function(iwam) {
|
||||
M[idx].forEach(function(iwam) {
|
||||
var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
|
||||
if (mtype == 1) {
|
||||
if (!docroot)
|
||||
@ -22667,7 +22773,325 @@ function parse_numbers_iwa(cfb) {
|
||||
});
|
||||
if (!docroot)
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(out, docroot);
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({ t: "s", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "s", v: data[C] }, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({ t: "n", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "n", v: data[C] }, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({ t: "b", v: data[C] }, SST);
|
||||
_celload = write_old_storage({ t: "b", v: data[C] }, SST);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
return cnt;
|
||||
}
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if (wb.SheetNames.length > 1)
|
||||
console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
var data = sheet_to_json(ws, { range: range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(function(row) {
|
||||
return row.forEach(function(cell) {
|
||||
if (typeof cell == "string")
|
||||
SST.push(cell);
|
||||
});
|
||||
});
|
||||
var dependents = {};
|
||||
var indices = [];
|
||||
var cfb = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (fi.type != 2)
|
||||
return;
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var old_content = fi.content;
|
||||
var raw1 = decompress_iwa_file(old_content);
|
||||
var x2 = parse_iwa_file(raw1);
|
||||
x2.forEach(function(packet2) {
|
||||
indices.push(packet2.id);
|
||||
dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
|
||||
});
|
||||
});
|
||||
indices.sort(function(x2, y2) {
|
||||
return x2 - y2;
|
||||
});
|
||||
var indices_varint = indices.filter(function(x2) {
|
||||
return x2 > 1;
|
||||
}).map(function(x2) {
|
||||
return [x2, write_varint49(x2)];
|
||||
});
|
||||
cfb.FileIndex.map(function(fi, idx) {
|
||||
return [fi, cfb.FullPaths[idx]];
|
||||
}).forEach(function(row) {
|
||||
var fi = row[0], fp = row[1];
|
||||
if (!fi.name.match(/\.iwa/))
|
||||
return;
|
||||
var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
|
||||
x2.forEach(function(ia) {
|
||||
ia.messages.forEach(function(m) {
|
||||
indices_varint.forEach(function(ivi) {
|
||||
if (ia.messages.some(function(mess) {
|
||||
return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
|
||||
})) {
|
||||
dependents[ivi[0]].deps.push(ia.id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
function get_unique_msgid() {
|
||||
for (var i = 927262; i < 2e6; ++i)
|
||||
if (!dependents[i])
|
||||
return i;
|
||||
throw new Error("Too many messages");
|
||||
}
|
||||
var entry = CFB.find(cfb, dependents[1].location);
|
||||
var x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
var docroot;
|
||||
for (var xi = 0; xi < x.length; ++xi) {
|
||||
var packet = x[xi];
|
||||
if (packet.id == 1)
|
||||
docroot = packet;
|
||||
}
|
||||
var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
|
||||
entry = CFB.find(cfb, dependents[sheetrootref].location);
|
||||
x = parse_iwa_file(decompress_iwa_file(entry.content));
|
||||
for (xi = 0; xi < x.length; ++xi) {
|
||||
packet = x[xi];
|
||||
if (packet.id == sheetrootref)
|
||||
docroot = packet;
|
||||
}
|
||||
var pb = parse_shallow(docroot.messages[0].data);
|
||||
{
|
||||
pb[6][0].data = write_varint49(range.e.r + 1);
|
||||
pb[7][0].data = write_varint49(range.e.c + 1);
|
||||
var cruidsref = parse_TSP_Reference(pb[46][0].data);
|
||||
var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
|
||||
var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
for (var j = 0; j < _x.length; ++j) {
|
||||
if (_x[j].id == cruidsref)
|
||||
break;
|
||||
}
|
||||
if (_x[j].id != cruidsref)
|
||||
throw "Bad ColumnRowUIDMapArchive";
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = [];
|
||||
cruids[2] = [], cruids[3] = [];
|
||||
for (var C = 0; C <= range.e.c; ++C) {
|
||||
var uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
|
||||
cruids[1].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[2].push({ type: 0, data: write_varint49(C) });
|
||||
cruids[3].push({ type: 0, data: write_varint49(C) });
|
||||
}
|
||||
cruids[4] = [];
|
||||
cruids[5] = [], cruids[6] = [];
|
||||
for (var R = 0; R <= range.e.r; ++R) {
|
||||
uuid = [];
|
||||
uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
|
||||
cruids[4].push({ type: 2, data: write_shallow(uuid) });
|
||||
cruids[5].push({ type: 0, data: write_varint49(R) });
|
||||
cruids[6].push({ type: 0, data: write_varint49(R) });
|
||||
}
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
store[7][0].data = write_varint49(range.e.r + 1);
|
||||
var row_headers = parse_shallow(store[1][0].data);
|
||||
var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var col_header_ref = parse_TSP_Reference(store[2][0].data);
|
||||
oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
|
||||
_x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
|
||||
{
|
||||
if (_x[0].id != col_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (C = 0; C <= range.e.c; ++C) {
|
||||
_bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(C);
|
||||
_bucket[4][0].data = write_varint49(range.e.r + 1);
|
||||
base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
oldbucket.size = oldbucket.content.length;
|
||||
var sstref = parse_TSP_Reference(store[4][0].data);
|
||||
(function() {
|
||||
var sentry = CFB.find(cfb, dependents[sstref].location);
|
||||
var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
|
||||
var sstroot;
|
||||
for (var sxi = 0; sxi < sx.length; ++sxi) {
|
||||
var packet2 = sx[sxi];
|
||||
if (packet2.id == sstref)
|
||||
sstroot = packet2;
|
||||
}
|
||||
var sstdata = parse_shallow(sstroot.messages[0].data);
|
||||
{
|
||||
sstdata[3] = [];
|
||||
var newsst = [];
|
||||
SST.forEach(function(str, i) {
|
||||
newsst[1] = [{ type: 0, data: write_varint49(i) }];
|
||||
newsst[2] = [{ type: 0, data: write_varint49(1) }];
|
||||
newsst[3] = [{ type: 2, data: stru8(str) }];
|
||||
sstdata[3].push({ type: 2, data: write_shallow(newsst) });
|
||||
});
|
||||
}
|
||||
sstroot.messages[0].data = write_shallow(sstdata);
|
||||
var sy = write_iwa_file(sx);
|
||||
var raw32 = compress_iwa_file(sy);
|
||||
sentry.content = raw32;
|
||||
sentry.size = sentry.content.length;
|
||||
})();
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
(function() {
|
||||
var tentry = CFB.find(cfb, dependents[tileref].location);
|
||||
var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
|
||||
var tileroot;
|
||||
for (var sxi = 0; sxi < tx.length; ++sxi) {
|
||||
var packet2 = tx[sxi];
|
||||
if (packet2.id == tileref)
|
||||
tileroot = packet2;
|
||||
}
|
||||
var tiledata = parse_shallow(tileroot.messages[0].data);
|
||||
{
|
||||
delete tiledata[6];
|
||||
delete tile[7];
|
||||
var rowload = new Uint8Array(tiledata[5][0].data);
|
||||
tiledata[5] = [];
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
var ty = write_iwa_file(tx);
|
||||
var raw32 = compress_iwa_file(ty);
|
||||
tentry.content = raw32;
|
||||
tentry.size = tentry.content.length;
|
||||
})();
|
||||
}
|
||||
t.data = write_shallow(tl);
|
||||
}
|
||||
store[3][0].data = write_shallow(tile);
|
||||
}
|
||||
pb[4][0].data = write_shallow(store);
|
||||
}
|
||||
docroot.messages[0].data = write_shallow(pb);
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
entry.content = raw3;
|
||||
entry.size = entry.content.length;
|
||||
return cfb;
|
||||
}
|
||||
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
|
||||
return function fix_opts(opts) {
|
||||
@ -23008,6 +23432,7 @@ function parse_xlsxcfb(cfb, _opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
||||
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
|
||||
if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
|
||||
return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
@ -23576,6 +24001,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'xlsm':
|
||||
case 'xlam':
|
||||
case 'xlsb':
|
||||
case 'numbers':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user