@shbernal/ts-xlsx 3.0.0 → 3.2.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 +34 -24
- package/dist/bytes.d.ts +10 -2
- package/dist/bytes.js +22 -0
- package/dist/core/address.d.ts +96 -2
- package/dist/core/address.js +87 -33
- package/dist/core/array-formula-ranges.d.ts +33 -0
- package/dist/core/array-formula-ranges.js +62 -0
- package/dist/core/autofilter.d.ts +4 -3
- package/dist/core/autofilter.js +31 -30
- package/dist/core/axis-handle.d.ts +2 -0
- package/dist/core/axis-handle.js +5 -2
- package/dist/core/cell.d.ts +4 -3
- package/dist/core/cell.js +4 -6
- package/dist/core/clone.d.ts +29 -0
- package/dist/core/clone.js +24 -0
- package/dist/core/color-resolution.js +4 -6
- package/dist/core/column.d.ts +1 -0
- package/dist/core/column.js +6 -2
- package/dist/core/comment-thread.d.ts +7 -3
- package/dist/core/comment-thread.js +2 -1
- package/dist/core/conditional-formatting-overlay.d.ts +11 -1
- package/dist/core/conditional-formatting-overlay.js +30 -3
- package/dist/core/conditional-formatting.d.ts +107 -11
- package/dist/core/conditional-formatting.js +76 -19
- package/dist/core/containers.d.ts +12 -0
- package/dist/core/containers.js +5 -0
- package/dist/core/data-validation-overlay.d.ts +7 -1
- package/dist/core/data-validation-overlay.js +19 -4
- package/dist/core/data-validation.d.ts +22 -0
- package/dist/core/data-validation.js +30 -4
- package/dist/core/date-format.d.ts +20 -0
- package/dist/core/date-format.js +170 -0
- package/dist/core/date.d.ts +43 -8
- package/dist/core/date.js +19 -3
- package/dist/core/formula-references.d.ts +26 -0
- package/dist/core/formula-references.js +173 -0
- package/dist/core/formula-scan.d.ts +2 -0
- package/dist/core/formula-scan.js +58 -0
- package/dist/core/formula.d.ts +76 -17
- package/dist/core/formula.js +87 -80
- package/dist/core/function-values.d.ts +4 -0
- package/dist/core/function-values.js +58 -0
- package/dist/core/future-functions.d.ts +3 -0
- package/dist/core/{modern-functions.js → future-functions.js} +119 -88
- package/dist/core/grid-edits.d.ts +30 -3
- package/dist/core/grid-edits.js +248 -81
- package/dist/core/grid-shift.d.ts +58 -9
- package/dist/core/grid-shift.js +26 -4
- package/dist/core/hyperlink.d.ts +39 -0
- package/dist/core/hyperlink.js +88 -0
- package/dist/core/image.d.ts +49 -14
- package/dist/core/image.js +16 -5
- package/dist/core/internal.d.ts +10 -2
- package/dist/core/limits.d.ts +25 -0
- package/dist/core/limits.js +4 -0
- package/dist/core/merge.d.ts +18 -4
- package/dist/core/merge.js +33 -20
- package/dist/core/page-setup.d.ts +26 -11
- package/dist/core/pivot-table.d.ts +49 -10
- package/dist/core/pivot-table.js +112 -60
- package/dist/core/protection.d.ts +66 -4
- package/dist/core/protection.js +6 -11
- package/dist/core/range.js +34 -30
- package/dist/core/row-input.js +2 -2
- package/dist/core/row.d.ts +1 -0
- package/dist/core/row.js +6 -2
- package/dist/core/structured-reference.d.ts +7 -0
- package/dist/core/structured-reference.js +7 -0
- package/dist/core/style.d.ts +85 -70
- package/dist/core/style.js +92 -28
- package/dist/core/table-style.d.ts +1 -1
- package/dist/core/table-style.js +4 -4
- package/dist/core/table.d.ts +64 -16
- package/dist/core/table.js +87 -40
- package/dist/core/theme.d.ts +2 -0
- package/dist/core/theme.js +9 -5
- package/dist/core/value.d.ts +60 -28
- package/dist/core/value.js +48 -43
- package/dist/core/workbook-media.d.ts +34 -0
- package/dist/core/workbook-media.js +44 -0
- package/dist/core/workbook-styles.d.ts +83 -1
- package/dist/core/workbook-styles.js +4 -0
- package/dist/core/workbook-theme.js +5 -3
- package/dist/core/workbook-vba.js +3 -2
- package/dist/core/workbook.d.ts +41 -3
- package/dist/core/workbook.js +46 -41
- package/dist/core/worksheet-comments.d.ts +2 -1
- package/dist/core/worksheet-comments.js +20 -13
- package/dist/core/worksheet-merges.d.ts +49 -0
- package/dist/core/worksheet-merges.js +65 -0
- package/dist/core/worksheet-model.d.ts +10 -2
- package/dist/core/worksheet-model.js +28 -9
- package/dist/core/worksheet-pictures.d.ts +3 -3
- package/dist/core/worksheet-pictures.js +7 -6
- package/dist/core/worksheet.d.ts +165 -27
- package/dist/core/worksheet.js +206 -89
- package/dist/customui/ribbon.js +2 -1
- package/dist/entries/core.d.ts +21 -14
- package/dist/entries/core.js +14 -7
- package/dist/entries/errors.d.ts +1 -0
- package/dist/entries/errors.js +1 -0
- package/dist/entries/xlsx.d.ts +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +22 -0
- package/dist/hex.d.ts +8 -0
- package/dist/hex.js +3 -0
- package/dist/io/cell-metadata/metadata.d.ts +42 -0
- package/dist/io/cell-metadata/metadata.js +35 -0
- package/dist/io/cell-metadata/rich-values.d.ts +11 -0
- package/dist/io/cell-metadata/rich-values.js +80 -0
- package/dist/io/csv/delimiter.d.ts +21 -0
- package/dist/io/csv/delimiter.js +18 -0
- package/dist/io/csv/errors.d.ts +14 -0
- package/dist/io/csv/errors.js +5 -0
- package/dist/io/csv/read.d.ts +6 -1
- package/dist/io/csv/read.js +51 -22
- package/dist/io/csv/write.d.ts +19 -5
- package/dist/io/csv/write.js +24 -44
- package/dist/io/opc/inflate.js +14 -0
- package/dist/io/opc/namespaces.d.ts +16 -0
- package/dist/io/opc/namespaces.js +4 -0
- package/dist/io/opc/part-paths.d.ts +9 -0
- package/dist/io/opc/part-paths.js +5 -5
- package/dist/io/opc/read-opc.d.ts +58 -14
- package/dist/io/opc/read-opc.js +49 -21
- package/dist/io/opc/read-options.d.ts +5 -1
- package/dist/io/opc/sniff-format.d.ts +3 -3
- package/dist/io/opc/sniff-format.js +2 -2
- package/dist/io/opc/strict-relationships.d.ts +2 -0
- package/dist/io/opc/strict-relationships.js +12 -0
- package/dist/io/read-policy/column-budget.d.ts +26 -0
- package/dist/io/read-policy/column-budget.js +18 -0
- package/dist/io/read-policy/read-repair.d.ts +74 -0
- package/dist/io/read-policy/read-repair.js +119 -0
- package/dist/io/style/cell-style-resolution.d.ts +25 -0
- package/dist/io/style/cell-style-resolution.js +30 -0
- package/dist/io/style/xf-style.d.ts +23 -1
- package/dist/io/style/xf-style.js +8 -0
- package/dist/io/xlsb/formula.d.ts +2 -2
- package/dist/io/xlsb/formula.js +52 -35
- package/dist/io/xlsb/primitives.js +8 -14
- package/dist/io/xlsb/ptg-functions.d.ts +19 -10
- package/dist/io/xlsb/ptg-functions.js +495 -596
- package/dist/io/xlsb/read-metadata.d.ts +7 -0
- package/dist/io/xlsb/read-metadata.js +69 -0
- package/dist/io/xlsb/read-styles.js +45 -81
- package/dist/io/xlsb/read-worksheet.d.ts +26 -1
- package/dist/io/xlsb/read-worksheet.js +148 -106
- package/dist/io/xlsb/read.d.ts +6 -3
- package/dist/io/xlsb/read.js +70 -31
- package/dist/io/xlsb/record-stream.d.ts +30 -0
- package/dist/io/xlsb/record-stream.js +20 -0
- package/dist/io/xlsb/record-types.d.ts +14 -5
- package/dist/io/xlsb/record-types.js +14 -5
- package/dist/io/xlsb/sheet-protection.d.ts +20 -0
- package/dist/io/xlsb/sheet-protection.js +60 -0
- package/dist/io/xlsx/cell-accumulator.d.ts +24 -9
- package/dist/io/xlsx/cell-accumulator.js +74 -21
- package/dist/io/xlsx/cell-metadata.d.ts +39 -0
- package/dist/io/xlsx/cell-metadata.js +162 -0
- package/dist/io/xlsx/cell-value.d.ts +19 -5
- package/dist/io/xlsx/cell-value.js +45 -30
- package/dist/io/xlsx/color-xml.js +3 -2
- package/dist/io/xlsx/column-span.d.ts +11 -0
- package/dist/io/xlsx/column-span.js +9 -0
- package/dist/io/xlsx/comments.d.ts +9 -30
- package/dist/io/xlsx/comments.js +25 -83
- package/dist/io/xlsx/conditional-formatting.d.ts +43 -23
- package/dist/io/xlsx/conditional-formatting.js +437 -138
- package/dist/io/xlsx/data-validation.d.ts +12 -7
- package/dist/io/xlsx/data-validation.js +67 -53
- package/dist/io/xlsx/edit-vba.d.ts +7 -2
- package/dist/io/xlsx/edit-vba.js +52 -52
- package/dist/io/xlsx/font-xml.d.ts +7 -0
- package/dist/io/xlsx/font-xml.js +104 -0
- package/dist/io/xlsx/hyperlinks.d.ts +19 -21
- package/dist/io/xlsx/hyperlinks.js +12 -32
- package/dist/io/xlsx/images.d.ts +49 -16
- package/dist/io/xlsx/images.js +149 -50
- package/dist/io/xlsx/namespaces.d.ts +24 -0
- package/dist/io/xlsx/namespaces.js +11 -0
- package/dist/io/xlsx/package-plan.d.ts +60 -15
- package/dist/io/xlsx/package-plan.js +83 -18
- package/dist/io/xlsx/part-names.d.ts +6 -8
- package/dist/io/xlsx/part-names.js +3 -7
- package/dist/io/xlsx/pivot.d.ts +5 -5
- package/dist/io/xlsx/pivot.js +26 -24
- package/dist/io/xlsx/preserved-splices.d.ts +6 -0
- package/dist/io/xlsx/preserved-splices.js +74 -0
- package/dist/io/xlsx/read-comments.d.ts +29 -0
- package/dist/io/xlsx/read-comments.js +75 -0
- package/dist/io/xlsx/read-parts.d.ts +59 -0
- package/dist/io/xlsx/read-parts.js +259 -0
- package/dist/io/xlsx/read-pivot.js +11 -4
- package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +8 -5
- package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +24 -4
- package/dist/io/xlsx/read-rows.d.ts +35 -11
- package/dist/io/xlsx/read-rows.js +73 -49
- package/dist/io/xlsx/read-shared-strings.js +3 -2
- package/dist/io/xlsx/read-styles.d.ts +0 -30
- package/dist/io/xlsx/read-styles.js +45 -105
- package/dist/io/xlsx/read-workbook-xml.d.ts +42 -0
- package/dist/io/xlsx/read-workbook-xml.js +175 -0
- package/dist/io/xlsx/read-worksheet.d.ts +9 -3
- package/dist/io/xlsx/read-worksheet.js +70 -177
- package/dist/io/xlsx/read.d.ts +3 -14
- package/dist/io/xlsx/read.js +74 -411
- package/dist/io/xlsx/relationships.d.ts +3 -0
- package/dist/io/xlsx/relationships.js +4 -0
- package/dist/io/xlsx/rich-text.js +1 -1
- package/dist/io/xlsx/row-position.d.ts +20 -0
- package/dist/io/xlsx/row-position.js +11 -0
- package/dist/io/xlsx/row-xml.d.ts +139 -0
- package/dist/io/xlsx/row-xml.js +222 -0
- package/dist/io/xlsx/shared-formulas.js +2 -2
- package/dist/io/xlsx/sheet-properties.d.ts +10 -1
- package/dist/io/xlsx/sheet-properties.js +182 -20
- package/dist/io/xlsx/strict-parts.d.ts +7 -0
- package/dist/io/xlsx/strict-parts.js +171 -0
- package/dist/io/xlsx/style-elements.d.ts +41 -0
- package/dist/io/xlsx/style-elements.js +136 -0
- package/dist/io/xlsx/styles.d.ts +17 -3
- package/dist/io/xlsx/styles.js +13 -209
- package/dist/io/xlsx/tables.d.ts +10 -2
- package/dist/io/xlsx/tables.js +55 -52
- package/dist/io/xlsx/theme-xml.d.ts +32 -4
- package/dist/io/xlsx/theme-xml.js +106 -71
- package/dist/io/xlsx/threaded-comments.d.ts +14 -11
- package/dist/io/xlsx/threaded-comments.js +16 -8
- package/dist/io/xlsx/workbook-xml.d.ts +45 -6
- package/dist/io/xlsx/workbook-xml.js +62 -54
- package/dist/io/xlsx/worksheet-xml.d.ts +26 -70
- package/dist/io/xlsx/worksheet-xml.js +69 -282
- package/dist/io/xlsx/write-stream.d.ts +90 -19
- package/dist/io/xlsx/write-stream.js +80 -25
- package/dist/io/xlsx/write.d.ts +12 -6
- package/dist/io/xlsx/write.js +226 -123
- package/dist/rel-type.d.ts +25 -0
- package/dist/rel-type.js +9 -0
- package/dist/token-set.d.ts +13 -0
- package/dist/token-set.js +4 -1
- package/dist/vba/bytes.d.ts +16 -5
- package/dist/vba/bytes.js +27 -6
- package/dist/vba/cfb-format.d.ts +55 -0
- package/dist/vba/cfb-format.js +35 -0
- package/dist/vba/cfb-writer.d.ts +8 -0
- package/dist/vba/cfb-writer.js +40 -40
- package/dist/vba/cfb.d.ts +21 -4
- package/dist/vba/cfb.js +124 -90
- package/dist/vba/codepage.js +2 -1
- package/dist/vba/dir-records.d.ts +6 -0
- package/dist/vba/dir-records.js +10 -2
- package/dist/vba/errors.d.ts +11 -4
- package/dist/vba/index.d.ts +0 -2
- package/dist/vba/index.js +0 -2
- package/dist/vba/ms-ovba.d.ts +6 -2
- package/dist/vba/ms-ovba.js +66 -22
- package/dist/vba/project-editor.js +129 -119
- package/dist/vba/project.d.ts +15 -1
- package/dist/vba/project.js +38 -13
- package/dist/vba/vba-encoding.d.ts +4 -10
- package/dist/vba/vba-encoding.js +3 -17
- package/dist/xml/xml-attrs.d.ts +37 -0
- package/dist/xml/xml-attrs.js +30 -0
- package/dist/xml/xml-chars.d.ts +40 -0
- package/dist/xml/xml-chars.js +12 -0
- package/dist/xml/xml-namespaces.d.ts +31 -0
- package/dist/xml/xml-namespaces.js +50 -0
- package/dist/xml/xml-read.d.ts +101 -11
- package/dist/xml/xml-read.js +150 -18
- package/dist/xml/xml-scan.d.ts +25 -34
- package/dist/xml/xml-scan.js +69 -46
- package/dist/xml/xml.d.ts +59 -26
- package/dist/xml/xml.js +45 -23
- package/package.json +15 -9
- package/skills/ts-xlsx-upstream/SKILL.md +21 -13
- package/dist/core/modern-functions.d.ts +0 -1
package/dist/core/autofilter.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AuthoringError } from '../errors.js';
|
|
1
|
+
import { AuthoringError, quoted } from '../errors.js';
|
|
2
2
|
import { tokenSet } from '../token-set.js';
|
|
3
|
-
import { decodeRange,
|
|
4
|
-
import { isDeletedSpan, shiftIndex } from './grid-shift.js';
|
|
3
|
+
import { boundedRect, decodeRange, encodeRect } from './address.js';
|
|
4
|
+
import { isDeletedSpan, shiftIndex, shiftRect } from './grid-shift.js';
|
|
5
5
|
export const isCustomFilterOperator = tokenSet({
|
|
6
6
|
equal: true,
|
|
7
7
|
notEqual: true,
|
|
@@ -12,15 +12,16 @@ export const isCustomFilterOperator = tokenSet({
|
|
|
12
12
|
});
|
|
13
13
|
export function canonicalizeAutoFilter(input) {
|
|
14
14
|
const ref = typeof input === 'string' ? input : input.ref;
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const decoded = decodeRange(ref);
|
|
16
|
+
const rect = boundedRect(decoded);
|
|
17
|
+
if (rect === undefined) {
|
|
18
|
+
throw new AuthoringError(`autofilter range ${quoted(ref)} must be a bounded rectangle`);
|
|
18
19
|
}
|
|
19
20
|
if (typeof input === 'string')
|
|
20
|
-
return { ref: dimensions, columns: [] };
|
|
21
|
-
const width = right - left + 1;
|
|
21
|
+
return { ref: decoded.dimensions, columns: [] };
|
|
22
|
+
const width = rect.right - rect.left + 1;
|
|
22
23
|
return {
|
|
23
|
-
ref: dimensions,
|
|
24
|
+
ref: decoded.dimensions,
|
|
24
25
|
columns: input.columns.map((column) => canonicalizeColumn(column, width)),
|
|
25
26
|
};
|
|
26
27
|
}
|
|
@@ -28,35 +29,35 @@ function canonicalizeColumn(column, width) {
|
|
|
28
29
|
if (!Number.isInteger(column.colId) || column.colId < 0 || column.colId >= width) {
|
|
29
30
|
throw new AuthoringError(`autofilter colId ${column.colId} is outside the filter range`);
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
throw new AuthoringError(`a custom filter needs one or two predicates, got ${count}`);
|
|
35
|
-
}
|
|
32
|
+
const criteria = column.criteria;
|
|
33
|
+
if (criteria.kind === 'values') {
|
|
34
|
+
return { colId: column.colId, criteria: { ...criteria, values: [...criteria.values] } };
|
|
36
35
|
}
|
|
37
|
-
|
|
36
|
+
const count = criteria.predicates.length;
|
|
37
|
+
if (count < 1 || count > 2) {
|
|
38
|
+
throw new AuthoringError(`a custom filter needs one or two predicates, got ${count}`);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
colId: column.colId,
|
|
42
|
+
criteria: { ...criteria, predicates: criteria.predicates.map((predicate) => ({ ...predicate })) },
|
|
43
|
+
};
|
|
38
44
|
}
|
|
39
|
-
export function shiftAutoFilter(filter,
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
45
|
+
export function shiftAutoFilter(filter, splice) {
|
|
46
|
+
const rect = boundedRect(decodeRange(filter.ref));
|
|
47
|
+
if (rect === undefined)
|
|
42
48
|
return filter;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (isDeletedSpan(lo, hi, start, count))
|
|
49
|
+
const moved = shiftRect(rect, splice);
|
|
50
|
+
if (moved === undefined)
|
|
46
51
|
return undefined;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
if (axis === 'row') {
|
|
50
|
-
const ref = `${encodeAddress(left, movedLo)}:${encodeAddress(right, movedHi)}`;
|
|
52
|
+
const ref = encodeRect(moved);
|
|
53
|
+
if (splice.axis === 'row')
|
|
51
54
|
return { ref, columns: filter.columns };
|
|
52
|
-
}
|
|
53
|
-
const ref = `${encodeAddress(movedLo, top)}:${encodeAddress(movedHi, bottom)}`;
|
|
54
55
|
const columns = [];
|
|
55
56
|
for (const column of filter.columns) {
|
|
56
|
-
const absolute = left + column.colId;
|
|
57
|
-
if (isDeletedSpan(absolute, absolute,
|
|
57
|
+
const absolute = rect.left + column.colId;
|
|
58
|
+
if (isDeletedSpan(absolute, absolute, splice))
|
|
58
59
|
continue;
|
|
59
|
-
columns.push({ ...column, colId: shiftIndex(absolute,
|
|
60
|
+
columns.push({ ...column, colId: shiftIndex(absolute, splice) - moved.left });
|
|
60
61
|
}
|
|
61
62
|
return { ref, columns };
|
|
62
63
|
}
|
|
@@ -3,6 +3,8 @@ export declare abstract class AxisHandle<P extends object> {
|
|
|
3
3
|
protected abstract propertiesOf(): P | undefined;
|
|
4
4
|
/** This position's format record, created if it does not exist yet. */
|
|
5
5
|
protected abstract ensureProperties(): P;
|
|
6
|
+
/** Remove this position's format record entirely, so nothing is left declaring the line. */
|
|
7
|
+
protected abstract dropProperties(): void;
|
|
6
8
|
protected read<K extends keyof P>(key: K): P[K] | undefined;
|
|
7
9
|
protected write<K extends keyof P>(key: K, value: P[K]): void;
|
|
8
10
|
}
|
package/dist/core/axis-handle.js
CHANGED
|
@@ -5,8 +5,11 @@ export class AxisHandle {
|
|
|
5
5
|
write(key, value) {
|
|
6
6
|
if (value === undefined) {
|
|
7
7
|
const properties = this.propertiesOf();
|
|
8
|
-
if (properties
|
|
9
|
-
|
|
8
|
+
if (properties === undefined)
|
|
9
|
+
return;
|
|
10
|
+
delete properties[key];
|
|
11
|
+
if (Object.keys(properties).length === 0)
|
|
12
|
+
this.dropProperties();
|
|
10
13
|
return;
|
|
11
14
|
}
|
|
12
15
|
this.ensureProperties()[key] = value;
|
package/dist/core/cell.d.ts
CHANGED
|
@@ -139,9 +139,10 @@ export declare class Cell {
|
|
|
139
139
|
set note(note: string | undefined);
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
|
-
* Whether a cell carries formatting of its own:
|
|
143
|
-
* flag
|
|
144
|
-
* tuple reaches every "is this cell blank"
|
|
142
|
+
* Whether a cell carries formatting of its own: any {@link CellContent} facet, which is the six shared
|
|
143
|
+
* style facets plus the quote-prefix flag and the link to a named style. Driven by
|
|
144
|
+
* {@link CELL_CONTENT_FACETS}, so a facet added to the tuple reaches every "is this cell blank"
|
|
145
|
+
* decision without anyone remembering to widen a literal.
|
|
145
146
|
*
|
|
146
147
|
* Row- and column-inherited formatting is not the cell's own and does not count. Neither does a
|
|
147
148
|
* note: it lives in the comments part, not the cell's `<c>` element, so a writer deciding whether an
|
package/dist/core/cell.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { assertColumnInBounds, assertRowInBounds, encodeAddress } from './address.js';
|
|
2
2
|
import { NAMED_STYLE_ID } from './internal.js';
|
|
3
|
-
import { assignStyleFacets,
|
|
3
|
+
import { assignContentFacets, assignStyleFacets, CELL_CONTENT_FACETS, } from './style.js';
|
|
4
4
|
import { cellValueToText, coerceCellValue, detectValueType, } from './value.js';
|
|
5
5
|
export class Cell {
|
|
6
6
|
row;
|
|
@@ -107,9 +107,7 @@ export class Cell {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
export function cellHasOwnStyle(cell) {
|
|
110
|
-
return
|
|
111
|
-
cell.quotePrefix === true ||
|
|
112
|
-
cell[NAMED_STYLE_ID] !== undefined);
|
|
110
|
+
return CELL_CONTENT_FACETS.some((facet) => cell[facet] !== undefined);
|
|
113
111
|
}
|
|
114
112
|
export function cellCarriesContent(cell) {
|
|
115
113
|
return cell.value !== null || cell.note !== undefined || cellHasOwnStyle(cell);
|
|
@@ -119,7 +117,7 @@ export function applyCellStyle(cell, style) {
|
|
|
119
117
|
}
|
|
120
118
|
export function copyCellContent(source, target) {
|
|
121
119
|
target.value = source.value;
|
|
122
|
-
|
|
120
|
+
assignContentFacets(target, source);
|
|
123
121
|
target.note = source.note;
|
|
124
122
|
}
|
|
125
123
|
export function cellToModel(cell) {
|
|
@@ -129,6 +127,6 @@ export function cellToModel(cell) {
|
|
|
129
127
|
value: cell.value,
|
|
130
128
|
note: cell.note,
|
|
131
129
|
};
|
|
132
|
-
|
|
130
|
+
assignContentFacets(model, cell);
|
|
133
131
|
return model;
|
|
134
132
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far a copy of one field goes.
|
|
3
|
+
*
|
|
4
|
+
* - `'value'`: assign it. Correct for a scalar, and for anything genuinely immutable.
|
|
5
|
+
* - `'record'`: `{...v}`. A flat object whose own fields are scalars.
|
|
6
|
+
* - `'values'`: `[...v]`. An array of scalars.
|
|
7
|
+
* - `'records'`: `v.map(x => ({...x}))`. An array of flat objects.
|
|
8
|
+
* - a function: the field's own clone, for a nested type that has a plan of its own.
|
|
9
|
+
*/
|
|
10
|
+
export type CloneStrategy<V> = 'value' | 'record' | 'values' | 'records' | ((value: V) => V);
|
|
11
|
+
/**
|
|
12
|
+
* One strategy per field of `T`. The `Record` is what makes a missing field a compile error.
|
|
13
|
+
*
|
|
14
|
+
* A field's strategy sees the field's type without `undefined`, because {@link cloneWith} skips an
|
|
15
|
+
* absent field rather than handing it over. Under `exactOptionalPropertyTypes` a facet declared
|
|
16
|
+
* `font?: Font | undefined` keeps that `undefined` through `Required`, so without the exclusion a
|
|
17
|
+
* nested type's own clone function would not satisfy its own field's strategy.
|
|
18
|
+
*/
|
|
19
|
+
export type ClonePlan<T> = {
|
|
20
|
+
readonly [K in keyof Required<T>]-?: CloneStrategy<Exclude<Required<T>[K], undefined>>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Copy `source` according to `plan`, leaving a field absent when the source leaves it absent.
|
|
24
|
+
*
|
|
25
|
+
* Absent rather than `undefined`: every one of these types declares its optional fields under
|
|
26
|
+
* `exactOptionalPropertyTypes`, where a present-but-undefined key is a different shape from a missing
|
|
27
|
+
* one, and a round-trip that fabricated the first would report formatting a cell does not have.
|
|
28
|
+
*/
|
|
29
|
+
export declare function cloneWith<T extends object>(source: T, plan: ClonePlan<T>): T;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function cloneWith(source, plan) {
|
|
2
|
+
const out = {};
|
|
3
|
+
for (const key of Object.keys(plan)) {
|
|
4
|
+
const value = source[key];
|
|
5
|
+
if (value === undefined)
|
|
6
|
+
continue;
|
|
7
|
+
out[key] = applyStrategy(value, plan[key]);
|
|
8
|
+
}
|
|
9
|
+
return out;
|
|
10
|
+
}
|
|
11
|
+
function applyStrategy(value, strategy) {
|
|
12
|
+
if (typeof strategy === 'function')
|
|
13
|
+
return strategy(value);
|
|
14
|
+
switch (strategy) {
|
|
15
|
+
case 'value':
|
|
16
|
+
return value;
|
|
17
|
+
case 'record':
|
|
18
|
+
return { ...value };
|
|
19
|
+
case 'values':
|
|
20
|
+
return [...value];
|
|
21
|
+
case 'records':
|
|
22
|
+
return value.map((entry) => ({ ...entry }));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { hex } from '../hex.js';
|
|
1
2
|
import { parseArgb } from './style.js';
|
|
2
|
-
import { DEFAULT_THEME_COLOR_SCHEME, THEME_COLOR_SLOTS } from './theme.js';
|
|
3
|
+
import { DEFAULT_THEME_COLOR_SCHEME, isThemeRgb, THEME_COLOR_SLOTS, } from './theme.js';
|
|
3
4
|
export const DEFAULT_INDEXED_COLORS = [
|
|
4
5
|
'00000000', '00FFFFFF', '00FF0000', '0000FF00', '000000FF', '00FFFF00', '00FF00FF', '0000FFFF',
|
|
5
6
|
'00000000', '00FFFFFF', '00FF0000', '0000FF00', '000000FF', '00FFFF00', '00FF00FF', '0000FFFF',
|
|
@@ -31,7 +32,7 @@ function resolveBase(color, context) {
|
|
|
31
32
|
if (slot === undefined)
|
|
32
33
|
return undefined;
|
|
33
34
|
const value = (context.theme ?? DEFAULT_THEME_COLOR_SCHEME)[slot];
|
|
34
|
-
return value
|
|
35
|
+
return value !== undefined && isThemeRgb(value) ? `FF${value.toUpperCase()}` : undefined;
|
|
35
36
|
}
|
|
36
37
|
if (color.indexed !== undefined) {
|
|
37
38
|
if (SYSTEM_INDEXED_COLORS.has(color.indexed))
|
|
@@ -102,8 +103,5 @@ function hueToChannel(p, q, offset) {
|
|
|
102
103
|
return p;
|
|
103
104
|
}
|
|
104
105
|
function channelHex(value) {
|
|
105
|
-
return Math.round(clamp01(value) * 255)
|
|
106
|
-
.toString(16)
|
|
107
|
-
.toUpperCase()
|
|
108
|
-
.padStart(2, '0');
|
|
106
|
+
return hex(Math.round(clamp01(value) * 255), 2);
|
|
109
107
|
}
|
package/dist/core/column.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class Column extends AxisHandle<ColumnProperties> {
|
|
|
21
21
|
get properties(): Readonly<ColumnProperties> | undefined;
|
|
22
22
|
protected propertiesOf(): ColumnProperties | undefined;
|
|
23
23
|
protected ensureProperties(): ColumnProperties;
|
|
24
|
+
protected dropProperties(): void;
|
|
24
25
|
/**
|
|
25
26
|
* Stable key naming this column so a keyed-object row (see {@link Worksheet.addRow}) can place a
|
|
26
27
|
* value under it by name rather than position. In-memory only: never serialized to OOXML.
|
package/dist/core/column.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertColumnInBounds,
|
|
1
|
+
import { assertColumnInBounds, assertRowInBounds, numberToColumn } from './address.js';
|
|
2
2
|
import { AxisHandle } from './axis-handle.js';
|
|
3
3
|
import { INTERNAL } from './internal.js';
|
|
4
4
|
export class Column extends AxisHandle {
|
|
@@ -22,6 +22,9 @@ export class Column extends AxisHandle {
|
|
|
22
22
|
ensureProperties() {
|
|
23
23
|
return this.#sheet[INTERNAL].ensureColumnProperties(this.index);
|
|
24
24
|
}
|
|
25
|
+
dropProperties() {
|
|
26
|
+
this.#sheet[INTERNAL].dropColumnProperties(this.index);
|
|
27
|
+
}
|
|
25
28
|
get key() {
|
|
26
29
|
return this.read('key');
|
|
27
30
|
}
|
|
@@ -89,7 +92,8 @@ export class Column extends AxisHandle {
|
|
|
89
92
|
this.write('protection', protection);
|
|
90
93
|
}
|
|
91
94
|
getCell(row) {
|
|
92
|
-
|
|
95
|
+
assertRowInBounds(row);
|
|
96
|
+
return this.#sheet[INTERNAL].masterAt(row, this.index);
|
|
93
97
|
}
|
|
94
98
|
get cells() {
|
|
95
99
|
return this.#sheet[INTERNAL].columnCells(this.index);
|
|
@@ -55,11 +55,15 @@ export interface Comment {
|
|
|
55
55
|
/** Brace-wrapped GUID identifying this message, preserved verbatim from the file. */
|
|
56
56
|
readonly id: string;
|
|
57
57
|
/**
|
|
58
|
-
* Who wrote it, resolved through the workbook registry. Absent when the file recorded no author or
|
|
59
|
-
* named an id the registry does not hold
|
|
58
|
+
* Who wrote it, resolved through the workbook registry. Absent when the file recorded no author, or
|
|
59
|
+
* named an id the registry does not hold, which Excel treats the same way.
|
|
60
60
|
*/
|
|
61
61
|
readonly author?: Person;
|
|
62
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* The author's {@link Person.id}, which must be registered ({@link Workbook.addPerson}) by the time
|
|
64
|
+
* the workbook is written. Absent for a message with no recorded author, which is written under the
|
|
65
|
+
* null GUID Excel uses for one and shown by Excel as "Author".
|
|
66
|
+
*/
|
|
63
67
|
readonly personId?: string;
|
|
64
68
|
/**
|
|
65
69
|
* When it was written, verbatim. Excel writes local wall-clock with fractional seconds and no
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { quoted } from '../errors.js';
|
|
1
2
|
const GUID = /^\{?([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12})\}?$/i;
|
|
2
3
|
export function commentThreadGuid(value, what) {
|
|
3
4
|
const match = GUID.exec(value.trim());
|
|
4
5
|
if (match === null) {
|
|
5
6
|
throw new SyntaxError(`${what} must be a GUID: Excel writes threaded-comment ids as ` +
|
|
6
|
-
`"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", but got
|
|
7
|
+
`"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", but got ${quoted(value)}`);
|
|
7
8
|
}
|
|
8
9
|
return `{${match.slice(1).join('-').toUpperCase()}}`;
|
|
9
10
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ConditionalFormatting } from './conditional-formatting.ts';
|
|
2
|
+
import type { AxisSplice } from './grid-shift.ts';
|
|
2
3
|
export declare class ConditionalFormattingOverlay {
|
|
3
4
|
#private;
|
|
4
5
|
/**
|
|
@@ -6,6 +7,10 @@ export declare class ConditionalFormattingOverlay {
|
|
|
6
7
|
* range (`"A1:A10"`), a whole column, or several space-separated areas (`"A1:C1 A3:C3"`) sharing one
|
|
7
8
|
* rule set. The block is stored once against the range, defensively copied so the getter never hands
|
|
8
9
|
* back a reference into the caller's object.
|
|
10
|
+
*
|
|
11
|
+
* @throws {AuthoringError} when `formatting.ref` names no area at all. A rule set attached to
|
|
12
|
+
* nothing formats no cell and is written back as the same unreadable text, so it is a mistake worth
|
|
13
|
+
* surfacing at the call. The reader does not reach this: it drops such a block at its own boundary.
|
|
9
14
|
*/
|
|
10
15
|
add(formatting: ConditionalFormatting): void;
|
|
11
16
|
/** The conditional formattings on this sheet, each bound to its target range, in insertion order. */
|
|
@@ -14,7 +19,12 @@ export declare class ConditionalFormattingOverlay {
|
|
|
14
19
|
* Re-anchor every rule set through a row or column splice, so a highlight keeps covering the cells
|
|
15
20
|
* it was written for. A rule set whose every target area fell inside a deleted span goes with them.
|
|
16
21
|
*/
|
|
17
|
-
shift(
|
|
22
|
+
shift(splice: AxisSplice): void;
|
|
23
|
+
/**
|
|
24
|
+
* Rewrite every rule's formulae, and the value of each scale anchor whose type is `formula`, through
|
|
25
|
+
* `rewrite`, keeping a rule set nothing in which changed as the same object.
|
|
26
|
+
*/
|
|
27
|
+
mapFormulas(rewrite: (formula: string) => string): void;
|
|
18
28
|
/** Drop every conditional formatting, leaving the overlay empty. */
|
|
19
29
|
clear(): void;
|
|
20
30
|
}
|
|
@@ -1,23 +1,50 @@
|
|
|
1
|
+
import { AuthoringError, quoted } from '../errors.js';
|
|
1
2
|
import { cloneConditionalFormatting } from './conditional-formatting.js';
|
|
2
3
|
import { replaceContents } from './containers.js';
|
|
3
|
-
import { shiftSqref } from './merge.js';
|
|
4
|
+
import { decodeSqrefRects, shiftSqref } from './merge.js';
|
|
4
5
|
export class ConditionalFormattingOverlay {
|
|
5
6
|
#entries = [];
|
|
6
7
|
add(formatting) {
|
|
8
|
+
if (decodeSqrefRects(formatting.ref).length === 0) {
|
|
9
|
+
throw new AuthoringError(`conditional formatting range ${quoted(formatting.ref)} names no cells`);
|
|
10
|
+
}
|
|
7
11
|
this.#entries.push(cloneConditionalFormatting(formatting));
|
|
8
12
|
}
|
|
9
13
|
get entries() {
|
|
10
14
|
return this.#entries;
|
|
11
15
|
}
|
|
12
|
-
shift(
|
|
16
|
+
shift(splice) {
|
|
13
17
|
const entries = [];
|
|
14
18
|
for (const entry of this.#entries) {
|
|
15
|
-
const ref = shiftSqref(entry.ref,
|
|
19
|
+
const ref = shiftSqref(entry.ref, splice);
|
|
16
20
|
if (ref !== undefined)
|
|
17
21
|
entries.push({ ...entry, ref });
|
|
18
22
|
}
|
|
19
23
|
replaceContents(this.#entries, entries);
|
|
20
24
|
}
|
|
25
|
+
mapFormulas(rewrite) {
|
|
26
|
+
for (const [index, entry] of this.#entries.entries()) {
|
|
27
|
+
let changed = false;
|
|
28
|
+
const rules = entry.rules.map((rule) => {
|
|
29
|
+
const formulae = rule.formulae?.map((operand) => typeof operand === 'string' ? rewrite(operand) : operand);
|
|
30
|
+
const cfvo = rule.cfvo?.map((anchor) => anchor.type === 'formula' && typeof anchor.value === 'string'
|
|
31
|
+
? { ...anchor, value: rewrite(anchor.value) }
|
|
32
|
+
: anchor);
|
|
33
|
+
const formulaeMoved = formulae?.some((operand, i) => operand !== rule.formulae?.[i]) ?? false;
|
|
34
|
+
const cfvoMoved = cfvo?.some((anchor, i) => anchor.value !== rule.cfvo?.[i]?.value) ?? false;
|
|
35
|
+
if (!formulaeMoved && !cfvoMoved)
|
|
36
|
+
return rule;
|
|
37
|
+
changed = true;
|
|
38
|
+
return {
|
|
39
|
+
...rule,
|
|
40
|
+
...(formulae === undefined ? {} : { formulae }),
|
|
41
|
+
...(cfvo === undefined ? {} : { cfvo }),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
if (changed)
|
|
45
|
+
this.#entries[index] = { ...entry, rules };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
21
48
|
clear() {
|
|
22
49
|
this.#entries.length = 0;
|
|
23
50
|
}
|
|
@@ -1,16 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { type ClonePlan } from './clone.ts';
|
|
2
|
+
import type { AssertNever } from './internal.ts';
|
|
3
|
+
import { type Color } from './style.ts';
|
|
4
|
+
import type { DifferentialStyle } from './workbook-styles.ts';
|
|
5
|
+
/**
|
|
6
|
+
* How a {@link CfValueObject} reads its `value`: `ST_CfvoType` verbatim, with the `autoMin` and
|
|
7
|
+
* `autoMax` the 2009 extension adds.
|
|
8
|
+
*/
|
|
9
|
+
export type CfValueObjectType = 'num' | 'percent' | 'max' | 'min' | 'percentile' | 'formula' | 'autoMin' | 'autoMax';
|
|
4
10
|
/** Narrow a raw `<cfvo type>` token to a known {@link CfValueObjectType}. */
|
|
5
11
|
export declare const isCfValueObjectType: (value: string) => value is CfValueObjectType;
|
|
6
12
|
/**
|
|
7
13
|
* One anchor of a colour-scale, data-bar, or icon-set scale: a "conditional format value object".
|
|
8
14
|
* `type` names how `value` is read: a literal `num`, a `percent`/`percentile` of the range, a
|
|
9
15
|
* `formula`, or the range's own `min`/`max` (which carry no value).
|
|
16
|
+
*
|
|
17
|
+
* `autoMin` and `autoMax` are the automatic anchors Excel 2010 gives a new data bar, and carry no value
|
|
18
|
+
* either. Only the extension form spells them, so a data bar using one is written with its extension,
|
|
19
|
+
* its classic element saying `min` or `max` in their place as Excel's does.
|
|
10
20
|
*/
|
|
11
21
|
export interface CfValueObject {
|
|
12
22
|
type: CfValueObjectType;
|
|
13
23
|
value?: number | string;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a value equal to this threshold reaches it. `false` makes an icon set's threshold a strict
|
|
26
|
+
* `>` rather than the `>=` the schema defaults to.
|
|
27
|
+
*/
|
|
28
|
+
gte?: boolean;
|
|
14
29
|
}
|
|
15
30
|
/**
|
|
16
31
|
* What a rule tests, as `<cfRule type>` carries it: `ST_CfType` verbatim.
|
|
@@ -37,21 +52,49 @@ export declare const isConditionalFormattingOperator: (value: string) => value i
|
|
|
37
52
|
export type CfTimePeriod = 'today' | 'yesterday' | 'tomorrow' | 'last7Days' | 'thisMonth' | 'lastMonth' | 'nextMonth' | 'thisWeek' | 'lastWeek' | 'nextWeek';
|
|
38
53
|
/** Narrow a raw `<cfRule timePeriod>` token to a known {@link CfTimePeriod}. */
|
|
39
54
|
export declare const isCfTimePeriod: (value: string) => value is CfTimePeriod;
|
|
55
|
+
/**
|
|
56
|
+
* Which way a data bar grows, as `ST_DataBarDirection` enumerates it: `context` follows the sheet's
|
|
57
|
+
* reading direction.
|
|
58
|
+
*/
|
|
59
|
+
export type DataBarDirection = 'context' | 'leftToRight' | 'rightToLeft';
|
|
60
|
+
/** Narrow a raw `<x14:dataBar direction>` token to a known {@link DataBarDirection}. */
|
|
61
|
+
export declare const isDataBarDirection: (value: string) => value is DataBarDirection;
|
|
62
|
+
/**
|
|
63
|
+
* Where a data bar draws the axis between its negative and positive bars, as `ST_DataBarAxisPosition`
|
|
64
|
+
* enumerates it: where the values put it, at the middle of the cell, or nowhere, which grows a
|
|
65
|
+
* negative bar the way a positive one grows.
|
|
66
|
+
*/
|
|
67
|
+
export type DataBarAxisPosition = 'automatic' | 'middle' | 'none';
|
|
68
|
+
/** Narrow a raw `<x14:dataBar axisPosition>` token to a known {@link DataBarAxisPosition}. */
|
|
69
|
+
export declare const isDataBarAxisPosition: (value: string) => value is DataBarAxisPosition;
|
|
40
70
|
/**
|
|
41
71
|
* The named icon family an `iconSet` rule draws from, as `ST_IconSetType` enumerates it. The leading
|
|
42
72
|
* digit is the number of icons, which is also how many {@link CfValueObject} anchors the rule needs.
|
|
43
73
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* carry them; a file using one states it in the extension, which the library round-trips verbatim.
|
|
74
|
+
* `3Stars`, `3Triangles` and `5Boxes` are the families the 2009 extension added. The classic
|
|
75
|
+
* `<iconSet>` element cannot name them, so a rule drawing from one is written in the extension form.
|
|
47
76
|
*/
|
|
48
|
-
export type IconSetType = '3Arrows' | '3ArrowsGray' | '3Flags' | '3TrafficLights1' | '3TrafficLights2' | '3Signs' | '3Symbols' | '3Symbols2' | '4Arrows' | '4ArrowsGray' | '4RedToBlack' | '4Rating' | '4TrafficLights' | '5Arrows' | '5ArrowsGray' | '5Rating' | '5Quarters';
|
|
77
|
+
export type IconSetType = '3Arrows' | '3ArrowsGray' | '3Flags' | '3TrafficLights1' | '3TrafficLights2' | '3Signs' | '3Symbols' | '3Symbols2' | '4Arrows' | '4ArrowsGray' | '4RedToBlack' | '4Rating' | '4TrafficLights' | '5Arrows' | '5ArrowsGray' | '5Rating' | '5Quarters' | '3Stars' | '3Triangles' | '5Boxes';
|
|
49
78
|
/** Narrow a raw `<iconSet iconSet>` token to a known {@link IconSetType}. */
|
|
50
79
|
export declare const isIconSetType: (value: string) => value is IconSetType;
|
|
80
|
+
/** The families only the 2009 extension can name: a rule drawing from one is written there. */
|
|
81
|
+
export declare function isExtensionIconSet(iconSet: IconSetType): boolean;
|
|
82
|
+
/** The family a custom icon comes from: any {@link IconSetType}, or `NoIcons` for a threshold showing none. */
|
|
83
|
+
export type CfIconSetType = IconSetType | 'NoIcons';
|
|
84
|
+
/** Narrow a raw `<x14:cfIcon iconSet>` token to a known {@link CfIconSetType}. */
|
|
85
|
+
export declare function isCfIconSetType(value: string): value is CfIconSetType;
|
|
86
|
+
/** One threshold's icon in a custom icon set: icon number `iconId`, from 0, of the family `iconSet`. */
|
|
87
|
+
export interface CfIcon {
|
|
88
|
+
iconSet: CfIconSetType;
|
|
89
|
+
iconId: number;
|
|
90
|
+
}
|
|
51
91
|
/**
|
|
52
92
|
* A single conditional-formatting rule. `type` is the OOXML cfRule type; the remaining fields carry
|
|
53
93
|
* the operands that type needs and are absent otherwise. A rule the library does not model in depth
|
|
54
94
|
* still preserves `type`, `priority`, `operator`, `formulae`, and `dxfId` across a round-trip.
|
|
95
|
+
*
|
|
96
|
+
* A data bar's facets marked as x14 properties have no place in the classic `<dataBar>` element, so a
|
|
97
|
+
* bar carrying any of them, or an automatic anchor, is written with a linked `<x14:dataBar>` as well.
|
|
55
98
|
*/
|
|
56
99
|
export interface ConditionalFormattingRule {
|
|
57
100
|
type: ConditionalFormattingType;
|
|
@@ -75,14 +118,48 @@ export interface ConditionalFormattingRule {
|
|
|
75
118
|
color?: Color;
|
|
76
119
|
/** A colorScale's colours, one per {@link cfvo}. */
|
|
77
120
|
colors?: Color[];
|
|
78
|
-
/** A dataBar's
|
|
121
|
+
/** A dataBar's shortest bar, as a percentage of the cell. */
|
|
122
|
+
minLength?: number;
|
|
123
|
+
/** A dataBar's longest bar, as a percentage of the cell. */
|
|
124
|
+
maxLength?: number;
|
|
125
|
+
/** A dataBar's gradient-fill flag. An x14 property. */
|
|
79
126
|
gradient?: boolean;
|
|
80
|
-
/**
|
|
127
|
+
/** Whether a dataBar has a border, in {@link borderColor}. An x14 property. */
|
|
128
|
+
border?: boolean;
|
|
129
|
+
/** A dataBar's border colour. An x14 property. */
|
|
130
|
+
borderColor?: Color;
|
|
131
|
+
/** Which way a dataBar grows. An x14 property. */
|
|
132
|
+
direction?: DataBarDirection;
|
|
133
|
+
/** A dataBar's fill colour for negative values. An x14 property. */
|
|
81
134
|
negativeFillColor?: Color;
|
|
135
|
+
/** A dataBar's border colour for negative values. An x14 property. */
|
|
136
|
+
negativeBorderColor?: Color;
|
|
137
|
+
/**
|
|
138
|
+
* Whether a dataBar fills a negative bar in its positive colour rather than
|
|
139
|
+
* {@link negativeFillColor}. An x14 property.
|
|
140
|
+
*/
|
|
141
|
+
negativeBarColorSameAsPositive?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Whether a dataBar borders a negative bar in its positive border colour rather than
|
|
144
|
+
* {@link negativeBorderColor}. An x14 property.
|
|
145
|
+
*/
|
|
146
|
+
negativeBarBorderColorSameAsPositive?: boolean;
|
|
147
|
+
/** Where a dataBar draws the axis between negative and positive bars. An x14 property. */
|
|
148
|
+
axisPosition?: DataBarAxisPosition;
|
|
82
149
|
/** A dataBar's axis colour (the zero line between positive and negative bars). An x14 property. */
|
|
83
150
|
axisColor?: Color;
|
|
84
151
|
/** An iconSet's named icon family (e.g. `3TrafficLights1`). */
|
|
85
152
|
iconSet?: IconSetType;
|
|
153
|
+
/**
|
|
154
|
+
* A custom iconSet's icons, one per {@link cfvo} threshold in order, each replacing the icon
|
|
155
|
+
* {@link iconSet} would show there. Only the extension form carries them, so a rule with icons is
|
|
156
|
+
* written in it.
|
|
157
|
+
*/
|
|
158
|
+
icons?: CfIcon[];
|
|
159
|
+
/** iconSet: the icons in reverse order, the highest threshold showing the family's first icon. */
|
|
160
|
+
reverse?: boolean;
|
|
161
|
+
/** dataBar / iconSet: whether the cell still shows its value beside the bar or icon. */
|
|
162
|
+
showValue?: boolean;
|
|
86
163
|
/** top10 rank cutoff. */
|
|
87
164
|
rank?: number;
|
|
88
165
|
/** top10: the rank is a percentage rather than a count. */
|
|
@@ -98,13 +175,32 @@ export interface ConditionalFormattingRule {
|
|
|
98
175
|
/** timePeriod window (`today`, `lastWeek`, …). */
|
|
99
176
|
timePeriod?: CfTimePeriod;
|
|
100
177
|
}
|
|
101
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* A set of rules bound to the range(s) they cover. `ref` is an OOXML `sqref`: one or more
|
|
102
180
|
* space-separated areas (`"A1:C1 A3:C3 A5:C5"`), the shape Excel writes when one rule is applied to
|
|
103
|
-
* several non-contiguous selections at once.
|
|
181
|
+
* several non-contiguous selections at once.
|
|
182
|
+
*
|
|
183
|
+
* `extended` marks a set stored in the 2009 extension form (`<x14:conditionalFormatting>` inside the
|
|
184
|
+
* worksheet `<extLst>`), where Excel puts a rule whose formula reaches another sheet. The reader sets
|
|
185
|
+
* it for a set found in that form so a round-trip writes the set back there. A rule only that form can
|
|
186
|
+
* express, one drawing from a 2009 icon family or carrying custom icons, is written there whatever the
|
|
187
|
+
* flag says.
|
|
188
|
+
*/
|
|
104
189
|
export interface ConditionalFormatting {
|
|
105
190
|
ref: string;
|
|
106
191
|
rules: ConditionalFormattingRule[];
|
|
192
|
+
extended?: boolean;
|
|
107
193
|
}
|
|
108
194
|
/** A defensive deep copy, so a stored conditional formatting never aliases the caller's object nor
|
|
109
195
|
* any of its nested arrays (rules, formulae, cfvo, colours) or the differential style. */
|
|
110
196
|
export declare function cloneConditionalFormatting(cf: ConditionalFormatting): ConditionalFormatting;
|
|
197
|
+
/**
|
|
198
|
+
* Whether a rule needs the extension form: it names a family or custom icons the classic element has
|
|
199
|
+
* no way to spell.
|
|
200
|
+
*/
|
|
201
|
+
export declare function ruleNeedsExtension(rule: ConditionalFormattingRule): boolean;
|
|
202
|
+
declare const RULE_CLONE: ClonePlan<ConditionalFormattingRule>;
|
|
203
|
+
export type EveryRuleFieldIsCloned = AssertNever<Exclude<keyof Required<ConditionalFormattingRule>, keyof typeof RULE_CLONE>>;
|
|
204
|
+
declare const STYLE_CLONE: ClonePlan<DifferentialStyle>;
|
|
205
|
+
export type EveryDifferentialStyleFieldIsCloned = AssertNever<Exclude<keyof Required<DifferentialStyle>, keyof typeof STYLE_CLONE>>;
|
|
206
|
+
export {};
|