@rowsncolumns/toolkit 24.4.4 → 24.5.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/dist/cjs/autofilter-condition.d.ts +45 -1
- package/dist/cjs/autofilter-condition.d.ts.map +1 -1
- package/dist/cjs/autofilter-condition.js +135 -12
- package/dist/cjs/excel-parser/helpers.d.ts +15 -1
- package/dist/cjs/excel-parser/helpers.d.ts.map +1 -1
- package/dist/cjs/excel-parser/helpers.js +119 -5
- package/dist/cjs/excel-parser/interface.d.ts +3 -1
- package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/ods/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/ods/index.js +186 -97
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts +15 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/ods/styles.js +80 -6
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsb/index.js +107 -103
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts +77 -1
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/charts.js +920 -122
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts +7 -1
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.js +24 -9
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts +24 -3
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.js +25 -3
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +24 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +561 -394
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts +8 -2
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.js +312 -21
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts +6 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.js +9 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts +1 -1
- package/dist/cjs/excel-parser/types.d.ts +9 -1
- package/dist/cjs/excel-parser/types.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.d.ts +1 -0
- package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.js +5 -0
- package/dist/cjs/excel-parser/worker.js +2 -0
- package/dist/cjs/exporter/ods/ods-export.d.ts.map +1 -1
- package/dist/cjs/exporter/ods/ods-export.js +255 -80
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts +7 -1
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/chart-builder.js +902 -119
- package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts +16 -3
- package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/form-controls-builder.js +30 -8
- package/dist/cjs/exporter/xlsx/pivot-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/pivot-builder.js +206 -162
- package/dist/cjs/exporter/xlsx/style-builder.d.ts +8 -2
- package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/style-builder.js +25 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +2 -2
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/xlsx-export.js +728 -452
- package/dist/esm/autofilter-condition.d.ts +45 -1
- package/dist/esm/autofilter-condition.d.ts.map +1 -1
- package/dist/esm/autofilter-condition.js +131 -11
- package/dist/esm/excel-parser/helpers.d.ts +15 -1
- package/dist/esm/excel-parser/helpers.d.ts.map +1 -1
- package/dist/esm/excel-parser/helpers.js +94 -4
- package/dist/esm/excel-parser/interface.d.ts +3 -1
- package/dist/esm/excel-parser/interface.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/ods/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/ods/index.js +105 -22
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts +15 -0
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/ods/styles.js +79 -5
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsb/index.js +15 -7
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts +77 -1
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/charts.js +708 -16
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts +7 -1
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/drawing.js +23 -0
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts +24 -3
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.js +21 -3
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +24 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.js +192 -54
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts +8 -2
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/pivots.js +220 -4
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts +6 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/relationships.js +9 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts +1 -1
- package/dist/esm/excel-parser/types.d.ts +9 -1
- package/dist/esm/excel-parser/types.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.d.ts +1 -0
- package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.js +4 -0
- package/dist/esm/excel-parser/worker.js +2 -0
- package/dist/esm/exporter/ods/ods-export.d.ts.map +1 -1
- package/dist/esm/exporter/ods/ods-export.js +238 -72
- package/dist/esm/exporter/xlsx/chart-builder.d.ts +7 -1
- package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/chart-builder.js +674 -58
- package/dist/esm/exporter/xlsx/form-controls-builder.d.ts +16 -3
- package/dist/esm/exporter/xlsx/form-controls-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/form-controls-builder.js +29 -8
- package/dist/esm/exporter/xlsx/pivot-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/pivot-builder.js +187 -139
- package/dist/esm/exporter/xlsx/style-builder.d.ts +8 -2
- package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/style-builder.js +28 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts +2 -2
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/xlsx-export.js +451 -197
- package/package.json +11 -4
|
@@ -31,6 +31,15 @@ const ODS_ORDERED_XML_OPTIONS = {
|
|
|
31
31
|
preserveOrder: true,
|
|
32
32
|
};
|
|
33
33
|
const DISPLAY_CURRENCY_REGEX = /[$€¥£₹]/;
|
|
34
|
+
/** The symbol behind an ODS `office:currency` value — an ISO code for the currencies the display-text detection knows, a literal symbol as is. */
|
|
35
|
+
const ODS_CURRENCY_CODE_SYMBOLS = {
|
|
36
|
+
USD: "$",
|
|
37
|
+
EUR: "€",
|
|
38
|
+
GBP: "£",
|
|
39
|
+
JPY: "¥",
|
|
40
|
+
INR: "₹",
|
|
41
|
+
};
|
|
42
|
+
const odsCurrencySymbol = (currency) => ODS_CURRENCY_CODE_SYMBOLS[currency.toUpperCase()] ?? currency;
|
|
34
43
|
function findChild(children, tagName) {
|
|
35
44
|
return children?.find((child) => child[tagName]);
|
|
36
45
|
}
|
|
@@ -223,6 +232,10 @@ const ODS_OPERATOR_TO_CONDITION = {
|
|
|
223
232
|
endswith: "TEXT_ENDS_WITH",
|
|
224
233
|
empty: "BLANK",
|
|
225
234
|
"non-empty": "NOT_BLANK",
|
|
235
|
+
"top values": "NUMBER_TOP_N",
|
|
236
|
+
"bottom values": "NUMBER_BOTTOM_N",
|
|
237
|
+
"top percent": "NUMBER_TOP_PERCENT",
|
|
238
|
+
"bottom percent": "NUMBER_BOTTOM_PERCENT",
|
|
226
239
|
};
|
|
227
240
|
export class OdsPlugin extends BaseWorkbookPlugin {
|
|
228
241
|
zipParser;
|
|
@@ -865,25 +878,29 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
865
878
|
}
|
|
866
879
|
convertFilterNodeToSpecs(filterNode) {
|
|
867
880
|
const specMap = new Map();
|
|
868
|
-
|
|
881
|
+
// <table:filter-and> / <table:filter-or> nest (the exporter puts a
|
|
882
|
+
// column's Or-joined clause pair inside the outer And): walk them
|
|
883
|
+
// recursively, tagging each condition with the join of its container so
|
|
884
|
+
// a column's second condition becomes Excel's Custom AutoFilter clause.
|
|
885
|
+
const walk = (container, join) => {
|
|
869
886
|
const conditions = this.toArray(get(container, "table:filter-condition") ||
|
|
870
887
|
get(container, "filter-condition"));
|
|
871
888
|
for (const condition of conditions) {
|
|
872
|
-
this.applyFilterCondition(condition, specMap);
|
|
889
|
+
this.applyFilterCondition(condition, specMap, join);
|
|
890
|
+
}
|
|
891
|
+
const andNodes = this.toArray(get(container, "table:filter-and") || get(container, "filter-and"));
|
|
892
|
+
for (const node of andNodes) {
|
|
893
|
+
walk(node, "AND");
|
|
894
|
+
}
|
|
895
|
+
const orNodes = this.toArray(get(container, "table:filter-or") || get(container, "filter-or"));
|
|
896
|
+
for (const node of orNodes) {
|
|
897
|
+
walk(node, "OR");
|
|
873
898
|
}
|
|
874
899
|
};
|
|
875
|
-
|
|
876
|
-
const andNodes = this.toArray(get(filterNode, "table:filter-and") || get(filterNode, "filter-and"));
|
|
877
|
-
for (const node of andNodes) {
|
|
878
|
-
addConditions(node);
|
|
879
|
-
}
|
|
880
|
-
const orNodes = this.toArray(get(filterNode, "table:filter-or") || get(filterNode, "filter-or"));
|
|
881
|
-
for (const node of orNodes) {
|
|
882
|
-
addConditions(node);
|
|
883
|
-
}
|
|
900
|
+
walk(filterNode, "AND");
|
|
884
901
|
return Array.from(specMap.values()).sort((a, b) => a.columnIndex - b.columnIndex);
|
|
885
902
|
}
|
|
886
|
-
applyFilterCondition(node, specMap) {
|
|
903
|
+
applyFilterCondition(node, specMap, join) {
|
|
887
904
|
const attrs = this.getAttributes(node);
|
|
888
905
|
if (!attrs)
|
|
889
906
|
return;
|
|
@@ -919,10 +936,16 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
919
936
|
if (value2 !== undefined) {
|
|
920
937
|
conditionValues.push({ userEnteredValue: String(value2) });
|
|
921
938
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
939
|
+
const condition = { type: conditionType, values: conditionValues };
|
|
940
|
+
if (spec.filterCriteria.condition?.type) {
|
|
941
|
+
// A second operator condition on the column is the Custom
|
|
942
|
+
// AutoFilter's second clause, joined the way its container joins.
|
|
943
|
+
spec.filterCriteria.condition2 = condition;
|
|
944
|
+
spec.filterCriteria.conditionJoin = join;
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
spec.filterCriteria.condition = condition;
|
|
948
|
+
}
|
|
926
949
|
return;
|
|
927
950
|
}
|
|
928
951
|
// operator "=" (or unknown) -> value-list entry.
|
|
@@ -2017,7 +2040,28 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2017
2040
|
if (!plotArea)
|
|
2018
2041
|
return undefined;
|
|
2019
2042
|
const plotAreaAttrs = this.getAttributes(plotArea);
|
|
2020
|
-
const
|
|
2043
|
+
const plotAreaStyleName = plotAreaAttrs?.["@_chart:style-name"] || plotAreaAttrs?.["@_style-name"];
|
|
2044
|
+
const sourceChartType = this.resolveOdsSourceChartType(chartClass, chartType, plotAreaStyleName, styles);
|
|
2045
|
+
// Excel's "Show empty cells as" — the default (a gap) is left implicit.
|
|
2046
|
+
const emptyCells = styles.getChartStyleEmptyCells(plotAreaStyleName);
|
|
2047
|
+
// Axis tick-label formats — an axis style's data style with the source
|
|
2048
|
+
// link severed is Excel's `<c:numFmt sourceLinked="0">`; a linked axis
|
|
2049
|
+
// carries no options (the default).
|
|
2050
|
+
let valueAxisOptions;
|
|
2051
|
+
let categoryAxisOptions;
|
|
2052
|
+
for (const axisNode of this.toArray(get(plotArea, "chart:axis") || get(plotArea, "axis"))) {
|
|
2053
|
+
const axisAttrs = this.getAttributes(axisNode);
|
|
2054
|
+
const pattern = styles.getChartStyleNumberFormatPattern(axisAttrs?.["@_chart:style-name"] || axisAttrs?.["@_style-name"]);
|
|
2055
|
+
if (!pattern)
|
|
2056
|
+
continue;
|
|
2057
|
+
const dimension = axisAttrs?.["@_chart:dimension"] || axisAttrs?.["@_dimension"];
|
|
2058
|
+
if (dimension === "y" && !valueAxisOptions) {
|
|
2059
|
+
valueAxisOptions = { numberFormatPattern: pattern };
|
|
2060
|
+
}
|
|
2061
|
+
else if (dimension === "x" && !categoryAxisOptions) {
|
|
2062
|
+
categoryAxisOptions = { numberFormatPattern: pattern };
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2021
2065
|
const seriesNodes = this.toArray(get(plotArea, "chart:series") ||
|
|
2022
2066
|
get(plotArea, "chart:data-series") ||
|
|
2023
2067
|
get(plotArea, "series"));
|
|
@@ -2025,8 +2069,16 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2025
2069
|
return undefined;
|
|
2026
2070
|
const domains = [];
|
|
2027
2071
|
const series = [];
|
|
2072
|
+
// Exploded pie / doughnut: the largest `chart:pie-offset` across the
|
|
2073
|
+
// series styles (OOXML keeps one <c:explosion> per series too).
|
|
2074
|
+
let explosion;
|
|
2028
2075
|
let seriesIndex = 1;
|
|
2029
2076
|
for (const seriesNode of seriesNodes) {
|
|
2077
|
+
const seriesAttrs = this.getAttributes(seriesNode);
|
|
2078
|
+
const pieOffset = styles.getChartStylePieOffset(seriesAttrs?.["@_chart:style-name"] || seriesAttrs?.["@_style-name"]);
|
|
2079
|
+
if (pieOffset !== undefined) {
|
|
2080
|
+
explosion = Math.max(explosion ?? 0, pieOffset);
|
|
2081
|
+
}
|
|
2030
2082
|
const domainNode = get(seriesNode, "chart:domain") ||
|
|
2031
2083
|
get(seriesNode, "domain") ||
|
|
2032
2084
|
get(seriesNode, "chart:categories");
|
|
@@ -2064,6 +2116,13 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2064
2116
|
domains: finalizedDomains,
|
|
2065
2117
|
series,
|
|
2066
2118
|
...(sourceChartType ? { sourceChartType } : {}),
|
|
2119
|
+
...(emptyCells && emptyCells !== "gaps" ? { emptyCells } : {}),
|
|
2120
|
+
...(valueAxisOptions ? { valueAxisOptions } : {}),
|
|
2121
|
+
...(categoryAxisOptions ? { categoryAxisOptions } : {}),
|
|
2122
|
+
...(explosion !== undefined &&
|
|
2123
|
+
(chartType === "pie" || chartType === "doughnut")
|
|
2124
|
+
? { explosion }
|
|
2125
|
+
: {}),
|
|
2067
2126
|
};
|
|
2068
2127
|
}
|
|
2069
2128
|
extractSeriesLabel(seriesNode) {
|
|
@@ -2143,6 +2202,10 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2143
2202
|
if (normalized.includes("line") || normalized.includes("scatter")) {
|
|
2144
2203
|
return "line";
|
|
2145
2204
|
}
|
|
2205
|
+
// `chart:ring` is ODF's doughnut.
|
|
2206
|
+
if (normalized.includes("ring")) {
|
|
2207
|
+
return "doughnut";
|
|
2208
|
+
}
|
|
2146
2209
|
if (normalized.includes("pie") || normalized.includes("circle")) {
|
|
2147
2210
|
return "pie";
|
|
2148
2211
|
}
|
|
@@ -2175,6 +2238,8 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2175
2238
|
return "PIE_3D";
|
|
2176
2239
|
case "area":
|
|
2177
2240
|
return "AREA_3D";
|
|
2241
|
+
default:
|
|
2242
|
+
return undefined;
|
|
2178
2243
|
}
|
|
2179
2244
|
}
|
|
2180
2245
|
findRangeString(node, skipKeys) {
|
|
@@ -2273,6 +2338,24 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2273
2338
|
if (typeof offsetYPixels === "number") {
|
|
2274
2339
|
overlayPosition.offsetYPixels = offsetYPixels;
|
|
2275
2340
|
}
|
|
2341
|
+
// `table:end-cell-address` (+ end-x / end-y) is ODS's "Move and size with
|
|
2342
|
+
// cells" second anchor — kept as `toCell` so the frame follows the cells
|
|
2343
|
+
// between the corners (#668 C-06). A frame without one keeps its pixel size.
|
|
2344
|
+
const endAttr = (name) => frameAttrs?.[`@_table:${name}`] ||
|
|
2345
|
+
frameAttrs?.[`@_${name}`] ||
|
|
2346
|
+
cellAttrs?.[`@_table:${name}`] ||
|
|
2347
|
+
cellAttrs?.[`@_${name}`];
|
|
2348
|
+
const endCellAddress = endAttr("end-cell-address");
|
|
2349
|
+
if (endCellAddress) {
|
|
2350
|
+
const toCell = addressToCell((endCellAddress.split(".").pop() ?? endCellAddress).toUpperCase());
|
|
2351
|
+
if (toCell) {
|
|
2352
|
+
overlayPosition.toCell = toCell;
|
|
2353
|
+
overlayPosition.toOffsetXPixels =
|
|
2354
|
+
this.convertLengthToPixels(endAttr("end-x")) ?? 0;
|
|
2355
|
+
overlayPosition.toOffsetYPixels =
|
|
2356
|
+
this.convertLengthToPixels(endAttr("end-y")) ?? 0;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2276
2359
|
const DEFAULT_CELL_IMAGE_MAX_SIZE = 60;
|
|
2277
2360
|
const exceedsCellSize = (typeof widthPixels === "number" &&
|
|
2278
2361
|
widthPixels > DEFAULT_CELL_IMAGE_MAX_SIZE) ||
|
|
@@ -2994,19 +3077,19 @@ export class OdsPlugin extends BaseWorkbookPlugin {
|
|
|
2994
3077
|
mergedFormat = mergedFormat
|
|
2995
3078
|
? { ...mergedFormat }
|
|
2996
3079
|
: {};
|
|
2997
|
-
const currencySymbol = cellAttrs["@_office:currency"] ||
|
|
3080
|
+
const currencySymbol = odsCurrencySymbol(cellAttrs["@_office:currency"] ||
|
|
2998
3081
|
cellAttrs["@_currency"] ||
|
|
2999
|
-
"$";
|
|
3082
|
+
"$");
|
|
3000
3083
|
if (!mergedFormat.numberFormat ||
|
|
3001
3084
|
mergedFormat.numberFormat.type === "NUMBER") {
|
|
3085
|
+
// No currency data style: Excel's default Currency format
|
|
3086
|
+
// puts the symbol flush against the number (`$#,##0.00`).
|
|
3002
3087
|
const pattern = mergedFormat.numberFormat?.pattern || "#,##0.00";
|
|
3003
3088
|
mergedFormat.numberFormat = {
|
|
3004
3089
|
type: "CURRENCY",
|
|
3005
3090
|
pattern: pattern.includes(currencySymbol)
|
|
3006
3091
|
? pattern
|
|
3007
|
-
: `${currencySymbol}${pattern
|
|
3008
|
-
? " "
|
|
3009
|
-
: ""}${pattern}`,
|
|
3092
|
+
: `${currencySymbol}${pattern}`,
|
|
3010
3093
|
};
|
|
3011
3094
|
}
|
|
3012
3095
|
}
|
|
@@ -49,6 +49,12 @@ export declare class OdsStyles {
|
|
|
49
49
|
private rightToLeftTableStyles;
|
|
50
50
|
/** Chart styles whose `style:chart-properties` carry `chart:three-dimensional="true"`. */
|
|
51
51
|
private threeDimensionalChartStyles;
|
|
52
|
+
/** Chart styles' `chart:treat-empty-cells`, as the spec's `emptyCells` policy. */
|
|
53
|
+
private chartStyleEmptyCells;
|
|
54
|
+
/** Series chart styles' `chart:pie-offset` (slice explosion, % of the radius). */
|
|
55
|
+
private chartStylePieOffsets;
|
|
56
|
+
/** Chart (axis) styles' `style:data-style-name` when the link to the source is severed. */
|
|
57
|
+
private chartStyleDataStyles;
|
|
52
58
|
constructor();
|
|
53
59
|
reset(): void;
|
|
54
60
|
parseStylesXml(stylesXml: any): void;
|
|
@@ -73,6 +79,15 @@ export declare class OdsStyles {
|
|
|
73
79
|
getChartStyleColor(styleName?: string): Color | undefined;
|
|
74
80
|
/** Whether a chart style (plot-area) declares `chart:three-dimensional="true"`. */
|
|
75
81
|
isChartStyleThreeDimensional(styleName?: string): boolean;
|
|
82
|
+
/** A series style's `chart:pie-offset` (slice explosion, % of the radius). */
|
|
83
|
+
getChartStylePieOffset(styleName?: string): number | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* A chart axis style's explicit tick-label format (its data style, with
|
|
86
|
+
* the source link severed) as a number pattern; undefined when linked.
|
|
87
|
+
*/
|
|
88
|
+
getChartStyleNumberFormatPattern(styleName?: string): string | undefined;
|
|
89
|
+
/** The plot-area style's `chart:treat-empty-cells` as a spec `emptyCells` policy. */
|
|
90
|
+
getChartStyleEmptyCells(styleName?: string): "gaps" | "zero" | "connect" | undefined;
|
|
76
91
|
/** Whether a `style:family="table"` style renders the sheet right-to-left. */
|
|
77
92
|
isTableStyleRightToLeft(styleName?: string): boolean;
|
|
78
93
|
getTableCellFormat(styleName: string): CellFormat | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/ods/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,UAAU,EACV,KAAK,EAGL,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACX,MAAM,2BAA2B,CAAC;AAenC,KAAK,WAAW,GAAG;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/ods/styles.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { get } from "lodash-es";
|
|
2
2
|
import { headerFooterZoneFromTokens, joinHeaderFooterZones, odsLengthToInches, paperSizeFromCm, parseOdsPrintTokens, parseOdsTableCentering, } from "../../../print-settings";
|
|
3
|
+
/** ODF `chart:treat-empty-cells` → `ChartSpec.emptyCells`. */
|
|
4
|
+
const ODS_TREAT_EMPTY_CELLS_TO_POLICY = {
|
|
5
|
+
"leave-gap": "gaps",
|
|
6
|
+
"use-zero": "zero",
|
|
7
|
+
ignore: "connect",
|
|
8
|
+
};
|
|
3
9
|
export class OdsStyles {
|
|
4
10
|
cellStyles = new Map();
|
|
5
11
|
automaticCellStyles = new Map();
|
|
@@ -21,6 +27,12 @@ export class OdsStyles {
|
|
|
21
27
|
rightToLeftTableStyles = new Set();
|
|
22
28
|
/** Chart styles whose `style:chart-properties` carry `chart:three-dimensional="true"`. */
|
|
23
29
|
threeDimensionalChartStyles = new Set();
|
|
30
|
+
/** Chart styles' `chart:treat-empty-cells`, as the spec's `emptyCells` policy. */
|
|
31
|
+
chartStyleEmptyCells = new Map();
|
|
32
|
+
/** Series chart styles' `chart:pie-offset` (slice explosion, % of the radius). */
|
|
33
|
+
chartStylePieOffsets = new Map();
|
|
34
|
+
/** Chart (axis) styles' `style:data-style-name` when the link to the source is severed. */
|
|
35
|
+
chartStyleDataStyles = new Map();
|
|
24
36
|
constructor() { }
|
|
25
37
|
reset() {
|
|
26
38
|
this.cellStyles.clear();
|
|
@@ -40,6 +52,9 @@ export class OdsStyles {
|
|
|
40
52
|
this.masterPages.clear();
|
|
41
53
|
this.rightToLeftTableStyles.clear();
|
|
42
54
|
this.threeDimensionalChartStyles.clear();
|
|
55
|
+
this.chartStyleEmptyCells.clear();
|
|
56
|
+
this.chartStylePieOffsets.clear();
|
|
57
|
+
this.chartStyleDataStyles.clear();
|
|
43
58
|
}
|
|
44
59
|
parseStylesXml(stylesXml) {
|
|
45
60
|
if (!stylesXml)
|
|
@@ -269,6 +284,25 @@ export class OdsStyles {
|
|
|
269
284
|
if (threeDimensional === "true" || threeDimensional === true) {
|
|
270
285
|
this.threeDimensionalChartStyles.add(name);
|
|
271
286
|
}
|
|
287
|
+
const treatEmptyCells = chartProps?.["@_chart:treat-empty-cells"] ??
|
|
288
|
+
chartProps?.["@_treat-empty-cells"];
|
|
289
|
+
const emptyCells = ODS_TREAT_EMPTY_CELLS_TO_POLICY[String(treatEmptyCells)];
|
|
290
|
+
if (name && emptyCells) {
|
|
291
|
+
this.chartStyleEmptyCells.set(name, emptyCells);
|
|
292
|
+
}
|
|
293
|
+
const pieOffset = Number(chartProps?.["@_chart:pie-offset"] ?? chartProps?.["@_pie-offset"]);
|
|
294
|
+
if (name && Number.isFinite(pieOffset) && pieOffset > 0) {
|
|
295
|
+
this.chartStylePieOffsets.set(name, pieOffset);
|
|
296
|
+
}
|
|
297
|
+
// An axis' explicit tick-label format: a data style whose link to
|
|
298
|
+
// the source cells is severed (LibreOffice writes the data style
|
|
299
|
+
// with `chart:link-data-style-to-source="true"` for a linked axis).
|
|
300
|
+
const dataStyleName = style["@_style:data-style-name"] || style["@_data-style-name"];
|
|
301
|
+
const linkToSource = chartProps?.["@_chart:link-data-style-to-source"] ??
|
|
302
|
+
chartProps?.["@_link-data-style-to-source"];
|
|
303
|
+
if (name && dataStyleName && String(linkToSource) !== "true") {
|
|
304
|
+
this.chartStyleDataStyles.set(name, dataStyleName);
|
|
305
|
+
}
|
|
272
306
|
const color = this.convertChartStyle(style);
|
|
273
307
|
if (color) {
|
|
274
308
|
const displayName = style["@_style:display-name"] || style["@_display-name"];
|
|
@@ -343,6 +377,27 @@ export class OdsStyles {
|
|
|
343
377
|
isChartStyleThreeDimensional(styleName) {
|
|
344
378
|
return !!styleName && this.threeDimensionalChartStyles.has(styleName);
|
|
345
379
|
}
|
|
380
|
+
/** A series style's `chart:pie-offset` (slice explosion, % of the radius). */
|
|
381
|
+
getChartStylePieOffset(styleName) {
|
|
382
|
+
return styleName ? this.chartStylePieOffsets.get(styleName) : undefined;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* A chart axis style's explicit tick-label format (its data style, with
|
|
386
|
+
* the source link severed) as a number pattern; undefined when linked.
|
|
387
|
+
*/
|
|
388
|
+
getChartStyleNumberFormatPattern(styleName) {
|
|
389
|
+
const dataStyleName = styleName
|
|
390
|
+
? this.chartStyleDataStyles.get(styleName)
|
|
391
|
+
: undefined;
|
|
392
|
+
const numberFormat = dataStyleName
|
|
393
|
+
? this.numberFormats.get(dataStyleName)
|
|
394
|
+
: undefined;
|
|
395
|
+
return numberFormat?.pattern ?? undefined;
|
|
396
|
+
}
|
|
397
|
+
/** The plot-area style's `chart:treat-empty-cells` as a spec `emptyCells` policy. */
|
|
398
|
+
getChartStyleEmptyCells(styleName) {
|
|
399
|
+
return styleName ? this.chartStyleEmptyCells.get(styleName) : undefined;
|
|
400
|
+
}
|
|
346
401
|
/** Whether a `style:family="table"` style renders the sheet right-to-left. */
|
|
347
402
|
isTableStyleRightToLeft(styleName) {
|
|
348
403
|
return !!styleName && this.rightToLeftTableStyles.has(styleName);
|
|
@@ -664,13 +719,31 @@ export class OdsStyles {
|
|
|
664
719
|
case "currency": {
|
|
665
720
|
const symbolNode = this.first(this.toArray(node["number:currency-symbol"]));
|
|
666
721
|
const symbol = this.extractText(symbolNode) || "¤";
|
|
722
|
+
// The symbol's side is its element order relative to `number:number`
|
|
723
|
+
// (the unordered tree keeps first-occurrence key order); a
|
|
724
|
+
// `number:position="after"` attribute is honoured as a fallback.
|
|
667
725
|
const position = symbolNode?.["@_number:position"] ||
|
|
668
726
|
symbolNode?.["@_style:position"] ||
|
|
669
727
|
symbolNode?.["@_position"];
|
|
670
|
-
const
|
|
728
|
+
const keys = Object.keys(node);
|
|
729
|
+
const symbolAt = keys.indexOf("number:currency-symbol");
|
|
730
|
+
const numberAt = keys.indexOf("number:number");
|
|
731
|
+
const usePrefix = symbolAt >= 0 && numberAt >= 0
|
|
732
|
+
? symbolAt < numberAt
|
|
733
|
+
: position !== "after";
|
|
734
|
+
// A whitespace-only `number:text` is the gap between symbol and digits
|
|
735
|
+
// (the XML parser trims values, so it arrives as an empty node).
|
|
736
|
+
const texts = node["number:text"];
|
|
737
|
+
const space = texts !== undefined &&
|
|
738
|
+
(Array.isArray(texts) ? texts : [texts]).some((text) => {
|
|
739
|
+
const value = this.extractText(text);
|
|
740
|
+
return value === undefined || String(value).trim() === "";
|
|
741
|
+
})
|
|
742
|
+
? " "
|
|
743
|
+
: "";
|
|
671
744
|
const pattern = this.buildNumberPattern(node, {
|
|
672
|
-
prefix: usePrefix ? `${symbol}
|
|
673
|
-
suffix: !usePrefix ?
|
|
745
|
+
prefix: usePrefix ? `${symbol}${space}` : undefined,
|
|
746
|
+
suffix: !usePrefix ? `${space}${symbol}` : undefined,
|
|
674
747
|
defaultFractionDigits: 2,
|
|
675
748
|
});
|
|
676
749
|
return {
|
|
@@ -713,8 +786,9 @@ export class OdsStyles {
|
|
|
713
786
|
if (isNaN(decimals)) {
|
|
714
787
|
decimals = options?.defaultFractionDigits ?? 0;
|
|
715
788
|
}
|
|
716
|
-
|
|
717
|
-
const
|
|
789
|
+
// ODF's `number:grouping` defaults to false: `0.00` has no thousands separator.
|
|
790
|
+
const groupingAttr = numberNode?.["@_number:grouping"] || numberNode?.["@_grouping"] || "false";
|
|
791
|
+
const grouping = groupingAttr === "true";
|
|
718
792
|
const minIntegerDigits = Math.max(parseInt(numberNode?.["@_number:min-integer-digits"] ||
|
|
719
793
|
numberNode?.["@_min-integer-digits"] ||
|
|
720
794
|
"1", 10) || 1, 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsb/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EAEL,2BAA2B,EAE5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,WAAW,EAGX,qBAAqB,EACrB,wBAAwB,EAExB,aAAa,EACb,UAAU,EACV,KAAK,EACL,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsb/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { XMLParser } from "fast-xml-parser";
|
|
|
4
4
|
import { get } from "lodash-es";
|
|
5
5
|
import { parseRgce } from "./rgce-parser";
|
|
6
6
|
import { StreamingZipParser } from "../../zip-parser-streaming";
|
|
7
|
-
import { createFilterSpecsFromAutoFilter, excelColumnWidthToPixels, getRangeFromAddressRef, parseTableColumnTotals, } from "../../helpers";
|
|
7
|
+
import { createFilterSpecsFromAutoFilter, createSortSpecsFromSortState, excelColumnWidthToPixels, getRangeFromAddressRef, hiddenFilterButtonColumns, parseTableColumnTotals, } from "../../helpers";
|
|
8
8
|
import { defaultSpreadsheetTheme } from "../../theme-default";
|
|
9
9
|
import { BaseWorkbookPlugin } from "../base/index";
|
|
10
10
|
import { processChart } from "../xlsx/charts";
|
|
@@ -1557,6 +1557,12 @@ export class XlsbPlugin extends BaseWorkbookPlugin {
|
|
|
1557
1557
|
});
|
|
1558
1558
|
const autoFilter = tableDefinition.autoFilter ?? tableDefinition["x:autoFilter"];
|
|
1559
1559
|
const filterSpecs = createFilterSpecsFromAutoFilter(autoFilter);
|
|
1560
|
+
for (const colId of hiddenFilterButtonColumns(autoFilter)) {
|
|
1561
|
+
if (columns[colId])
|
|
1562
|
+
columns[colId].filterButton = false;
|
|
1563
|
+
}
|
|
1564
|
+
const sortSpecs = createSortSpecsFromSortState(tableDefinition.sortState ?? tableDefinition["x:sortState"], range);
|
|
1565
|
+
const headerRow = attrs.headerRowCount !== "0";
|
|
1560
1566
|
const tableStyle = get(tableDefinition, "tableStyleInfo") ||
|
|
1561
1567
|
get(tableDefinition, "x:tableStyleInfo") ||
|
|
1562
1568
|
{};
|
|
@@ -1565,16 +1571,18 @@ export class XlsbPlugin extends BaseWorkbookPlugin {
|
|
|
1565
1571
|
id: attrs.id || uuid(),
|
|
1566
1572
|
title: attrs.name || attrs.displayName || `Table_${tables.length + 1}`,
|
|
1567
1573
|
sheetId: sheet.sheetId,
|
|
1568
|
-
headerRow
|
|
1574
|
+
headerRow,
|
|
1569
1575
|
totalRow: attrs.totalsRowCount === "1",
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1576
|
+
// The banding toggles live on `<tableStyleInfo>`, not on `<table>`.
|
|
1577
|
+
showRowStripes: tableStyleAttrs.showRowStripes !== "0",
|
|
1578
|
+
showColumnStripes: tableStyleAttrs.showColumnStripes === "1",
|
|
1579
|
+
showFirstColumn: tableStyleAttrs.showFirstColumn === "1",
|
|
1580
|
+
showLastColumn: tableStyleAttrs.showLastColumn === "1",
|
|
1581
|
+
filterButton: attrs.filterButton !== "0" && (!headerRow || autoFilter !== undefined),
|
|
1575
1582
|
columns: columns,
|
|
1576
1583
|
range,
|
|
1577
1584
|
filterSpecs,
|
|
1585
|
+
...(sortSpecs.length ? { sortSpecs } : {}),
|
|
1578
1586
|
};
|
|
1579
1587
|
if (tableStyleAttrs.name) {
|
|
1580
1588
|
tableView.theme = tableStyleAttrs.name;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChartData, EmbeddedChart, EmbeddedObjectPosition, HIDDEN_DIMENSION_STRATEGY, SheetRange } from "@rowsncolumns/spreadsheet";
|
|
1
|
+
import type { ChartData, EmbeddedChart, EmbeddedObjectPosition, HIDDEN_DIMENSION_STRATEGY, PivotChartFieldButtons, PivotChartFormat, PivotTable, SheetRange } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import type { StreamingZipParser } from "../../zip-parser-streaming";
|
|
3
3
|
/**
|
|
4
4
|
* Resolver from a sheet name (as it appears inside chart formula refs,
|
|
@@ -15,6 +15,82 @@ export declare function extractChartDataRange(plotArea: any, chartType: string,
|
|
|
15
15
|
* In Excel: plotVisOnly="1" means skip hidden rows/columns, "0" means show all
|
|
16
16
|
*/
|
|
17
17
|
export declare function extractHiddenDimensionStrategy(chart: any): HIDDEN_DIMENSION_STRATEGY | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* `<c:dispBlanksAs val="gap|zero|span"/>` — Excel's "Show empty cells as"
|
|
20
|
+
* (Select Data → Hidden and Empty Cells). `span` is "Connect data points
|
|
21
|
+
* with line".
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractEmptyCellsPolicy(chart: any): "gaps" | "zero" | "connect" | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Excel 2016+ "Show #N/A as an empty cell":
|
|
26
|
+
* `<c:chart><c:extLst><c:ext uri="{56B9EC1D-…}"><c16r3:dataDisplayOptions16>
|
|
27
|
+
* <c16r3:dispNaAsBlank val="0|1"/>`. Undefined when the file predates the
|
|
28
|
+
* option (Excel then treats #N/A the legacy way — as if `val="0"`, but the
|
|
29
|
+
* spec leaves the default to the renderer).
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractShowNaAsEmpty(chart: any): boolean | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Transient spec key carrying `<c:pivotSource><c:name>` until the workbook's
|
|
34
|
+
* pivots are known; `bindPivotChartsToPivotTables` turns it into
|
|
35
|
+
* `pivotTableId` and removes it.
|
|
36
|
+
*/
|
|
37
|
+
export declare const PIVOT_SOURCE_NAME_KEY = "__pivotSourceName";
|
|
38
|
+
/**
|
|
39
|
+
* Transient spec key carrying `<c:pivotSource><c:fmtId>` alongside the
|
|
40
|
+
* name; becomes `pivotSource.formatId` once the chart binds to its pivot.
|
|
41
|
+
*/
|
|
42
|
+
export declare const PIVOT_SOURCE_FORMAT_ID_KEY = "__pivotSourceFormatId";
|
|
43
|
+
/**
|
|
44
|
+
* `<c:pivotSource><c:fmtId val="3"/>` — the id the pivot's `<chartFormats>`
|
|
45
|
+
* name this chart by. `0` is the exporter's default and stays implicit.
|
|
46
|
+
*/
|
|
47
|
+
export declare function extractPivotSourceFormatId(chartSpaceRoot: any): number | undefined;
|
|
48
|
+
/** `<c:pivotSource><c:name>[Book1.xlsx]Sheet1!PivotTable1</c:name>` → the name text. */
|
|
49
|
+
export declare function extractPivotSourceName(chartSpaceRoot: any): string | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Split a pivotSource name into its sheet and pivot-table parts. The
|
|
52
|
+
* `[workbook]` prefix is dropped (it names the file the chart lived in);
|
|
53
|
+
* the sheet may be quoted (`'My Sheet'!PivotTable1`).
|
|
54
|
+
*/
|
|
55
|
+
export declare function parsePivotSourceName(name: string): {
|
|
56
|
+
sheetTitle?: string;
|
|
57
|
+
pivotName: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve every imported chart's `<c:pivotSource>` name to the id of the
|
|
61
|
+
* imported PivotTable it names (matched by pivot name, and by the pivot's
|
|
62
|
+
* target sheet when the name carries one). A name that matches no pivot
|
|
63
|
+
* leaves a plain chart — Excel converts a PivotChart whose pivot is gone
|
|
64
|
+
* to a static chart too. The transient key is always removed.
|
|
65
|
+
*/
|
|
66
|
+
export declare function bindPivotChartsToPivotTables(charts: EmbeddedChart[], pivotTables: readonly PivotTable[], sheetTitleById: ReadonlyMap<number, string>): void;
|
|
67
|
+
/**
|
|
68
|
+
* `<c:chart><c:pivotFmts><c:pivotFmt><c:idx val/>…` — the per pivot-item
|
|
69
|
+
* formats Excel re-applies on a re-plot; only the index and a literal
|
|
70
|
+
* fill colour are kept.
|
|
71
|
+
*/
|
|
72
|
+
export declare function extractPivotFormats(chart: any): PivotChartFormat[] | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* Namespace URI → the prefix Excel writes for it. Bodies are stored with these
|
|
75
|
+
* canonical prefixes so a file that declared, say, `xmlns:c="…"` as `cs:` still
|
|
76
|
+
* round-trips through an exporter that declares `c:` / `a:` at the root.
|
|
77
|
+
*/
|
|
78
|
+
export declare const CHART_XML_PREFIXES: Record<string, string>;
|
|
79
|
+
/**
|
|
80
|
+
* Read every `<c:pivotFmt>` body (its children after `<c:idx>`) verbatim from
|
|
81
|
+
* the chart part and attach it to the matching `pivotFormats` entry by index
|
|
82
|
+
* (rowsncolumns/spreadsheet#668 C-83). Gradient fills, theme colours, markers
|
|
83
|
+
* and data-label formatting Excel keeps per pivot item survive the round-trip
|
|
84
|
+
* that `color` (a literal solid fill) alone cannot carry.
|
|
85
|
+
*/
|
|
86
|
+
export declare function attachPivotFormatBodies(formats: PivotChartFormat[], chartContent: string): void;
|
|
87
|
+
/**
|
|
88
|
+
* Excel's Field Buttons choices — `<c14:pivotOptions>` in the chartSpace
|
|
89
|
+
* `<c:extLst>`: `dropZoneFilter` / `dropZoneCategories` / `dropZoneData` /
|
|
90
|
+
* `dropZoneSeries` / `dropZonesVisible`, each `1` unless hidden. Only the
|
|
91
|
+
* hidden ones are recorded (every button shows by default).
|
|
92
|
+
*/
|
|
93
|
+
export declare function extractPivotFieldButtons(chartSpaceRoot: any): PivotChartFieldButtons | undefined;
|
|
18
94
|
export declare function extractChartTitle(chart: any): string;
|
|
19
95
|
export declare function determineChartType(chart: any): "bar" | "column" | "line" | "pie" | "doughnut" | "area" | "radar" | "stock" | "scatter" | "bubble" | "treemap" | "sunburst" | "histogram" | "boxplot" | "waterfall" | "funnel";
|
|
20
96
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsx/charts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,
|
|
1
|
+
{"version":3,"file":"charts.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsx/charts.ts"],"names":[],"mappings":"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"}
|