reamkit 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -8
- package/dist/esm/core/converter/facade.d.ts +12 -6
- package/dist/esm/core/converter/facade.js +34 -5
- package/dist/esm/core/converter/ream.d.ts +5 -3
- package/dist/esm/core/converter/ream.js +18 -4
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +26 -0
- package/dist/esm/core/drawingml/sparkline-geometry.d.ts +8 -0
- package/dist/esm/core/drawingml/sparkline-geometry.js +111 -0
- package/dist/esm/core/ir/adapters.d.ts +5 -5
- package/dist/esm/core/ir/sheet.d.ts +31 -0
- package/dist/esm/core/opc/relationships.js +1 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -0
- package/dist/esm/core/spreadsheet-model/types.d.ts +189 -0
- package/dist/esm/excel/column-bands.d.ts +7 -0
- package/dist/esm/excel/column-bands.js +87 -0
- package/dist/esm/excel/conditional-format.d.ts +16 -0
- package/dist/esm/excel/conditional-format.js +327 -0
- package/dist/esm/excel/index.d.ts +4 -3
- package/dist/esm/excel/print-model.d.ts +2 -1
- package/dist/esm/excel/print-model.js +144 -13
- package/dist/esm/excel/sheet-drawing.d.ts +1 -1
- package/dist/esm/excel/sheet-to-flow.d.ts +3 -0
- package/dist/esm/excel/sheet-to-flow.js +51 -0
- package/dist/esm/excel/styles-parser.d.ts +1 -50
- package/dist/esm/excel/styles-parser.js +38 -1
- package/dist/esm/excel/table-parser.d.ts +2 -0
- package/dist/esm/excel/table-parser.js +51 -0
- package/dist/esm/excel/workbook-parser.d.ts +1 -5
- package/dist/esm/excel/worksheet-parser.d.ts +1 -60
- package/dist/esm/excel/worksheet-parser.js +265 -1
- package/dist/esm/excel/xlsx-reader.d.ts +3 -1
- package/dist/esm/excel/xlsx-reader.js +86 -51
- package/dist/esm/excel/xlsx-writer.d.ts +4 -0
- package/dist/esm/excel/xlsx-writer.js +278 -0
- package/dist/esm/html/html-writer.js +126 -4
- package/dist/esm/layout/styled-layout.js +160 -1
- package/dist/esm/pdf-reader/cmap.d.ts +5 -0
- package/dist/esm/pdf-reader/cmap.js +72 -0
- package/dist/esm/pdf-reader/content.d.ts +14 -0
- package/dist/esm/pdf-reader/content.js +292 -0
- package/dist/esm/pdf-reader/document.d.ts +23 -0
- package/dist/esm/pdf-reader/document.js +230 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +4 -0
- package/dist/esm/pdf-reader/flow-build.js +27 -0
- package/dist/esm/pdf-reader/font.d.ts +4 -0
- package/dist/esm/pdf-reader/font.js +69 -0
- package/dist/esm/pdf-reader/layout.d.ts +3 -0
- package/dist/esm/pdf-reader/layout.js +69 -0
- package/dist/esm/pdf-reader/lexer.d.ts +43 -0
- package/dist/esm/pdf-reader/lexer.js +250 -0
- package/dist/esm/pdf-reader/parser.d.ts +10 -0
- package/dist/esm/pdf-reader/parser.js +86 -0
- package/dist/esm/pdf-reader/reader.d.ts +4 -0
- package/dist/esm/pdf-reader/reader.js +43 -0
- package/dist/esm/pdf-reader/struct-tree.d.ts +14 -0
- package/dist/esm/pdf-reader/struct-tree.js +92 -0
- package/dist/esm/pdf-reader/tagged.d.ts +3 -0
- package/dist/esm/pdf-reader/tagged.js +88 -0
- package/dist/esm/pdf-reader/text.d.ts +3 -0
- package/dist/esm/pdf-reader/text.js +18 -0
- package/package.json +4 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseCellRef } from "./cell-reference.js";
|
|
2
|
+
import { parseAreaRef } from "./defined-name-ref.js";
|
|
2
3
|
import { XMLParser } from "fast-xml-parser";
|
|
3
4
|
//#region src/excel/worksheet-parser.ts
|
|
4
5
|
var decoder = new TextDecoder("utf-8");
|
|
@@ -32,8 +33,12 @@ function parseWorksheet(data) {
|
|
|
32
33
|
const printOptions = parsePrintOptions(wsObj);
|
|
33
34
|
const rowBreaks = parseBreaks(wsObj, "rowBreaks");
|
|
34
35
|
const colBreaks = parseBreaks(wsObj, "colBreaks");
|
|
36
|
+
const pane = parsePane(wsObj);
|
|
35
37
|
const drawingNode = wsObj["drawing"];
|
|
36
38
|
const drawingRelId = drawingNode && typeof drawingNode === "object" ? strAttr(drawingNode, "id") : void 0;
|
|
39
|
+
const conditionalFormats = parseConditionalFormatting(wsObj);
|
|
40
|
+
const sparklines = parseSparklines(wsObj);
|
|
41
|
+
const tablePartRelIds = parseTableParts(wsObj);
|
|
37
42
|
const printModel = {
|
|
38
43
|
...pageMargins ? { pageMargins } : {},
|
|
39
44
|
...pageSetup ? { pageSetup } : {},
|
|
@@ -41,7 +46,11 @@ function parseWorksheet(data) {
|
|
|
41
46
|
...printOptions ? { printOptions } : {},
|
|
42
47
|
...rowBreaks.length > 0 ? { rowBreaks } : {},
|
|
43
48
|
...colBreaks.length > 0 ? { colBreaks } : {},
|
|
44
|
-
...
|
|
49
|
+
...pane ? { pane } : {},
|
|
50
|
+
...drawingRelId !== void 0 ? { drawingRelId } : {},
|
|
51
|
+
...conditionalFormats.length > 0 ? { conditionalFormats } : {},
|
|
52
|
+
...sparklines.length > 0 ? { sparklines } : {},
|
|
53
|
+
...tablePartRelIds.length > 0 ? { tablePartRelIds } : {}
|
|
45
54
|
};
|
|
46
55
|
const sheetData = wsObj["sheetData"];
|
|
47
56
|
if (!sheetData || typeof sheetData !== "object") return {
|
|
@@ -174,6 +183,30 @@ function parsePrintOptions(ws) {
|
|
|
174
183
|
...verticalCentered !== void 0 ? { verticalCentered } : {}
|
|
175
184
|
};
|
|
176
185
|
}
|
|
186
|
+
function parsePane(ws) {
|
|
187
|
+
const views = ws["sheetViews"];
|
|
188
|
+
if (!views || typeof views !== "object") return void 0;
|
|
189
|
+
const viewRaw = views["sheetView"];
|
|
190
|
+
const view = Array.isArray(viewRaw) ? viewRaw[0] : viewRaw;
|
|
191
|
+
if (!view || typeof view !== "object") return void 0;
|
|
192
|
+
const paneNode = view["pane"];
|
|
193
|
+
if (!paneNode || typeof paneNode !== "object") return void 0;
|
|
194
|
+
const pane = paneNode;
|
|
195
|
+
const state = strAttr(pane, "state");
|
|
196
|
+
if (state !== "frozen" && state !== "frozenSplit") return void 0;
|
|
197
|
+
const count = (key) => {
|
|
198
|
+
const raw = strAttr(pane, key);
|
|
199
|
+
const n = raw !== void 0 ? Number(raw) : NaN;
|
|
200
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : 0;
|
|
201
|
+
};
|
|
202
|
+
const frozenCols = count("xSplit");
|
|
203
|
+
const frozenRows = count("ySplit");
|
|
204
|
+
if (frozenCols === 0 && frozenRows === 0) return void 0;
|
|
205
|
+
return {
|
|
206
|
+
frozenRows,
|
|
207
|
+
frozenCols
|
|
208
|
+
};
|
|
209
|
+
}
|
|
177
210
|
function parseBreaks(ws, tag) {
|
|
178
211
|
const node = ws[tag];
|
|
179
212
|
if (!node || typeof node !== "object") return [];
|
|
@@ -239,6 +272,237 @@ function parseMerges(ws) {
|
|
|
239
272
|
}
|
|
240
273
|
return out;
|
|
241
274
|
}
|
|
275
|
+
function parseConditionalFormatting(ws) {
|
|
276
|
+
const raw = ws["conditionalFormatting"];
|
|
277
|
+
const items = Array.isArray(raw) ? raw : raw !== void 0 ? [raw] : [];
|
|
278
|
+
const out = [];
|
|
279
|
+
for (const item of items) {
|
|
280
|
+
if (!item || typeof item !== "object") continue;
|
|
281
|
+
const obj = item;
|
|
282
|
+
const sqref = strAttr(obj, "sqref");
|
|
283
|
+
if (!sqref) continue;
|
|
284
|
+
const ranges = parseSqref(sqref);
|
|
285
|
+
if (ranges.length === 0) continue;
|
|
286
|
+
const ruleRaw = obj["cfRule"];
|
|
287
|
+
const ruleItems = Array.isArray(ruleRaw) ? ruleRaw : ruleRaw !== void 0 ? [ruleRaw] : [];
|
|
288
|
+
const rules = [];
|
|
289
|
+
for (const rn of ruleItems) {
|
|
290
|
+
if (!rn || typeof rn !== "object") continue;
|
|
291
|
+
const rule = parseCfRule(rn);
|
|
292
|
+
if (rule) rules.push(rule);
|
|
293
|
+
}
|
|
294
|
+
if (rules.length > 0) out.push({
|
|
295
|
+
ranges,
|
|
296
|
+
rules
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return out;
|
|
300
|
+
}
|
|
301
|
+
function parseSqref(sqref) {
|
|
302
|
+
const out = [];
|
|
303
|
+
for (const token of sqref.split(/\s+/)) {
|
|
304
|
+
if (!token) continue;
|
|
305
|
+
const r = parseAreaRef(token);
|
|
306
|
+
if (r) out.push({
|
|
307
|
+
startColumn: r.startColumn,
|
|
308
|
+
startRow: r.startRow,
|
|
309
|
+
endColumn: r.endColumn,
|
|
310
|
+
endRow: r.endRow
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return out;
|
|
314
|
+
}
|
|
315
|
+
var CF_OPERATORS = new Set([
|
|
316
|
+
"lessThan",
|
|
317
|
+
"lessThanOrEqual",
|
|
318
|
+
"equal",
|
|
319
|
+
"notEqual",
|
|
320
|
+
"greaterThanOrEqual",
|
|
321
|
+
"greaterThan",
|
|
322
|
+
"between",
|
|
323
|
+
"notBetween"
|
|
324
|
+
]);
|
|
325
|
+
function parseCfRule(obj) {
|
|
326
|
+
const priority = parseNumericAttr(obj, "priority") ?? 0;
|
|
327
|
+
switch (strAttr(obj, "type")) {
|
|
328
|
+
case "cellIs": return parseCellIsRule(obj, priority);
|
|
329
|
+
case "colorScale": return parseColorScaleRule(obj, priority);
|
|
330
|
+
case "dataBar": return parseDataBarRule(obj, priority);
|
|
331
|
+
case "iconSet": return parseIconSetRule(obj, priority);
|
|
332
|
+
default: return;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function parseIconSetRule(obj, priority) {
|
|
336
|
+
const is = obj["iconSet"];
|
|
337
|
+
if (!is || typeof is !== "object") return void 0;
|
|
338
|
+
const isObj = is;
|
|
339
|
+
const cfvos = parseCfvos(isObj["cfvo"]);
|
|
340
|
+
if (cfvos.length < 3) return void 0;
|
|
341
|
+
const iconSet = strAttr(isObj, "iconSet") ?? "3TrafficLights1";
|
|
342
|
+
const reverseRaw = strAttr(isObj, "reverse");
|
|
343
|
+
const reverse = reverseRaw === "1" || reverseRaw === "true";
|
|
344
|
+
return {
|
|
345
|
+
type: "iconSet",
|
|
346
|
+
priority,
|
|
347
|
+
iconSet,
|
|
348
|
+
cfvos,
|
|
349
|
+
...reverse ? { reverse } : {}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function parseDataBarRule(obj, priority) {
|
|
353
|
+
const db = obj["dataBar"];
|
|
354
|
+
if (!db || typeof db !== "object") return void 0;
|
|
355
|
+
const dbObj = db;
|
|
356
|
+
const cfvos = parseCfvos(dbObj["cfvo"]);
|
|
357
|
+
if (cfvos.length < 2) return void 0;
|
|
358
|
+
const colorHex = colorRgbHex(dbObj["color"]);
|
|
359
|
+
if (!colorHex) return void 0;
|
|
360
|
+
const minLength = parseNumericAttr(dbObj, "minLength");
|
|
361
|
+
const maxLength = parseNumericAttr(dbObj, "maxLength");
|
|
362
|
+
return {
|
|
363
|
+
type: "dataBar",
|
|
364
|
+
priority,
|
|
365
|
+
cfvos,
|
|
366
|
+
colorHex,
|
|
367
|
+
...minLength !== void 0 ? { minLength } : {},
|
|
368
|
+
...maxLength !== void 0 ? { maxLength } : {}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function parseCellIsRule(obj, priority) {
|
|
372
|
+
const operator = strAttr(obj, "operator");
|
|
373
|
+
if (!operator || !CF_OPERATORS.has(operator)) return void 0;
|
|
374
|
+
const dxfId = parseNumericAttr(obj, "dxfId");
|
|
375
|
+
if (dxfId === void 0) return void 0;
|
|
376
|
+
const fRaw = obj["formula"];
|
|
377
|
+
const fItems = Array.isArray(fRaw) ? fRaw : fRaw !== void 0 ? [fRaw] : [];
|
|
378
|
+
const formulas = [];
|
|
379
|
+
for (const f of fItems) {
|
|
380
|
+
const text = formulaText(f);
|
|
381
|
+
if (text !== void 0) formulas.push(text);
|
|
382
|
+
}
|
|
383
|
+
if (formulas.length === 0) return void 0;
|
|
384
|
+
return {
|
|
385
|
+
type: "cellIs",
|
|
386
|
+
priority,
|
|
387
|
+
operator,
|
|
388
|
+
formulas,
|
|
389
|
+
dxfId
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
var CFVO_TYPES = new Set([
|
|
393
|
+
"num",
|
|
394
|
+
"percent",
|
|
395
|
+
"max",
|
|
396
|
+
"min",
|
|
397
|
+
"percentile",
|
|
398
|
+
"formula",
|
|
399
|
+
"autoMin",
|
|
400
|
+
"autoMax"
|
|
401
|
+
]);
|
|
402
|
+
function parseColorScaleRule(obj, priority) {
|
|
403
|
+
const cs = obj["colorScale"];
|
|
404
|
+
if (!cs || typeof cs !== "object") return void 0;
|
|
405
|
+
const csObj = cs;
|
|
406
|
+
const cfvos = parseCfvos(csObj["cfvo"]);
|
|
407
|
+
const colorsHex = parseScaleColors(csObj["color"]);
|
|
408
|
+
if (cfvos.length < 2 || cfvos.length !== colorsHex.length) return void 0;
|
|
409
|
+
return {
|
|
410
|
+
type: "colorScale",
|
|
411
|
+
priority,
|
|
412
|
+
cfvos,
|
|
413
|
+
colorsHex
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function parseCfvos(raw) {
|
|
417
|
+
const items = Array.isArray(raw) ? raw : raw !== void 0 ? [raw] : [];
|
|
418
|
+
const out = [];
|
|
419
|
+
for (const it of items) {
|
|
420
|
+
if (!it || typeof it !== "object") continue;
|
|
421
|
+
const o = it;
|
|
422
|
+
const type = strAttr(o, "type");
|
|
423
|
+
if (!type || !CFVO_TYPES.has(type)) return [];
|
|
424
|
+
const val = strAttr(o, "val");
|
|
425
|
+
out.push(val !== void 0 ? {
|
|
426
|
+
type,
|
|
427
|
+
val
|
|
428
|
+
} : { type });
|
|
429
|
+
}
|
|
430
|
+
return out;
|
|
431
|
+
}
|
|
432
|
+
function parseScaleColors(raw) {
|
|
433
|
+
const items = Array.isArray(raw) ? raw : raw !== void 0 ? [raw] : [];
|
|
434
|
+
const out = [];
|
|
435
|
+
for (const it of items) {
|
|
436
|
+
const hex = colorRgbHex(it);
|
|
437
|
+
if (!hex) return [];
|
|
438
|
+
out.push(hex);
|
|
439
|
+
}
|
|
440
|
+
return out;
|
|
441
|
+
}
|
|
442
|
+
function colorRgbHex(node) {
|
|
443
|
+
if (!node || typeof node !== "object") return void 0;
|
|
444
|
+
const rgb = strAttr(node, "rgb");
|
|
445
|
+
if (!rgb) return void 0;
|
|
446
|
+
if (/^[0-9A-Fa-f]{8}$/.test(rgb)) return rgb.substring(2).toUpperCase();
|
|
447
|
+
if (/^[0-9A-Fa-f]{6}$/.test(rgb)) return rgb.toUpperCase();
|
|
448
|
+
}
|
|
449
|
+
function formulaText(node) {
|
|
450
|
+
if (typeof node === "string") return node;
|
|
451
|
+
if (typeof node === "number") return String(node);
|
|
452
|
+
if (node && typeof node === "object") {
|
|
453
|
+
const t = node["#text"];
|
|
454
|
+
if (typeof t === "string") return t;
|
|
455
|
+
if (typeof t === "number") return String(t);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function toArray(v) {
|
|
459
|
+
return Array.isArray(v) ? v : v === void 0 || v === null ? [] : [v];
|
|
460
|
+
}
|
|
461
|
+
function parseSparklines(ws) {
|
|
462
|
+
const extLst = asObjectNode(ws["extLst"]);
|
|
463
|
+
if (!extLst) return [];
|
|
464
|
+
const out = [];
|
|
465
|
+
for (const ext of toArray(extLst["ext"])) {
|
|
466
|
+
const groupsNode = asObjectNode(asObjectNode(ext)?.["sparklineGroups"]);
|
|
467
|
+
if (!groupsNode) continue;
|
|
468
|
+
for (const g of toArray(groupsNode["sparklineGroup"])) {
|
|
469
|
+
const group = asObjectNode(g);
|
|
470
|
+
if (!group) continue;
|
|
471
|
+
const typeStr = strAttr(group, "type");
|
|
472
|
+
const kind = typeStr === "column" ? "column" : typeStr === "stacked" ? "winLoss" : "line";
|
|
473
|
+
const colorHex = colorRgbHex(group["colorSeries"]);
|
|
474
|
+
const slNode = asObjectNode(group["sparklines"]);
|
|
475
|
+
if (!slNode) continue;
|
|
476
|
+
for (const sl of toArray(slNode["sparkline"])) {
|
|
477
|
+
const spark = asObjectNode(sl);
|
|
478
|
+
if (!spark) continue;
|
|
479
|
+
const dataRange = formulaText(spark["f"]);
|
|
480
|
+
const sqref = formulaText(spark["sqref"]);
|
|
481
|
+
if (dataRange && sqref) out.push({
|
|
482
|
+
kind,
|
|
483
|
+
dataRange,
|
|
484
|
+
sqref,
|
|
485
|
+
...colorHex ? { colorHex } : {}
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return out;
|
|
491
|
+
}
|
|
492
|
+
function asObjectNode(v) {
|
|
493
|
+
return v && typeof v === "object" && !Array.isArray(v) ? v : void 0;
|
|
494
|
+
}
|
|
495
|
+
function parseTableParts(ws) {
|
|
496
|
+
const node = asObjectNode(ws["tableParts"]);
|
|
497
|
+
if (!node) return [];
|
|
498
|
+
const out = [];
|
|
499
|
+
for (const tp of toArray(node["tablePart"])) {
|
|
500
|
+
const obj = asObjectNode(tp);
|
|
501
|
+
const rid = obj ? strAttr(obj, "id") : void 0;
|
|
502
|
+
if (rid) out.push(rid);
|
|
503
|
+
}
|
|
504
|
+
return out;
|
|
505
|
+
}
|
|
242
506
|
function parseCell(c, fallbackRow, fallbackCol) {
|
|
243
507
|
if (!c || typeof c !== "object") return null;
|
|
244
508
|
const obj = c;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { DocumentReader, ReadResult } from '../core/ir/adapters.js';
|
|
2
2
|
import { FlowDoc } from '../core/ir/flow.js';
|
|
3
|
+
import { SheetDoc } from '../core/ir/sheet.js';
|
|
3
4
|
export declare function readXlsx(xlsx: Uint8Array): ReadResult<FlowDoc>;
|
|
4
|
-
export declare
|
|
5
|
+
export declare function readXlsxToSheetDoc(xlsx: Uint8Array): SheetDoc;
|
|
6
|
+
export declare const xlsxReader: DocumentReader<SheetDoc>;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { pt } from "../core/ir/units.js";
|
|
2
1
|
import { ResourceStore } from "../core/ir/resources.js";
|
|
3
2
|
import { FEATURES } from "../core/ir/features.js";
|
|
4
|
-
import { EMPTY_STYLE_SHEET, resolveBodyStyles } from "../core/style-cascade/resolver.js";
|
|
5
|
-
import "../core/style-cascade/index.js";
|
|
6
3
|
import { bytesInclude } from "../core/bytes.js";
|
|
7
4
|
import { DEFAULT_THEME_PALETTE, makeColorResolver } from "../core/drawingml/colors.js";
|
|
8
5
|
import { parseChart, withChartColorStyle } from "../core/drawingml/chart-parser.js";
|
|
@@ -16,14 +13,21 @@ import { parseWorkbook } from "./workbook-parser.js";
|
|
|
16
13
|
import { parseWorksheet } from "./worksheet-parser.js";
|
|
17
14
|
import { EMPTY_XLSX_STYLES, parseXlsxStyles } from "./styles-parser.js";
|
|
18
15
|
import "./index.js";
|
|
19
|
-
import { resolvePrintArea, resolvePrintTitleRows, sectionFromWorksheet, worksheetToBody } from "./print-model.js";
|
|
20
16
|
import { parseSheetDrawing } from "./sheet-drawing.js";
|
|
17
|
+
import { parseTablePart } from "./table-parser.js";
|
|
18
|
+
import { projectSheetDoc } from "./sheet-to-flow.js";
|
|
21
19
|
//#region src/excel/xlsx-reader.ts
|
|
22
20
|
var WORKBOOK_PART = "xl/workbook.xml";
|
|
23
21
|
var SHARED_STRINGS_PART = "xl/sharedStrings.xml";
|
|
24
22
|
var STYLES_PART = "xl/styles.xml";
|
|
25
23
|
var CORE_PROPS_PART = "docProps/core.xml";
|
|
26
24
|
function readXlsx(xlsx) {
|
|
25
|
+
return {
|
|
26
|
+
doc: projectSheetDoc(readXlsxToSheetDoc(xlsx)),
|
|
27
|
+
losses: []
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function readXlsxToSheetDoc(xlsx) {
|
|
27
31
|
const pkg = OpcPackage.open(xlsx);
|
|
28
32
|
const workbookData = pkg.getPart(WORKBOOK_PART);
|
|
29
33
|
if (!workbookData) throw new Error("Not a valid xlsx: missing xl/workbook.xml");
|
|
@@ -34,10 +38,10 @@ function readXlsx(xlsx) {
|
|
|
34
38
|
const stylesData = pkg.getPart(STYLES_PART);
|
|
35
39
|
const styles = stylesData ? parseXlsxStyles(stylesData) : EMPTY_XLSX_STYLES;
|
|
36
40
|
const workbookRels = pkg.getPartRelationships(WORKBOOK_PART);
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const resolveColor =
|
|
40
|
-
|
|
41
|
+
const chartData = /* @__PURE__ */ new Map();
|
|
42
|
+
const palette = buildThemePalette(pkg, workbookRels);
|
|
43
|
+
const resolveColor = makeColorResolver(palette);
|
|
44
|
+
const sheetsOut = [];
|
|
41
45
|
for (let sheetIdx = 0; sheetIdx < sheets.length; sheetIdx++) {
|
|
42
46
|
const sheet = sheets[sheetIdx];
|
|
43
47
|
const sheetRel = workbookRels.find((r) => r.id === sheet.relationshipId);
|
|
@@ -45,61 +49,61 @@ function readXlsx(xlsx) {
|
|
|
45
49
|
const resolved = pkg.resolveRelatedPart(WORKBOOK_PART, sheetRel);
|
|
46
50
|
if (!resolved) continue;
|
|
47
51
|
const worksheet = parseWorksheet(resolved.data);
|
|
48
|
-
|
|
49
|
-
if (sheetIdx > 0) body.push({
|
|
50
|
-
kind: "paragraph",
|
|
51
|
-
paragraph: {
|
|
52
|
-
properties: { pageBreakBefore: true },
|
|
53
|
-
runs: []
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const printArea = resolvePrintArea(definedNames, sheetIdx);
|
|
57
|
-
const titleRows = resolvePrintTitleRows(definedNames, sheetIdx);
|
|
58
|
-
const gridLines = worksheet.printOptions?.gridLines === true;
|
|
59
|
-
body.push(...worksheetToBody(worksheet, sharedStrings, styles, date1904, {
|
|
60
|
-
...printArea ? { printArea } : {},
|
|
61
|
-
...titleRows ? { titleRows } : {},
|
|
62
|
-
gridLines
|
|
63
|
-
}));
|
|
52
|
+
const charts = [];
|
|
64
53
|
if (worksheet.drawingRelId) {
|
|
65
54
|
const drawingRel = pkg.getPartRelationships(resolved.path).find((r) => r.id === worksheet.drawingRelId);
|
|
66
55
|
const drawing = drawingRel ? pkg.resolveRelatedPart(resolved.path, drawingRel) : void 0;
|
|
67
56
|
if (drawing) for (const ref of parseSheetDrawing(drawing.data, drawing.path, pkg, worksheet)) {
|
|
68
|
-
if (!
|
|
69
|
-
const
|
|
70
|
-
const parsed =
|
|
57
|
+
if (!chartData.has(ref.chartPartPath)) {
|
|
58
|
+
const chartXml = pkg.getPart(ref.chartPartPath);
|
|
59
|
+
const parsed = chartXml ? parseChart(chartXml, resolveColor) : null;
|
|
71
60
|
if (!parsed) continue;
|
|
72
|
-
|
|
61
|
+
chartData.set(ref.chartPartPath, withChartColorStyle(parsed, pkg, ref.chartPartPath, resolveColor));
|
|
73
62
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
width: pt(ref.widthPt),
|
|
79
|
-
height: pt(ref.heightPt),
|
|
80
|
-
paragraphProperties: {}
|
|
81
|
-
}
|
|
63
|
+
charts.push({
|
|
64
|
+
chartPartPath: ref.chartPartPath,
|
|
65
|
+
widthPt: ref.widthPt,
|
|
66
|
+
heightPt: ref.heightPt
|
|
82
67
|
});
|
|
83
68
|
}
|
|
84
69
|
}
|
|
70
|
+
let tables;
|
|
71
|
+
if (worksheet.tablePartRelIds && worksheet.tablePartRelIds.length > 0) {
|
|
72
|
+
const wsRels = pkg.getPartRelationships(resolved.path);
|
|
73
|
+
const resolvedTables = [];
|
|
74
|
+
for (const rid of worksheet.tablePartRelIds) {
|
|
75
|
+
const rel = wsRels.find((r) => r.id === rid);
|
|
76
|
+
const part = rel ? pkg.resolveRelatedPart(resolved.path, rel) : void 0;
|
|
77
|
+
const parsed = part ? parseTablePart(part.data) : void 0;
|
|
78
|
+
if (parsed) resolvedTables.push(resolveTableStyle(parsed, palette));
|
|
79
|
+
}
|
|
80
|
+
if (resolvedTables.length > 0) tables = resolvedTables;
|
|
81
|
+
}
|
|
82
|
+
const grid = tables ? {
|
|
83
|
+
...worksheet,
|
|
84
|
+
tables
|
|
85
|
+
} : worksheet;
|
|
86
|
+
sheetsOut.push({
|
|
87
|
+
name: sheet.name,
|
|
88
|
+
grid,
|
|
89
|
+
...charts.length > 0 ? { charts } : {}
|
|
90
|
+
});
|
|
85
91
|
}
|
|
86
92
|
const coreData = pkg.getPart(CORE_PROPS_PART);
|
|
87
93
|
const info = infoFromCore(coreData ? parseCoreProperties(coreData) : void 0);
|
|
88
94
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
},
|
|
99
|
-
losses: []
|
|
95
|
+
kind: "sheet",
|
|
96
|
+
sheets: sheetsOut,
|
|
97
|
+
styles,
|
|
98
|
+
sharedStrings,
|
|
99
|
+
definedNames,
|
|
100
|
+
date1904,
|
|
101
|
+
...chartData.size > 0 ? { chartData } : {},
|
|
102
|
+
resources: new ResourceStore(),
|
|
103
|
+
...info ? { info } : {}
|
|
100
104
|
};
|
|
101
105
|
}
|
|
102
|
-
function
|
|
106
|
+
function buildThemePalette(pkg, workbookRels) {
|
|
103
107
|
const palette = new Map(DEFAULT_THEME_PALETTE);
|
|
104
108
|
for (const rel of workbookRels) {
|
|
105
109
|
if (!isOoxmlRel(rel.type, "theme")) continue;
|
|
@@ -108,14 +112,45 @@ function buildXlsxColorResolver(pkg, workbookRels) {
|
|
|
108
112
|
for (const [slot, hex] of parseTheme(resolved.data)) palette.set(slot, hex);
|
|
109
113
|
break;
|
|
110
114
|
}
|
|
111
|
-
return
|
|
115
|
+
return palette;
|
|
116
|
+
}
|
|
117
|
+
function resolveTableStyle(t, palette) {
|
|
118
|
+
const m = t.styleName ? /TableStyle(Light|Medium|Dark)(\d+)/i.exec(t.styleName) : null;
|
|
119
|
+
if (!m) return t;
|
|
120
|
+
const kind = m[1].toLowerCase();
|
|
121
|
+
const column = (Number(m[2]) - 1) % 7;
|
|
122
|
+
const base = column === 0 ? "7F7F7F" : palette.get(`accent${column}`) ?? "4472C4";
|
|
123
|
+
if (kind === "light") return {
|
|
124
|
+
...t,
|
|
125
|
+
headerHex: lighten(base, .6),
|
|
126
|
+
bandHex: lighten(base, .85)
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
...t,
|
|
130
|
+
headerHex: base,
|
|
131
|
+
bandHex: lighten(base, .8),
|
|
132
|
+
headerTextHex: "FFFFFF"
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function lighten(hex, amount) {
|
|
136
|
+
const m = /^#?([0-9a-fA-F]{6})$/.exec(hex);
|
|
137
|
+
const n = m ? parseInt(m[1], 16) : 4485828;
|
|
138
|
+
const ch = (shift) => {
|
|
139
|
+
const c = n >> shift & 255;
|
|
140
|
+
return Math.round(c + (255 - c) * amount);
|
|
141
|
+
};
|
|
142
|
+
const hx = (c) => c.toString(16).padStart(2, "0").toUpperCase();
|
|
143
|
+
return `${hx(ch(16))}${hx(ch(8))}${hx(ch(0))}`;
|
|
112
144
|
}
|
|
113
145
|
var xlsxReader = {
|
|
114
146
|
id: "xlsx",
|
|
115
|
-
produces: "
|
|
147
|
+
produces: "sheet",
|
|
116
148
|
supports: new Set([FEATURES.text, FEATURES.tables]),
|
|
117
149
|
sniff: (bytes) => bytes[0] === 80 && bytes[1] === 75 && bytesInclude(bytes, "xl/workbook.xml"),
|
|
118
|
-
read: (bytes) =>
|
|
150
|
+
read: (bytes) => ({
|
|
151
|
+
doc: readXlsxToSheetDoc(bytes),
|
|
152
|
+
losses: []
|
|
153
|
+
})
|
|
119
154
|
};
|
|
120
155
|
function infoFromCore(core) {
|
|
121
156
|
if (!core) return void 0;
|