@trebco/treb 28.17.5 → 29.1.2
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/dist/treb-spreadsheet-light.mjs +12 -12
- package/dist/treb-spreadsheet.mjs +12 -12
- package/dist/treb.d.ts +121 -82
- package/eslint.config.js +21 -0
- package/package.json +6 -6
- package/treb-base-types/src/area.ts +4 -2
- package/treb-base-types/src/cell.ts +1 -1
- package/treb-base-types/src/cells.ts +16 -7
- package/treb-base-types/src/dom-utilities.ts +4 -2
- package/treb-base-types/src/import.ts +2 -2
- package/treb-base-types/src/rectangle.ts +5 -5
- package/treb-base-types/src/union.ts +6 -1
- package/treb-base-types/src/value-type.ts +1 -1
- package/treb-calculator/src/calculator.ts +114 -165
- package/treb-calculator/src/dag/calculation_leaf_vertex.ts +1 -2
- package/treb-calculator/src/dag/graph.ts +3 -3
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +2 -2
- package/treb-calculator/src/dag/state_leaf_vertex.ts +2 -4
- package/treb-calculator/src/descriptors.ts +28 -2
- package/treb-calculator/src/expression-calculator.ts +25 -34
- package/treb-calculator/src/function-error.ts +2 -2
- package/treb-calculator/src/function-library.ts +16 -0
- package/treb-calculator/src/functions/base-functions.ts +185 -211
- package/treb-calculator/src/functions/checkbox.ts +0 -1
- package/treb-calculator/src/functions/complex-functions.ts +49 -47
- package/treb-calculator/src/functions/finance-functions.ts +10 -10
- package/treb-calculator/src/functions/function-utilities.ts +26 -0
- package/treb-calculator/src/functions/information-functions.ts +21 -41
- package/treb-calculator/src/functions/matrix-functions.ts +8 -1
- package/treb-calculator/src/functions/sparkline.ts +6 -4
- package/treb-calculator/src/functions/statistics-functions.ts +21 -17
- package/treb-calculator/src/functions/text-functions.ts +14 -13
- package/treb-calculator/src/primitives.ts +48 -37
- package/treb-calculator/src/utilities.ts +117 -134
- package/treb-charts/src/chart-functions.ts +3 -3
- package/treb-charts/src/chart-types.ts +42 -1
- package/treb-charts/src/chart-utils.ts +155 -113
- package/treb-charts/src/chart.ts +6 -5
- package/treb-charts/src/default-chart-renderer.ts +6 -5
- package/treb-charts/src/renderer.ts +12 -11
- package/treb-charts/src/util.ts +25 -36
- package/treb-data-model/package.json +5 -0
- package/{treb-grid/src/types → treb-data-model/src}/annotation.ts +2 -2
- package/{treb-grid/src/types → treb-data-model/src}/conditional_format.ts +20 -0
- package/{treb-grid/src/types → treb-data-model/src}/data_model.ts +231 -133
- package/treb-data-model/src/index.ts +45 -0
- package/{treb-grid/src/types/named_range.ts → treb-data-model/src/named.ts} +459 -376
- package/{treb-grid/src/types → treb-data-model/src}/sheet.ts +13 -5
- package/treb-data-model/src/sheet_collection.ts +114 -0
- package/{treb-grid/src/types → treb-data-model/src}/sheet_types.ts +6 -3
- package/treb-embed/modern.tsconfig.json +1 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +2 -2
- package/treb-embed/src/embedded-spreadsheet.ts +125 -270
- package/treb-embed/src/selection-state.ts +1 -1
- package/treb-embed/src/toolbar-message.ts +1 -1
- package/treb-embed/src/types.ts +13 -5
- package/treb-export/src/export-worker/export-worker.ts +22 -7
- package/treb-export/src/export2.ts +110 -41
- package/treb-export/src/import2.ts +6 -5
- package/treb-export/src/workbook2.ts +31 -13
- package/treb-export/src/xml-utils.ts +5 -1
- package/treb-format/src/format.ts +8 -6
- package/treb-grid/src/editors/autocomplete.ts +2 -2
- package/treb-grid/src/editors/autocomplete_matcher.ts +57 -19
- package/treb-grid/src/editors/editor.ts +27 -25
- package/treb-grid/src/editors/formula_bar.ts +5 -5
- package/treb-grid/src/editors/overlay_editor.ts +1 -2
- package/treb-grid/src/index.ts +0 -11
- package/treb-grid/src/layout/base_layout.ts +20 -8
- package/treb-grid/src/layout/grid_layout.ts +2 -2
- package/treb-grid/src/layout/mock-layout.ts +5 -6
- package/treb-grid/src/render/selection-renderer.ts +2 -3
- package/treb-grid/src/render/tile_renderer.ts +1 -1
- package/treb-grid/src/types/grid.ts +95 -66
- package/treb-grid/src/types/grid_base.ts +76 -60
- package/treb-grid/src/types/grid_command.ts +3 -2
- package/treb-grid/src/types/grid_events.ts +12 -6
- package/treb-grid/src/types/tab_bar.ts +1 -2
- package/treb-parser/src/parser-types.ts +2 -1
- package/treb-parser/src/parser.ts +7 -5
- package/treb-utils/src/event_source.ts +1 -1
- package/treb-utils/src/serialize_html.ts +31 -6
- package/.eslintignore +0 -8
- package/.eslintrc.cjs +0 -168
- package/treb-grid/src/layout/rectangle_cache.ts +0 -86
- /package/{treb-grid/src/types → treb-data-model/src}/serialize_options.ts +0 -0
- /package/{treb-grid/src/types/grid_selection.ts → treb-data-model/src/sheet_selection.ts} +0 -0
package/treb-embed/src/types.ts
CHANGED
|
@@ -20,8 +20,11 @@
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
import type { IArea, Table, TableTheme } from 'treb-base-types';
|
|
23
|
-
import type {
|
|
24
|
-
|
|
23
|
+
import type {
|
|
24
|
+
SerializedNamedExpression,
|
|
25
|
+
SerializedSheet,
|
|
26
|
+
SerializedMacroFunction,
|
|
27
|
+
SerializedNamed } from 'treb-data-model';
|
|
25
28
|
|
|
26
29
|
export enum SaveFileType {
|
|
27
30
|
json = 'json',
|
|
@@ -66,7 +69,7 @@ export interface TREBDocument {
|
|
|
66
69
|
* opaque user data. we don't read or parse this, but applications can
|
|
67
70
|
* use it to store arbitrary data.
|
|
68
71
|
*/
|
|
69
|
-
user_data?:
|
|
72
|
+
user_data?: unknown;
|
|
70
73
|
|
|
71
74
|
/**
|
|
72
75
|
* per-sheet data. this should be an array, but for historical reasons
|
|
@@ -86,12 +89,17 @@ export interface TREBDocument {
|
|
|
86
89
|
*/
|
|
87
90
|
rendered_values?: boolean;
|
|
88
91
|
|
|
89
|
-
/** document named ranges */
|
|
92
|
+
/** document named ranges @deprecated */
|
|
90
93
|
named_ranges?: Record<string, IArea>;
|
|
91
94
|
|
|
92
|
-
/** document named expressions */
|
|
95
|
+
/** document named expressions @deprecated */
|
|
93
96
|
named_expressions?: SerializedNamedExpression[];
|
|
94
97
|
|
|
98
|
+
/**
|
|
99
|
+
* new consolidated named ranges & expressions
|
|
100
|
+
*/
|
|
101
|
+
named?: SerializedNamed[];
|
|
102
|
+
|
|
95
103
|
/** document macro functions */
|
|
96
104
|
macro_functions?: SerializedMacroFunction[];
|
|
97
105
|
|
|
@@ -19,15 +19,19 @@
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import type { ImportedSheetData } from 'treb-base-types
|
|
22
|
+
import type { ImportedSheetData } from 'treb-base-types';
|
|
23
|
+
import type { SerializedModel } from 'treb-data-model';
|
|
23
24
|
|
|
24
25
|
import { Exporter } from '../export2';
|
|
25
26
|
import { Importer } from '../import2';
|
|
26
27
|
|
|
27
|
-
const ctx: Worker = self as
|
|
28
|
+
const ctx: Worker = self as unknown as Worker;
|
|
28
29
|
const exporter = new Exporter();
|
|
29
30
|
|
|
30
|
-
const ExportSheets = (data:
|
|
31
|
+
const ExportSheets = (data: {
|
|
32
|
+
sheet: SerializedModel,
|
|
33
|
+
decorated: Record<string, string>,
|
|
34
|
+
}) => {
|
|
31
35
|
|
|
32
36
|
if (data.sheet) {
|
|
33
37
|
exporter.Init(data.decorated || []);
|
|
@@ -37,17 +41,19 @@ const ExportSheets = (data: any) => {
|
|
|
37
41
|
|
|
38
42
|
};
|
|
39
43
|
|
|
40
|
-
const ImportSheet = (data:
|
|
44
|
+
const ImportSheet = (data: { data: ArrayBuffer }) => {
|
|
41
45
|
|
|
42
46
|
const importer = new Importer();
|
|
43
47
|
|
|
44
48
|
try {
|
|
45
49
|
importer.Init(data.data);
|
|
46
50
|
|
|
51
|
+
const named = importer.workbook?.GetNamedRanges();
|
|
52
|
+
|
|
47
53
|
const count = importer.SheetCount();
|
|
48
54
|
const results = {
|
|
49
55
|
sheets: [] as ImportedSheetData[],
|
|
50
|
-
|
|
56
|
+
named,
|
|
51
57
|
active_tab: importer.workbook?.active_tab,
|
|
52
58
|
};
|
|
53
59
|
|
|
@@ -58,6 +64,15 @@ const ImportSheet = (data: any) => {
|
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
for (const entry of named || []) {
|
|
68
|
+
if (typeof entry.local_scope === 'number') {
|
|
69
|
+
const sheet = results.sheets[entry.local_scope];
|
|
70
|
+
if (sheet) {
|
|
71
|
+
entry.scope = sheet.name;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
61
76
|
ctx.postMessage({ status: 'complete', results });
|
|
62
77
|
|
|
63
78
|
}
|
|
@@ -72,9 +87,9 @@ const ImportSheet = (data: any) => {
|
|
|
72
87
|
// initialize message handler
|
|
73
88
|
ctx.addEventListener('message', (event) => {
|
|
74
89
|
if (event.data && event.data.command === 'export'){
|
|
75
|
-
ExportSheets(event.data);
|
|
90
|
+
ExportSheets(event.data as { sheet: SerializedModel, decorated: Record<string, string>});
|
|
76
91
|
}
|
|
77
92
|
else if (event.data && event.data.command === 'import'){
|
|
78
|
-
ImportSheet(event.data);
|
|
93
|
+
ImportSheet(event.data as { data: ArrayBuffer });
|
|
79
94
|
}
|
|
80
95
|
});
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
|
|
28
28
|
// import JSZip from 'jszip';
|
|
29
29
|
|
|
30
|
-
import UZip from 'uzip';
|
|
31
30
|
import * as Base64JS from 'base64-js';
|
|
32
31
|
|
|
33
32
|
import { PixelsToColumnWidth } from './column-width';
|
|
@@ -35,7 +34,7 @@ import { PixelsToColumnWidth } from './column-width';
|
|
|
35
34
|
const XMLDeclaration = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n`;
|
|
36
35
|
|
|
37
36
|
import { template } from './template-2';
|
|
38
|
-
import type { SerializedSheet } from 'treb-
|
|
37
|
+
import type { SerializedModel, SerializedSheet } from 'treb-data-model';
|
|
39
38
|
|
|
40
39
|
import type { IArea, ICellAddress, CellValue, DataValidation, CellStyle,
|
|
41
40
|
AnnotationLayout, Corner as LayoutCorner, Cell, Rectangle } from 'treb-base-types';
|
|
@@ -52,7 +51,7 @@ import { Theme } from './workbook-theme2';
|
|
|
52
51
|
|
|
53
52
|
import type { RelationshipMap} from './relationship';
|
|
54
53
|
import { AddRel } from './relationship';
|
|
55
|
-
import { XMLOptions2 } from './xml-utils';
|
|
54
|
+
import { type DOMContent, XMLOptions2 } from './xml-utils';
|
|
56
55
|
|
|
57
56
|
import type { UnitAddress, UnitRange, ExpressionUnit} from 'treb-parser';
|
|
58
57
|
import { Parser, QuotedSheetNameRegex } from 'treb-parser';
|
|
@@ -64,9 +63,15 @@ import type { ImageOptions } from './drawing2/embedded-image';
|
|
|
64
63
|
import type { TwoCellAnchor } from './drawing2/drawing2';
|
|
65
64
|
import { Drawing } from './drawing2/drawing2';
|
|
66
65
|
import { ConditionalFormatOperators, type TableDescription, type TableFooterType } from './workbook2';
|
|
67
|
-
import type { AnnotationData } from 'treb-
|
|
66
|
+
import type { AnnotationData } from 'treb-data-model/src/annotation';
|
|
68
67
|
import { ZipWrapper } from './zip-wrapper';
|
|
69
68
|
|
|
69
|
+
/*
|
|
70
|
+
interface NestedDOMType {
|
|
71
|
+
[index: string]: string|number|NestedDOMType|NestedDOMType[];
|
|
72
|
+
}
|
|
73
|
+
*/
|
|
74
|
+
|
|
70
75
|
export class Exporter {
|
|
71
76
|
|
|
72
77
|
// public zip?: JSZip;
|
|
@@ -153,14 +158,14 @@ export class Exporter {
|
|
|
153
158
|
|
|
154
159
|
const keys = Object.keys(rels);
|
|
155
160
|
|
|
156
|
-
const dom = {
|
|
161
|
+
const dom: DOMContent = {
|
|
157
162
|
Relationships: {
|
|
158
163
|
a$: {
|
|
159
164
|
xmlns: 'http://schemas.openxmlformats.org/package/2006/relationships',
|
|
160
165
|
},
|
|
161
166
|
Relationship: keys.map(key => {
|
|
162
167
|
const rel = rels[key];
|
|
163
|
-
const a$:
|
|
168
|
+
const a$: DOMContent = {
|
|
164
169
|
Id: rel.id,
|
|
165
170
|
Target: rel.target,
|
|
166
171
|
Type: rel.type,
|
|
@@ -198,7 +203,8 @@ export class Exporter {
|
|
|
198
203
|
|
|
199
204
|
// we could just pass through except that we have argb and excel has rgb
|
|
200
205
|
|
|
201
|
-
const attrs:
|
|
206
|
+
const attrs: XlColor & { rgb?: string } = {};
|
|
207
|
+
|
|
202
208
|
if (color.indexed !== undefined) {
|
|
203
209
|
attrs.indexed = color.indexed;
|
|
204
210
|
}
|
|
@@ -212,10 +218,11 @@ export class Exporter {
|
|
|
212
218
|
attrs.rgb = color.argb;
|
|
213
219
|
}
|
|
214
220
|
return attrs;
|
|
221
|
+
|
|
215
222
|
};
|
|
216
223
|
|
|
217
224
|
const xfs = style_cache.cell_xfs.map(xf => {
|
|
218
|
-
const block:
|
|
225
|
+
const block: DOMContent = {
|
|
219
226
|
a$: {
|
|
220
227
|
numFmtId: xf.number_format,
|
|
221
228
|
fontId: xf.font,
|
|
@@ -225,22 +232,24 @@ export class Exporter {
|
|
|
225
232
|
};
|
|
226
233
|
|
|
227
234
|
if (xf.horizontal_alignment || xf.vertical_alignment || xf.wrap_text || xf.indent) {
|
|
228
|
-
|
|
229
|
-
|
|
235
|
+
|
|
236
|
+
const attrs: DOMContent = {};
|
|
230
237
|
|
|
231
238
|
if (xf.horizontal_alignment) {
|
|
232
|
-
|
|
239
|
+
attrs.horizontal = xf.horizontal_alignment;
|
|
233
240
|
}
|
|
234
241
|
if (xf.vertical_alignment) {
|
|
235
|
-
|
|
242
|
+
attrs.vertical = xf.vertical_alignment;
|
|
236
243
|
}
|
|
237
244
|
if (xf.wrap_text) {
|
|
238
|
-
|
|
245
|
+
attrs.wrapText = 1;
|
|
239
246
|
}
|
|
240
247
|
if (xf.indent && xf.horizontal_alignment !== 'center') {
|
|
241
|
-
|
|
248
|
+
attrs.indent = xf.indent;
|
|
242
249
|
}
|
|
243
250
|
|
|
251
|
+
block.alignment = { a$: attrs };
|
|
252
|
+
|
|
244
253
|
}
|
|
245
254
|
|
|
246
255
|
return block;
|
|
@@ -377,7 +386,7 @@ export class Exporter {
|
|
|
377
386
|
return block;
|
|
378
387
|
});
|
|
379
388
|
|
|
380
|
-
const dom:
|
|
389
|
+
const dom: DOMContent = {
|
|
381
390
|
styleSheet: {
|
|
382
391
|
a$: {
|
|
383
392
|
'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
|
|
@@ -396,14 +405,14 @@ export class Exporter {
|
|
|
396
405
|
|
|
397
406
|
if (style_cache.number_formats.length) {
|
|
398
407
|
|
|
399
|
-
dom.styleSheet.numFmts = {
|
|
408
|
+
(dom.styleSheet as DOMContent).numFmts = {
|
|
400
409
|
a$: { count: style_cache.number_formats.length },
|
|
401
410
|
numFmt: style_cache.number_formats.map(format => {
|
|
402
411
|
return {
|
|
403
412
|
a$: {
|
|
404
413
|
numFmtId: format.id,
|
|
405
414
|
formatCode: format.format,
|
|
406
|
-
},
|
|
415
|
+
} as DOMContent,
|
|
407
416
|
};
|
|
408
417
|
}),
|
|
409
418
|
};
|
|
@@ -414,21 +423,21 @@ export class Exporter {
|
|
|
414
423
|
}
|
|
415
424
|
|
|
416
425
|
if (fonts.length) {
|
|
417
|
-
dom.styleSheet.fonts = {
|
|
426
|
+
(dom.styleSheet as DOMContent).fonts = {
|
|
418
427
|
a$: { count: fonts.length },
|
|
419
428
|
font: fonts,
|
|
420
429
|
};
|
|
421
430
|
}
|
|
422
431
|
|
|
423
432
|
if (fills.length) {
|
|
424
|
-
dom.styleSheet.fills = {
|
|
433
|
+
(dom.styleSheet as DOMContent).fills = {
|
|
425
434
|
a$: { count: fills.length },
|
|
426
435
|
fill: fills,
|
|
427
436
|
};
|
|
428
437
|
}
|
|
429
438
|
|
|
430
439
|
if (borders.length) {
|
|
431
|
-
dom.styleSheet.borders = {
|
|
440
|
+
(dom.styleSheet as DOMContent).borders = {
|
|
432
441
|
a$: { count: borders.length },
|
|
433
442
|
border: borders,
|
|
434
443
|
};
|
|
@@ -437,27 +446,27 @@ export class Exporter {
|
|
|
437
446
|
// console.info("B", borders, JSON.stringify(dom.styleSheet.borders, undefined, 2))
|
|
438
447
|
|
|
439
448
|
if (xfs.length) {
|
|
440
|
-
dom.styleSheet.cellXfs = {
|
|
449
|
+
(dom.styleSheet as DOMContent).cellXfs = {
|
|
441
450
|
a$: { count: xfs.length },
|
|
442
451
|
xf: xfs,
|
|
443
452
|
};
|
|
444
453
|
}
|
|
445
454
|
|
|
446
455
|
if (style_cache.dxf_styles.length) {
|
|
447
|
-
const dxf:
|
|
456
|
+
const dxf: DOMContent[] = [];
|
|
448
457
|
for (const style of style_cache.dxf_styles) {
|
|
449
|
-
const entry:
|
|
458
|
+
const entry: DOMContent = {};
|
|
450
459
|
if (style.text || style.bold || style.italic || style.underline) {
|
|
451
|
-
const font:
|
|
460
|
+
const font: DOMContent = {};
|
|
452
461
|
if (style.text) {
|
|
453
462
|
font.color = { a$: {}};
|
|
454
463
|
if (style.text.text) {
|
|
455
|
-
font.color.a
|
|
464
|
+
(font.color.a$ as DOMContent).rgb = `FF` + style.text.text.substring(1);
|
|
456
465
|
}
|
|
457
466
|
else if (style.text.theme) {
|
|
458
|
-
font.color.a
|
|
467
|
+
(font.color.a$ as DOMContent).theme = style.text.theme;
|
|
459
468
|
if (style.text.tint) {
|
|
460
|
-
font.color.a
|
|
469
|
+
(font.color.a$ as DOMContent).tint = style.text.tint;
|
|
461
470
|
}
|
|
462
471
|
}
|
|
463
472
|
}
|
|
@@ -476,23 +485,24 @@ export class Exporter {
|
|
|
476
485
|
entry.font = font;
|
|
477
486
|
}
|
|
478
487
|
if (style.fill) {
|
|
479
|
-
const
|
|
488
|
+
const attrs: DOMContent = {};
|
|
480
489
|
if (style.fill.text) {
|
|
481
|
-
|
|
490
|
+
attrs.rgb = `FF` + style.fill.text.substring(1);
|
|
482
491
|
}
|
|
483
492
|
else if (style.fill.theme) {
|
|
484
|
-
|
|
493
|
+
attrs.theme = style.fill.theme;
|
|
485
494
|
if (style.fill.tint) {
|
|
486
|
-
|
|
495
|
+
attrs.tint = style.fill.tint;
|
|
487
496
|
}
|
|
488
497
|
}
|
|
498
|
+
const color: DOMContent = { a$: attrs };
|
|
489
499
|
entry.fill = { patternFill: { bgColor: color }};
|
|
490
500
|
}
|
|
491
501
|
dxf.push(entry);
|
|
492
502
|
}
|
|
493
503
|
|
|
494
504
|
if (dxf.length) {
|
|
495
|
-
dom.styleSheet.dxfs = {
|
|
505
|
+
(dom.styleSheet as DOMContent).dxfs = {
|
|
496
506
|
a$: { count: dxf.length },
|
|
497
507
|
dxf,
|
|
498
508
|
};
|
|
@@ -527,7 +537,7 @@ export class Exporter {
|
|
|
527
537
|
throw new Error('missing zip');
|
|
528
538
|
}
|
|
529
539
|
|
|
530
|
-
const dom:
|
|
540
|
+
const dom: DOMContent = {
|
|
531
541
|
sst: {
|
|
532
542
|
a$: {
|
|
533
543
|
'xmlns': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
|
|
@@ -1206,13 +1216,7 @@ export class Exporter {
|
|
|
1206
1216
|
|
|
1207
1217
|
}
|
|
1208
1218
|
|
|
1209
|
-
public Export(source: {
|
|
1210
|
-
sheet_data: SerializedSheet[];
|
|
1211
|
-
active_sheet?: number;
|
|
1212
|
-
named_ranges?: {[index: string]: IArea};
|
|
1213
|
-
named_expressions?: Array<{ name: string, expression: string }>;
|
|
1214
|
-
decimal_mark: ','|'.';
|
|
1215
|
-
}) {
|
|
1219
|
+
public Export(source: SerializedModel) {
|
|
1216
1220
|
|
|
1217
1221
|
// --- create a map --------------------------------------------------------
|
|
1218
1222
|
|
|
@@ -2443,6 +2447,68 @@ export class Exporter {
|
|
|
2443
2447
|
this.WriteRels(workbook_rels, `xl/_rels/workbook.xml.rels`);
|
|
2444
2448
|
|
|
2445
2449
|
let definedNames: any = {definedName: []};
|
|
2450
|
+
|
|
2451
|
+
if (source.named) {
|
|
2452
|
+
for (const entry of source.named) {
|
|
2453
|
+
|
|
2454
|
+
let scope: string|undefined = undefined;
|
|
2455
|
+
|
|
2456
|
+
if (entry.scope) {
|
|
2457
|
+
|
|
2458
|
+
const test = entry.scope.toLowerCase();
|
|
2459
|
+
for (const [index, sheet] of source.sheet_data.entries()) {
|
|
2460
|
+
if (sheet.name?.toLowerCase() === test) {
|
|
2461
|
+
scope = index.toString();
|
|
2462
|
+
break;
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
if (entry.area) {
|
|
2468
|
+
let sheet_name = '';
|
|
2469
|
+
const area = new Area(entry.area.start, entry.area.end);
|
|
2470
|
+
area.start.absolute_column = area.start.absolute_row = true;
|
|
2471
|
+
area.end.absolute_column = area.end.absolute_row = true;
|
|
2472
|
+
|
|
2473
|
+
if (entry.area.start.sheet) {
|
|
2474
|
+
sheet_name = entry.area.start.sheet;
|
|
2475
|
+
}
|
|
2476
|
+
else if (entry.area.start.sheet_id) {
|
|
2477
|
+
for (const sheet of source.sheet_data) {
|
|
2478
|
+
if (sheet.id === area.start.sheet_id) {
|
|
2479
|
+
sheet_name = sheet.name || '';
|
|
2480
|
+
break;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
|
|
2485
|
+
if (sheet_name) {
|
|
2486
|
+
if (QuotedSheetNameRegex.test(sheet_name)) {
|
|
2487
|
+
sheet_name = `'${sheet_name}'`;
|
|
2488
|
+
}
|
|
2489
|
+
sheet_name += '!';
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
// console.info({key, area, lx: area.spreadsheet_label, sheet_name });
|
|
2493
|
+
definedNames.definedName.push({
|
|
2494
|
+
a$: { name: entry.name, localSheetId: scope },
|
|
2495
|
+
t$: sheet_name + area.spreadsheet_label,
|
|
2496
|
+
});
|
|
2497
|
+
|
|
2498
|
+
}
|
|
2499
|
+
else if (entry.expression) {
|
|
2500
|
+
definedNames.definedName.push({
|
|
2501
|
+
a$: { name: entry.name, localSheetId: scope },
|
|
2502
|
+
t$: entry.expression,
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
console.info("DB", definedNames);
|
|
2510
|
+
|
|
2511
|
+
/*
|
|
2446
2512
|
if (source.named_ranges) {
|
|
2447
2513
|
const keys = Object.keys(source.named_ranges);
|
|
2448
2514
|
for (const key of keys) {
|
|
@@ -2483,10 +2549,13 @@ export class Exporter {
|
|
|
2483
2549
|
});
|
|
2484
2550
|
}
|
|
2485
2551
|
}
|
|
2552
|
+
*/
|
|
2553
|
+
|
|
2486
2554
|
if (!definedNames.definedName.length) {
|
|
2487
2555
|
definedNames = undefined;
|
|
2488
2556
|
}
|
|
2489
|
-
|
|
2557
|
+
// else { console.info({definedNames}); }
|
|
2558
|
+
|
|
2490
2559
|
const workbook_dom: any = {
|
|
2491
2560
|
workbook: {
|
|
2492
2561
|
a$: {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
// import JSZip from 'jszip';
|
|
23
23
|
|
|
24
|
-
import UZip from 'uzip';
|
|
24
|
+
// import UZip from 'uzip';
|
|
25
25
|
import Base64JS from 'base64-js';
|
|
26
26
|
|
|
27
27
|
import type { AnchoredChartDescription, AnchoredImageDescription, AnchoredTextBoxDescription} from './workbook2';
|
|
@@ -31,7 +31,7 @@ import { Parser } from 'treb-parser';
|
|
|
31
31
|
import type { RangeType, AddressType, HyperlinkType } from './address-type';
|
|
32
32
|
import { is_range, ShiftRange, InRange, is_address } from './address-type';
|
|
33
33
|
import type { ImportedSheetData, AnchoredAnnotation, CellParseResult, AnnotationLayout, Corner as LayoutCorner, ICellAddress, DataValidation, IArea, GradientStop, Color } from 'treb-base-types/src';
|
|
34
|
-
import {
|
|
34
|
+
import { ValidationType, type SerializedValueType } from 'treb-base-types/src';
|
|
35
35
|
import type { Sheet} from './workbook-sheet2';
|
|
36
36
|
import { VisibleState } from './workbook-sheet2';
|
|
37
37
|
import type { CellAnchor } from './drawing2/drawing2';
|
|
@@ -39,8 +39,9 @@ import { XMLUtils } from './xml-utils';
|
|
|
39
39
|
|
|
40
40
|
// import { one_hundred_pixels } from './constants';
|
|
41
41
|
import { ColumnWidthToPixels } from './column-width';
|
|
42
|
-
import type { AnnotationType
|
|
42
|
+
import type { AnnotationType } from 'treb-data-model';
|
|
43
43
|
import { ZipWrapper } from './zip-wrapper';
|
|
44
|
+
import type { ConditionalFormat } from 'treb-data-model';
|
|
44
45
|
|
|
45
46
|
interface SharedFormula {
|
|
46
47
|
row: number;
|
|
@@ -146,7 +147,7 @@ export class Importer {
|
|
|
146
147
|
|
|
147
148
|
if (element.a$?.t && element.a$.t === 's') {
|
|
148
149
|
type = 'string'; // ValueType.string;
|
|
149
|
-
if (typeof element.v !== undefined) {
|
|
150
|
+
if (typeof element.v !== 'undefined') {
|
|
150
151
|
const index = Number(element.v);
|
|
151
152
|
if (!isNaN(index) && sheet.shared_strings) {
|
|
152
153
|
value = sheet.shared_strings.Get(index) || '';
|
|
@@ -934,7 +935,7 @@ export class Importer {
|
|
|
934
935
|
br: AnchorToCorner(descriptor.anchor.to),
|
|
935
936
|
};
|
|
936
937
|
|
|
937
|
-
|
|
938
|
+
const type: AnnotationType = 'image';
|
|
938
939
|
const data = Base64JS.fromByteArray(descriptor.image);
|
|
939
940
|
let imagetype: string = '';
|
|
940
941
|
|
|
@@ -19,12 +19,6 @@
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import UZip from 'uzip';
|
|
23
|
-
|
|
24
|
-
// import type JSZip from 'jszip';
|
|
25
|
-
// import * as xmlparser from 'fast-xml-parser';
|
|
26
|
-
|
|
27
|
-
|
|
28
22
|
import { XMLParser } from 'fast-xml-parser';
|
|
29
23
|
import { XMLUtils, XMLOptions, XMLOptions2 } from './xml-utils';
|
|
30
24
|
|
|
@@ -45,6 +39,7 @@ import { Sheet, VisibleState } from './workbook-sheet2';
|
|
|
45
39
|
import type { RelationshipMap } from './relationship';
|
|
46
40
|
import { ZipWrapper } from './zip-wrapper';
|
|
47
41
|
import type { CellStyle } from 'treb-base-types';
|
|
42
|
+
import type { CompositeNamed } from 'treb-data-model';
|
|
48
43
|
|
|
49
44
|
|
|
50
45
|
/*
|
|
@@ -157,8 +152,10 @@ export class Workbook {
|
|
|
157
152
|
/** theme */
|
|
158
153
|
public theme = new Theme();
|
|
159
154
|
|
|
160
|
-
|
|
161
|
-
public defined_names: Record<string, string> = {};
|
|
155
|
+
/* * defined names. these can be ranges or expressions. */
|
|
156
|
+
// public defined_names: Record<string, string> = {};
|
|
157
|
+
|
|
158
|
+
public named: Array<CompositeNamed & {local_scope?: number}> = [];
|
|
162
159
|
|
|
163
160
|
/** the workbook "rels" */
|
|
164
161
|
public rels: RelationshipMap = {};
|
|
@@ -229,15 +226,34 @@ export class Workbook {
|
|
|
229
226
|
xml = xmlparser2.parse(data);
|
|
230
227
|
|
|
231
228
|
// defined names
|
|
232
|
-
this.
|
|
229
|
+
this.named = [];
|
|
233
230
|
const defined_names = XMLUtils.FindAll(xml, 'workbook/definedNames/definedName');
|
|
234
231
|
for (const defined_name of defined_names) {
|
|
235
232
|
const name = defined_name.a$?.name;
|
|
236
233
|
const expression = defined_name.t$ || '';
|
|
234
|
+
const sheet_index = (defined_name.a$?.localSheetId) ? Number(defined_name.a$.localSheetId) : undefined;
|
|
235
|
+
|
|
236
|
+
// console.info({defined_name, name, expression, sheet_index});
|
|
237
|
+
this.named.push({
|
|
238
|
+
name,
|
|
239
|
+
expression: typeof expression === 'string' ? expression : expression?.toString() || '',
|
|
240
|
+
local_scope: sheet_index,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/*
|
|
246
|
+
this.defined_names = {};
|
|
247
|
+
const defined_names = XMLUtils.FindAll(xml, 'workbook/definedNames/definedName');
|
|
248
|
+
|
|
249
|
+
console.info({defined_names});
|
|
250
|
+
|
|
251
|
+
for (const defined_name of defined_names) {
|
|
237
252
|
if (name && expression) {
|
|
238
253
|
this.defined_names[name] = expression;
|
|
239
254
|
}
|
|
240
255
|
}
|
|
256
|
+
*/
|
|
241
257
|
|
|
242
258
|
const workbook_views = XMLUtils.FindAll(xml, 'workbook/bookViews/workbookView');
|
|
243
259
|
|
|
@@ -390,7 +406,7 @@ export class Workbook {
|
|
|
390
406
|
const fill = sppr['a:solidFill'];
|
|
391
407
|
if (fill) {
|
|
392
408
|
if (fill['a:schemeClr']?.a$?.val) {
|
|
393
|
-
|
|
409
|
+
const m = (fill['a:schemeClr'].a$.val).match(/accent(\d+)/);
|
|
394
410
|
if (m) {
|
|
395
411
|
style.fill = { theme: Number(m[1]) + 3 }
|
|
396
412
|
if (fill['a:schemeClr']['a:lumOff']?.a$?.val) {
|
|
@@ -428,7 +444,7 @@ export class Workbook {
|
|
|
428
444
|
const para: { text: string, style?: CellStyle }[] = [];
|
|
429
445
|
let style: CellStyle|undefined;
|
|
430
446
|
|
|
431
|
-
|
|
447
|
+
const appr = paragraph['a:pPr'];
|
|
432
448
|
if (appr) {
|
|
433
449
|
style = {};
|
|
434
450
|
if (appr.a$?.algn === 'r') {
|
|
@@ -673,13 +689,15 @@ export class Workbook {
|
|
|
673
689
|
}
|
|
674
690
|
|
|
675
691
|
/** FIXME: accessor */
|
|
676
|
-
public GetNamedRanges()
|
|
692
|
+
public GetNamedRanges() {
|
|
677
693
|
|
|
678
694
|
// ... what does this do, not do, or what is it supposed to do?
|
|
679
695
|
// note that this is called by the import routine, so it probably
|
|
680
696
|
// expects to do something
|
|
681
697
|
|
|
682
|
-
return this.defined_names;
|
|
698
|
+
// return this.defined_names;
|
|
699
|
+
|
|
700
|
+
return this.named;
|
|
683
701
|
|
|
684
702
|
}
|
|
685
703
|
|
|
@@ -24,6 +24,10 @@ import type { X2jOptions } from 'fast-xml-parser';
|
|
|
24
24
|
|
|
25
25
|
export const XMLTagProcessor = (name: string, value: string): string => Unescape(value);
|
|
26
26
|
|
|
27
|
+
export interface DOMContent {
|
|
28
|
+
[index: string]: string|DOMContent|string[]|DOMContent[]|number|number[];
|
|
29
|
+
}
|
|
30
|
+
|
|
27
31
|
export const XMLOptions: Partial<X2jOptions> = {
|
|
28
32
|
ignoreAttributes: false,
|
|
29
33
|
attributeNamePrefix: '__',
|
|
@@ -48,7 +52,7 @@ export const XMLOptions2: Partial<X2jOptions> = {
|
|
|
48
52
|
|
|
49
53
|
// arrayMode: false, // this was removed in FXP, but false is default anyway
|
|
50
54
|
|
|
51
|
-
isArray: (tagName: string
|
|
55
|
+
isArray: (tagName: string) => {
|
|
52
56
|
return /Relationship$/.test(tagName);
|
|
53
57
|
},
|
|
54
58
|
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
/* eslint-disable no-irregular-whitespace */
|
|
23
|
+
|
|
22
24
|
import { FormatParser } from './format_parser';
|
|
23
25
|
import { NumberFormatSection } from './number_format_section';
|
|
24
26
|
import type { TextPart, Complex, DimensionedQuantity, CellValue} from 'treb-base-types';
|
|
@@ -534,7 +536,7 @@ export class NumberFormat {
|
|
|
534
536
|
if (has_imaginary_value) {
|
|
535
537
|
|
|
536
538
|
// also has imaginary part
|
|
537
|
-
const i = Math.abs(value.imaginary);
|
|
539
|
+
// const i = Math.abs(value.imaginary);
|
|
538
540
|
parts.push({ text: value.imaginary < 0 ? ` ${NumberFormat.minus_character} ` : ' + ' });
|
|
539
541
|
|
|
540
542
|
const reformatted_imaginary = drop_imaginary_coefficient ?
|
|
@@ -559,7 +561,7 @@ export class NumberFormat {
|
|
|
559
561
|
* states. it's intended for graphical representation where things
|
|
560
562
|
* like hidden characters and padding require multiple passes or measurement.
|
|
561
563
|
*/
|
|
562
|
-
public FormatParts(value:
|
|
564
|
+
public FormatParts(value: CellValue): TextPart[] {
|
|
563
565
|
|
|
564
566
|
// new, shortcut
|
|
565
567
|
if (typeof value !== 'number' && !this.sections[3]) {
|
|
@@ -567,7 +569,7 @@ export class NumberFormat {
|
|
|
567
569
|
// NOTE: that note (next line) seems to be incorrect, not sure why
|
|
568
570
|
// ofc if that was true there'd be no point to this block...
|
|
569
571
|
|
|
570
|
-
return [{ text: value.toString() }] as TextPart[]; // unreachable because we ensure 4 sections
|
|
572
|
+
return [{ text: (value??'').toString() }] as TextPart[]; // unreachable because we ensure 4 sections
|
|
571
573
|
}
|
|
572
574
|
|
|
573
575
|
const { parts, section } = this.BaseFormat(value);
|
|
@@ -621,7 +623,7 @@ export class NumberFormat {
|
|
|
621
623
|
* FIXME: date, string (this is lagging)
|
|
622
624
|
* UPDATE: unifying, basing this on the text part functionality
|
|
623
625
|
*/
|
|
624
|
-
public Format(value:
|
|
626
|
+
public Format(value: CellValue, text_width = 0): string {
|
|
625
627
|
|
|
626
628
|
/*
|
|
627
629
|
const parts = this.FormatParts(value);
|
|
@@ -857,14 +859,14 @@ export class NumberFormat {
|
|
|
857
859
|
|
|
858
860
|
}
|
|
859
861
|
|
|
860
|
-
public BaseFormat(value:
|
|
862
|
+
public BaseFormat(value: CellValue) {
|
|
861
863
|
|
|
862
864
|
if (this.sections[0].date_format) {
|
|
863
865
|
return this.DateFormat(Number(value));
|
|
864
866
|
}
|
|
865
867
|
|
|
866
868
|
if (typeof value !== 'number') {
|
|
867
|
-
return this.StringFormat(value.toString(), this.sections[3]);
|
|
869
|
+
return this.StringFormat((value??'').toString(), this.sections[3]);
|
|
868
870
|
}
|
|
869
871
|
|
|
870
872
|
let section = this.sections[0];
|