@rowsncolumns/toolkit 24.4.3 → 24.4.5
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/excel-parser/interface.d.ts +5 -1
- package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/base/index.d.ts +2 -0
- package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/base/index.js +3 -0
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts +55 -9
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xls/index.js +487 -24
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsb/index.js +12 -5
- package/dist/cjs/excel-parser/plugins/xlsx/chartex.d.ts +37 -0
- package/dist/cjs/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/chartex.js +244 -0
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts +70 -0
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/form-controls.js +295 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +9 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +251 -104
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +15 -1
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
- package/dist/cjs/excel-parser/plugins/xlsx/styles.js +90 -4
- package/dist/cjs/excel-parser/registry.d.ts +7 -0
- package/dist/cjs/excel-parser/registry.d.ts.map +1 -1
- package/dist/cjs/excel-parser/registry.js +28 -1
- package/dist/cjs/excel-parser/types.d.ts +10 -1
- package/dist/cjs/excel-parser/types.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.d.ts +2 -0
- package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
- package/dist/cjs/excel-parser/workbook.js +20 -14
- package/dist/cjs/excel-parser/worker.js +128 -130
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/chart-builder.js +5 -33
- package/dist/cjs/exporter/xlsx/chartex-builder.d.ts +36 -0
- package/dist/cjs/exporter/xlsx/chartex-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/chartex-builder.js +109 -0
- package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts +61 -0
- package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/form-controls-builder.js +197 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/cjs/exporter/xlsx/xlsx-export.js +431 -193
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/excel-parser/interface.d.ts +5 -1
- package/dist/esm/excel-parser/interface.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/base/index.d.ts +2 -0
- package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/base/index.js +3 -0
- package/dist/esm/excel-parser/plugins/xls/index.d.ts +55 -9
- package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xls/index.js +429 -23
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsb/index.js +10 -3
- package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts +37 -0
- package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/chartex.js +199 -0
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts +70 -0
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/form-controls.js +246 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +9 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/index.js +92 -6
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +15 -1
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
- package/dist/esm/excel-parser/plugins/xlsx/styles.js +80 -0
- package/dist/esm/excel-parser/registry.d.ts +7 -0
- package/dist/esm/excel-parser/registry.d.ts.map +1 -1
- package/dist/esm/excel-parser/registry.js +18 -1
- package/dist/esm/excel-parser/types.d.ts +10 -1
- package/dist/esm/excel-parser/types.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.d.ts +2 -0
- package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
- package/dist/esm/excel-parser/workbook.js +16 -10
- package/dist/esm/excel-parser/worker.js +10 -18
- package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/chart-builder.js +0 -28
- package/dist/esm/exporter/xlsx/chartex-builder.d.ts +36 -0
- package/dist/esm/exporter/xlsx/chartex-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/chartex-builder.js +97 -0
- package/dist/esm/exporter/xlsx/form-controls-builder.d.ts +61 -0
- package/dist/esm/exporter/xlsx/form-controls-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/form-controls-builder.js +173 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
- package/dist/esm/exporter/xlsx/xlsx-export.js +228 -19
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/xlsx.d.ts +14 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator, __read, __spreadArray, __values } from "tslib";
|
|
2
|
+
import { generateSelectionsFromFormula, uuid } from "@rowsncolumns/utils";
|
|
3
|
+
import { get } from "lodash-es";
|
|
4
|
+
import { extractChartPosition, } from "./charts";
|
|
5
|
+
/**
|
|
6
|
+
* Excel 2016+ "chartex" charts (`xl/charts/chartEx{N}.xml`, namespace
|
|
7
|
+
* `http://schemas.microsoft.com/office/drawing/2014/chartex`): treemap,
|
|
8
|
+
* sunburst, histogram / pareto, box & whisker, waterfall, funnel. They are
|
|
9
|
+
* anchored through an `mc:AlternateContent` whose `Choice` graphic frame
|
|
10
|
+
* carries `<cx:chart r:id>` instead of `<c:chart>`, and their data lives in
|
|
11
|
+
* `<cx:chartData><cx:data>` dimensions (`strDim type="cat"` for the
|
|
12
|
+
* hierarchy, `numDim type="size"|"val"` for the numbers) referenced by the
|
|
13
|
+
* series through `<cx:dataId>`.
|
|
14
|
+
*
|
|
15
|
+
* The exporter counterpart is `exporter/xlsx/chartex-builder.ts`.
|
|
16
|
+
*/
|
|
17
|
+
export var CHART_EX_REL_TYPE = "http://schemas.microsoft.com/office/2014/relationships/chartEx";
|
|
18
|
+
export var CHART_EX_GRAPHIC_URI = "http://schemas.microsoft.com/office/drawing/2014/chartex";
|
|
19
|
+
var asArray = function (value) {
|
|
20
|
+
return value == null ? [] : Array.isArray(value) ? value : [value];
|
|
21
|
+
};
|
|
22
|
+
/** Read a child by local name, tolerating any namespace prefix. */
|
|
23
|
+
var child = function (node, localName) {
|
|
24
|
+
var e_1, _a;
|
|
25
|
+
if (!node || typeof node !== "object")
|
|
26
|
+
return undefined;
|
|
27
|
+
if (node[localName] !== undefined)
|
|
28
|
+
return node[localName];
|
|
29
|
+
try {
|
|
30
|
+
for (var _b = __values(Object.keys(node)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
31
|
+
var key = _c.value;
|
|
32
|
+
var colon = key.indexOf(":");
|
|
33
|
+
if (colon >= 0 && key.slice(colon + 1) === localName)
|
|
34
|
+
return node[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
38
|
+
finally {
|
|
39
|
+
try {
|
|
40
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
41
|
+
}
|
|
42
|
+
finally { if (e_1) throw e_1.error; }
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
46
|
+
var textOf = function (node) {
|
|
47
|
+
if (node == null)
|
|
48
|
+
return undefined;
|
|
49
|
+
if (typeof node === "object") {
|
|
50
|
+
var inner = node.t$;
|
|
51
|
+
return inner == null ? undefined : String(inner);
|
|
52
|
+
}
|
|
53
|
+
return String(node);
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* `<cx:chart r:id>` inside an anchor's `mc:AlternateContent` choice (Excel
|
|
57
|
+
* also writes a plain `xdr:graphicFrame` for some producers — both forms are
|
|
58
|
+
* checked). Returns the `cx:chart` node or undefined for non-chartex anchors.
|
|
59
|
+
*/
|
|
60
|
+
export function getChartExReferenceFromAnchor(anchor) {
|
|
61
|
+
var e_2, _a, e_3, _b, e_4, _c;
|
|
62
|
+
var frames = [];
|
|
63
|
+
try {
|
|
64
|
+
for (var _d = __values(asArray(child(anchor, "AlternateContent"))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
65
|
+
var alternate = _e.value;
|
|
66
|
+
try {
|
|
67
|
+
for (var _f = (e_3 = void 0, __values(asArray(child(alternate, "Choice")))), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
68
|
+
var choice = _g.value;
|
|
69
|
+
frames.push.apply(frames, __spreadArray([], __read(asArray(child(choice, "graphicFrame"))), false));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
73
|
+
finally {
|
|
74
|
+
try {
|
|
75
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
76
|
+
}
|
|
77
|
+
finally { if (e_3) throw e_3.error; }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
82
|
+
finally {
|
|
83
|
+
try {
|
|
84
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
85
|
+
}
|
|
86
|
+
finally { if (e_2) throw e_2.error; }
|
|
87
|
+
}
|
|
88
|
+
frames.push.apply(frames, __spreadArray([], __read(asArray(child(anchor, "graphicFrame"))), false));
|
|
89
|
+
try {
|
|
90
|
+
for (var frames_1 = __values(frames), frames_1_1 = frames_1.next(); !frames_1_1.done; frames_1_1 = frames_1.next()) {
|
|
91
|
+
var frame = frames_1_1.value;
|
|
92
|
+
var graphicData = child(child(frame, "graphic"), "graphicData");
|
|
93
|
+
if (!graphicData)
|
|
94
|
+
continue;
|
|
95
|
+
var uri = get(graphicData, "a$.uri");
|
|
96
|
+
var cxChart = child(graphicData, "chart");
|
|
97
|
+
if (uri === CHART_EX_GRAPHIC_URI && cxChart)
|
|
98
|
+
return cxChart;
|
|
99
|
+
// A `cx:`-prefixed chart element without the uri attribute (defensive).
|
|
100
|
+
if (cxChart && Object.keys(graphicData).some(function (k) { return k.startsWith("cx:"); })) {
|
|
101
|
+
return cxChart;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
106
|
+
finally {
|
|
107
|
+
try {
|
|
108
|
+
if (frames_1_1 && !frames_1_1.done && (_c = frames_1.return)) _c.call(frames_1);
|
|
109
|
+
}
|
|
110
|
+
finally { if (e_4) throw e_4.error; }
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
/** `layoutId` → engine chart type. Unknown layouts are not imported. */
|
|
115
|
+
var CHART_TYPE_BY_LAYOUT = {
|
|
116
|
+
treemap: "treemap",
|
|
117
|
+
sunburst: "sunburst",
|
|
118
|
+
waterfall: "waterfall",
|
|
119
|
+
funnel: "funnel",
|
|
120
|
+
boxWhisker: "boxplot",
|
|
121
|
+
// `clusteredColumn` is a histogram / pareto only when it carries `<cx:binning>`.
|
|
122
|
+
};
|
|
123
|
+
var sourcesFromRef = function (ref, hostSheetId, resolveSheetId) {
|
|
124
|
+
if (!ref)
|
|
125
|
+
return [];
|
|
126
|
+
var selections = generateSelectionsFromFormula("=".concat(ref));
|
|
127
|
+
return selections.map(function (sel) {
|
|
128
|
+
var _a;
|
|
129
|
+
return (__assign(__assign({}, sel.range), { sheetId: (_a = (sel.sheetName ? resolveSheetId === null || resolveSheetId === void 0 ? void 0 : resolveSheetId(sel.sheetName) : undefined)) !== null && _a !== void 0 ? _a : hostSheetId }));
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
var chartData = function (sources) {
|
|
133
|
+
return ({ sources: sources });
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Split a multi-column hierarchy range (Excel lays the treemap hierarchy out
|
|
137
|
+
* as columns, top level first, leaf last) into `parentLabels` (one entry per
|
|
138
|
+
* parent column) and `labels` (the leaf column).
|
|
139
|
+
*/
|
|
140
|
+
export var splitHierarchyRange = function (range) {
|
|
141
|
+
var parentLabels = [];
|
|
142
|
+
for (var c = range.startColumnIndex; c < range.endColumnIndex; c++) {
|
|
143
|
+
parentLabels.push(__assign(__assign({}, range), { startColumnIndex: c, endColumnIndex: c }));
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
parentLabels: parentLabels,
|
|
147
|
+
labels: __assign(__assign({}, range), { startColumnIndex: range.endColumnIndex, endColumnIndex: range.endColumnIndex }),
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
var dimensionRef = function (data, dimTag, type) {
|
|
151
|
+
var _a, _b;
|
|
152
|
+
var dims = asArray(child(data, dimTag)).filter(function (dim) { return get(dim, "a$.type") === type; });
|
|
153
|
+
var dim = (_a = dims[0]) !== null && _a !== void 0 ? _a : (dimTag === "numDim" ? asArray(child(data, dimTag))[0] : undefined);
|
|
154
|
+
var f = child(dim, "f");
|
|
155
|
+
return ((_b = textOf(Array.isArray(f) ? f[0] : f)) === null || _b === void 0 ? void 0 : _b.trim()) || undefined;
|
|
156
|
+
};
|
|
157
|
+
/** Parse a `cx:chartSpace` DOM into an `EmbeddedChart` spec (null when unsupported). */
|
|
158
|
+
export function parseChartExSpec(chartSpaceDom, sheetId, resolveSheetId) {
|
|
159
|
+
var _a, _b, _c, _d, _e;
|
|
160
|
+
var chartSpace = (_a = child(chartSpaceDom, "chartSpace")) !== null && _a !== void 0 ? _a : chartSpaceDom;
|
|
161
|
+
var chart = child(chartSpace, "chart");
|
|
162
|
+
if (!chart)
|
|
163
|
+
return null;
|
|
164
|
+
var region = child(child(chart, "plotArea"), "plotAreaRegion");
|
|
165
|
+
var series = asArray(child(region, "series"))[0];
|
|
166
|
+
if (!series)
|
|
167
|
+
return null;
|
|
168
|
+
var layoutId = String((_b = get(series, "a$.layoutId")) !== null && _b !== void 0 ? _b : "");
|
|
169
|
+
// Excel nests `<cx:binning>` in `<cx:layoutPr>`; tolerate it directly on the series too.
|
|
170
|
+
var binning = (_c = child(child(series, "layoutPr"), "binning")) !== null && _c !== void 0 ? _c : child(series, "binning");
|
|
171
|
+
var chartType = layoutId === "clusteredColumn" && binning
|
|
172
|
+
? "histogram"
|
|
173
|
+
: CHART_TYPE_BY_LAYOUT[layoutId];
|
|
174
|
+
if (!chartType)
|
|
175
|
+
return null;
|
|
176
|
+
var dataId = String((_d = get(child(series, "dataId"), "a$.val")) !== null && _d !== void 0 ? _d : "0");
|
|
177
|
+
var data = (_e = asArray(child(child(chartSpace, "chartData"), "data")).find(function (d) { return String(get(d, "a$.id")) === dataId; })) !== null && _e !== void 0 ? _e : asArray(child(child(chartSpace, "chartData"), "data"))[0];
|
|
178
|
+
if (!data)
|
|
179
|
+
return null;
|
|
180
|
+
var title = textOf(child(child(child(child(chart, "title"), "tx"), "txData"), "v"));
|
|
181
|
+
var catRef = dimensionRef(data, "strDim", "cat");
|
|
182
|
+
var catSources = sourcesFromRef(catRef, sheetId, resolveSheetId);
|
|
183
|
+
if (chartType === "treemap" || chartType === "sunburst") {
|
|
184
|
+
var sizeRef = dimensionRef(data, "numDim", "size");
|
|
185
|
+
var sizeSources = sourcesFromRef(sizeRef, sheetId, resolveSheetId);
|
|
186
|
+
if (!catSources.length || !sizeSources.length)
|
|
187
|
+
return null;
|
|
188
|
+
var hierarchy = splitHierarchyRange(catSources[0]);
|
|
189
|
+
return __assign(__assign({ chartType: chartType }, (title ? { title: title } : {})), { labels: [chartData([hierarchy.labels])], parentLabels: hierarchy.parentLabels.map(function (range) { return chartData([range]); }), sizeData: [chartData(sizeSources)] });
|
|
190
|
+
}
|
|
191
|
+
var valRef = dimensionRef(data, "numDim", "val");
|
|
192
|
+
var valSources = sourcesFromRef(valRef, sheetId, resolveSheetId);
|
|
193
|
+
if (!valSources.length)
|
|
194
|
+
return null;
|
|
195
|
+
var spec = __assign(__assign(__assign({ chartType: chartType }, (title ? { title: title } : {})), { series: [chartData(valSources)] }), (catSources.length ? { domains: [chartData(catSources)] } : {}));
|
|
196
|
+
if (chartType === "histogram") {
|
|
197
|
+
var binCount = Number(get(child(binning, "binCount"), "a$.val"));
|
|
198
|
+
if (Number.isFinite(binCount) && binCount > 0)
|
|
199
|
+
spec.binCount = binCount;
|
|
200
|
+
}
|
|
201
|
+
return spec;
|
|
202
|
+
}
|
|
203
|
+
/** Resolve + parse one chartex part referenced from a drawing anchor. */
|
|
204
|
+
export function processChartEx(chartTarget, drawingPath, anchor, sheetId, zipParser, xmlParser, sheetDimensions, resolveSheetId) {
|
|
205
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
206
|
+
var chartPath, drawingDir, content, _a, spec, position;
|
|
207
|
+
return __generator(this, function (_b) {
|
|
208
|
+
switch (_b.label) {
|
|
209
|
+
case 0:
|
|
210
|
+
chartPath = chartTarget;
|
|
211
|
+
drawingDir = drawingPath.substring(0, drawingPath.lastIndexOf("/"));
|
|
212
|
+
if (chartPath.startsWith("/")) {
|
|
213
|
+
chartPath = chartPath.slice(1);
|
|
214
|
+
}
|
|
215
|
+
else if (chartPath.startsWith("../")) {
|
|
216
|
+
chartPath = "xl/".concat(chartPath.replace("../", ""));
|
|
217
|
+
}
|
|
218
|
+
else if (!chartPath.startsWith("xl/")) {
|
|
219
|
+
chartPath = "".concat(drawingDir, "/").concat(chartPath);
|
|
220
|
+
}
|
|
221
|
+
_b.label = 1;
|
|
222
|
+
case 1:
|
|
223
|
+
_b.trys.push([1, 3, , 4]);
|
|
224
|
+
return [4 /*yield*/, zipParser.getText(chartPath)];
|
|
225
|
+
case 2:
|
|
226
|
+
content = _b.sent();
|
|
227
|
+
return [3 /*break*/, 4];
|
|
228
|
+
case 3:
|
|
229
|
+
_a = _b.sent();
|
|
230
|
+
return [2 /*return*/, null];
|
|
231
|
+
case 4:
|
|
232
|
+
if (!content)
|
|
233
|
+
return [2 /*return*/, null];
|
|
234
|
+
spec = parseChartExSpec(xmlParser.parse(content), sheetId, resolveSheetId);
|
|
235
|
+
if (!spec)
|
|
236
|
+
return [2 /*return*/, null];
|
|
237
|
+
position = extractChartPosition(anchor, sheetId, sheetDimensions);
|
|
238
|
+
if (!position)
|
|
239
|
+
return [2 /*return*/, null];
|
|
240
|
+
return [2 /*return*/, { chartId: uuid(), spec: spec, position: position }];
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { EmbeddedObject } from "@rowsncolumns/spreadsheet";
|
|
2
|
+
export declare const CTRL_PROP_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp";
|
|
3
|
+
export declare const VML_DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
|
|
4
|
+
type CellAnchor = {
|
|
5
|
+
col: number;
|
|
6
|
+
colOff: number;
|
|
7
|
+
row: number;
|
|
8
|
+
rowOff: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* `<controlPr><anchor><from>…</from><to>…</to></anchor>` → the engine's
|
|
12
|
+
* pixel overlay position (1-based anchor cell, EMU offsets → px, size from
|
|
13
|
+
* the cell span at the grid defaults — the same approximation the drawing
|
|
14
|
+
* importer uses for `twoCellAnchor`s).
|
|
15
|
+
*/
|
|
16
|
+
export declare const controlAnchorToOverlayPosition: (from: CellAnchor, to: CellAnchor | undefined) => {
|
|
17
|
+
anchorCell: {
|
|
18
|
+
rowIndex: number;
|
|
19
|
+
columnIndex: number;
|
|
20
|
+
};
|
|
21
|
+
offsetXPixels?: number;
|
|
22
|
+
offsetYPixels?: number;
|
|
23
|
+
widthPixels?: number;
|
|
24
|
+
heightPixels?: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Parse an `xl/ctrlProps/ctrlPropN.xml` part: `objectType`, every other
|
|
28
|
+
* `formControlPr` attribute verbatim, and the literal `itemLst` items.
|
|
29
|
+
*/
|
|
30
|
+
export declare const parseFormControlPr: (ctrlPropDom: any) => {
|
|
31
|
+
objectType: string;
|
|
32
|
+
properties: Record<string, string>;
|
|
33
|
+
listItems?: string[];
|
|
34
|
+
} | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Captions live only in the legacy VML part: `<v:shape id="_x0000_s1025">
|
|
37
|
+
* … <v:textbox><div>Check Box 1</div></v:textbox>`. Returns shapeId → text.
|
|
38
|
+
* VML is scanned textually — Excel's VML is not reliably well-formed XML.
|
|
39
|
+
*/
|
|
40
|
+
export declare const parseVmlControlCaptions: (vml: string | undefined) => Map<number, string>;
|
|
41
|
+
export type RawWorksheetControl = {
|
|
42
|
+
shapeId?: number;
|
|
43
|
+
name?: string;
|
|
44
|
+
relId?: string;
|
|
45
|
+
controlProperties: Record<string, string>;
|
|
46
|
+
moveWithCells?: boolean;
|
|
47
|
+
sizeWithCells?: boolean;
|
|
48
|
+
from?: CellAnchor;
|
|
49
|
+
to?: CellAnchor;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* `<controls>` from a worksheet DOM, whether wrapped in
|
|
53
|
+
* `<mc:AlternateContent><mc:Choice Requires="x14">` (Excel) or bare.
|
|
54
|
+
*/
|
|
55
|
+
export declare const readWorksheetControls: (sheetDom: any) => RawWorksheetControl[];
|
|
56
|
+
/**
|
|
57
|
+
* Assemble the sheet's form controls. `loadCtrlProp` resolves a control's
|
|
58
|
+
* `r:id` to its parsed `ctrlProp` DOM (undefined when the part is missing —
|
|
59
|
+
* the control is then skipped, Excel would repair it the same way).
|
|
60
|
+
*/
|
|
61
|
+
export declare const buildFormControlEmbeds: ({ controls, sheetId, ctrlProps, captions, }: {
|
|
62
|
+
controls: RawWorksheetControl[];
|
|
63
|
+
sheetId: number;
|
|
64
|
+
ctrlProps: Map<string, ReturnType<typeof parseFormControlPr>>;
|
|
65
|
+
captions: Map<number, string>;
|
|
66
|
+
}) => EmbeddedObject[];
|
|
67
|
+
/** The `r:id` of a worksheet's `<legacyDrawing>` (VML part), if any. */
|
|
68
|
+
export declare const readLegacyDrawingRelId: (sheetDom: any) => string | undefined;
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=form-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-controls.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xlsx/form-controls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACf,MAAM,2BAA2B,CAAC;AAgBnC,eAAO,MAAM,kBAAkB,iFACiD,CAAC;AACjF,eAAO,MAAM,oBAAoB,mFACiD,CAAC;AA6CnF,KAAK,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAe/E;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GACzC,MAAM,UAAU,EAChB,IAAI,UAAU,GAAG,SAAS;gBAKZ;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;oBACrC,MAAM;oBACN,MAAM;kBACR,MAAM;mBACL,MAAM;CAiBxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,aAAa,GAAG,KACf;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,SAkBH,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,MAAM,GAAG,SAAS,KACtB,GAAG,CAAC,MAAM,EAAE,MAAM,CAwBpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,UAAU,GAAG,KAAG,mBAAmB,EA+BxE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,6CAKpC;IACD,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC;IAC9D,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,KAAG,cAAc,EA+BjB,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,GAAI,UAAU,GAAG,KAAG,MAAM,GAAG,SAK/D,CAAC"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { __assign, __read, __rest, __spreadArray, __values } from "tslib";
|
|
2
|
+
/**
|
|
3
|
+
* Excel form controls (`<controls>` in the worksheet + `xl/ctrlProps/*` +
|
|
4
|
+
* the legacy VML shape). Parsed into `EmbeddedObject`s with an
|
|
5
|
+
* {@link EmbedFormControlSpec} so the exporter can write the same three
|
|
6
|
+
* parts back (`exporter/xlsx/form-controls-builder.ts`). The grid does not
|
|
7
|
+
* run the control; the spec is a faithful, opaque carrier of what Excel
|
|
8
|
+
* stored.
|
|
9
|
+
*/
|
|
10
|
+
var EMU_PER_PIXEL = 9525;
|
|
11
|
+
/** Grid defaults used to size a control from its cell-span anchor. */
|
|
12
|
+
var DEFAULT_COLUMN_WIDTH_PX = 100;
|
|
13
|
+
var DEFAULT_ROW_HEIGHT_PX = 20;
|
|
14
|
+
export var CTRL_PROP_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp";
|
|
15
|
+
export var VML_DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
|
|
16
|
+
var asArray = function (value) {
|
|
17
|
+
return value == null ? [] : Array.isArray(value) ? value : [value];
|
|
18
|
+
};
|
|
19
|
+
/** Read a child by local name, tolerating any namespace prefix. */
|
|
20
|
+
var childByLocalName = function (node, localName) {
|
|
21
|
+
var e_1, _a;
|
|
22
|
+
if (!node || typeof node !== "object")
|
|
23
|
+
return undefined;
|
|
24
|
+
if (node[localName] !== undefined)
|
|
25
|
+
return node[localName];
|
|
26
|
+
try {
|
|
27
|
+
for (var _b = __values(Object.keys(node)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
28
|
+
var key = _c.value;
|
|
29
|
+
var colon = key.indexOf(":");
|
|
30
|
+
if (colon >= 0 && key.slice(colon + 1) === localName) {
|
|
31
|
+
return node[key];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
36
|
+
finally {
|
|
37
|
+
try {
|
|
38
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
39
|
+
}
|
|
40
|
+
finally { if (e_1) throw e_1.error; }
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
};
|
|
44
|
+
/** Text of a leaf element (`t$` when it carries attributes, else the value). */
|
|
45
|
+
var textOf = function (node) {
|
|
46
|
+
if (node == null)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (typeof node === "object") {
|
|
49
|
+
var inner = node.t$;
|
|
50
|
+
return inner == null ? undefined : String(inner);
|
|
51
|
+
}
|
|
52
|
+
return String(node);
|
|
53
|
+
};
|
|
54
|
+
var numberOf = function (node) {
|
|
55
|
+
var text = textOf(node);
|
|
56
|
+
var value = text == null ? Number.NaN : Number(text);
|
|
57
|
+
return Number.isFinite(value) ? value : 0;
|
|
58
|
+
};
|
|
59
|
+
var attrs = function (node) {
|
|
60
|
+
var e_2, _a;
|
|
61
|
+
var raw = node === null || node === void 0 ? void 0 : node.a$;
|
|
62
|
+
var out = {};
|
|
63
|
+
if (!raw || typeof raw !== "object")
|
|
64
|
+
return out;
|
|
65
|
+
try {
|
|
66
|
+
for (var _b = __values(Object.entries(raw)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
67
|
+
var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
|
|
68
|
+
if (value == null)
|
|
69
|
+
continue;
|
|
70
|
+
out[key] = String(value);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
74
|
+
finally {
|
|
75
|
+
try {
|
|
76
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
77
|
+
}
|
|
78
|
+
finally { if (e_2) throw e_2.error; }
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
};
|
|
82
|
+
var readCellAnchor = function (node) {
|
|
83
|
+
if (!node)
|
|
84
|
+
return undefined;
|
|
85
|
+
var col = childByLocalName(node, "col");
|
|
86
|
+
var row = childByLocalName(node, "row");
|
|
87
|
+
if (col === undefined || row === undefined)
|
|
88
|
+
return undefined;
|
|
89
|
+
return {
|
|
90
|
+
col: numberOf(col),
|
|
91
|
+
colOff: numberOf(childByLocalName(node, "colOff")),
|
|
92
|
+
row: numberOf(row),
|
|
93
|
+
rowOff: numberOf(childByLocalName(node, "rowOff")),
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* `<controlPr><anchor><from>…</from><to>…</to></anchor>` → the engine's
|
|
98
|
+
* pixel overlay position (1-based anchor cell, EMU offsets → px, size from
|
|
99
|
+
* the cell span at the grid defaults — the same approximation the drawing
|
|
100
|
+
* importer uses for `twoCellAnchor`s).
|
|
101
|
+
*/
|
|
102
|
+
export var controlAnchorToOverlayPosition = function (from, to) {
|
|
103
|
+
var offsetXPixels = Math.round(from.colOff / EMU_PER_PIXEL);
|
|
104
|
+
var offsetYPixels = Math.round(from.rowOff / EMU_PER_PIXEL);
|
|
105
|
+
var overlay = {
|
|
106
|
+
anchorCell: { rowIndex: from.row + 1, columnIndex: from.col + 1 },
|
|
107
|
+
};
|
|
108
|
+
if (offsetXPixels)
|
|
109
|
+
overlay.offsetXPixels = offsetXPixels;
|
|
110
|
+
if (offsetYPixels)
|
|
111
|
+
overlay.offsetYPixels = offsetYPixels;
|
|
112
|
+
if (to) {
|
|
113
|
+
var width = (to.col - from.col) * DEFAULT_COLUMN_WIDTH_PX +
|
|
114
|
+
(to.colOff - from.colOff) / EMU_PER_PIXEL;
|
|
115
|
+
var height = (to.row - from.row) * DEFAULT_ROW_HEIGHT_PX +
|
|
116
|
+
(to.rowOff - from.rowOff) / EMU_PER_PIXEL;
|
|
117
|
+
if (width > 0)
|
|
118
|
+
overlay.widthPixels = Math.round(width);
|
|
119
|
+
if (height > 0)
|
|
120
|
+
overlay.heightPixels = Math.round(height);
|
|
121
|
+
}
|
|
122
|
+
return overlay;
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Parse an `xl/ctrlProps/ctrlPropN.xml` part: `objectType`, every other
|
|
126
|
+
* `formControlPr` attribute verbatim, and the literal `itemLst` items.
|
|
127
|
+
*/
|
|
128
|
+
export var parseFormControlPr = function (ctrlPropDom) {
|
|
129
|
+
var e_3, _a;
|
|
130
|
+
var root = childByLocalName(ctrlPropDom, "formControlPr");
|
|
131
|
+
if (!root)
|
|
132
|
+
return undefined;
|
|
133
|
+
var _b = attrs(root), objectType = _b.objectType, properties = __rest(_b, ["objectType"]);
|
|
134
|
+
if (!objectType)
|
|
135
|
+
return undefined;
|
|
136
|
+
try {
|
|
137
|
+
// Namespace declarations ride along as attributes in fast-xml-parser.
|
|
138
|
+
for (var _c = __values(Object.keys(properties)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
139
|
+
var key = _d.value;
|
|
140
|
+
if (key === "xmlns" || key.startsWith("xmlns:"))
|
|
141
|
+
delete properties[key];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
145
|
+
finally {
|
|
146
|
+
try {
|
|
147
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
148
|
+
}
|
|
149
|
+
finally { if (e_3) throw e_3.error; }
|
|
150
|
+
}
|
|
151
|
+
var itemLst = childByLocalName(root, "itemLst");
|
|
152
|
+
var listItems = asArray(childByLocalName(itemLst, "item"))
|
|
153
|
+
.map(function (item) { return attrs(item).val; })
|
|
154
|
+
.filter(function (val) { return typeof val === "string"; });
|
|
155
|
+
return __assign({ objectType: objectType, properties: properties }, (listItems.length ? { listItems: listItems } : {}));
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Captions live only in the legacy VML part: `<v:shape id="_x0000_s1025">
|
|
159
|
+
* … <v:textbox><div>Check Box 1</div></v:textbox>`. Returns shapeId → text.
|
|
160
|
+
* VML is scanned textually — Excel's VML is not reliably well-formed XML.
|
|
161
|
+
*/
|
|
162
|
+
export var parseVmlControlCaptions = function (vml) {
|
|
163
|
+
var captions = new Map();
|
|
164
|
+
if (!vml)
|
|
165
|
+
return captions;
|
|
166
|
+
var shapeRe = /<v:shape\b([^>]*)>([\s\S]*?)<\/v:shape>/g;
|
|
167
|
+
var match;
|
|
168
|
+
while ((match = shapeRe.exec(vml))) {
|
|
169
|
+
var idMatch = /\bid="_x0000_s(\d+)"/.exec(match[1]);
|
|
170
|
+
if (!idMatch)
|
|
171
|
+
continue;
|
|
172
|
+
var body = match[2];
|
|
173
|
+
if (!/<x:ClientData\b/.test(body))
|
|
174
|
+
continue;
|
|
175
|
+
var textbox = /<v:textbox\b[^>]*>([\s\S]*?)<\/v:textbox>/.exec(body);
|
|
176
|
+
if (!textbox)
|
|
177
|
+
continue;
|
|
178
|
+
var text = textbox[1]
|
|
179
|
+
.replace(/<br\s*\/?>/gi, "\n")
|
|
180
|
+
.replace(/<[^>]+>/g, "")
|
|
181
|
+
.replace(/&/g, "&")
|
|
182
|
+
.replace(/</g, "<")
|
|
183
|
+
.replace(/>/g, ">")
|
|
184
|
+
.replace(/"/g, '"')
|
|
185
|
+
.replace(/&#(\d+);/g, function (_, code) { return String.fromCodePoint(Number(code)); })
|
|
186
|
+
.trim();
|
|
187
|
+
if (text)
|
|
188
|
+
captions.set(Number(idMatch[1]), text);
|
|
189
|
+
}
|
|
190
|
+
return captions;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* `<controls>` from a worksheet DOM, whether wrapped in
|
|
194
|
+
* `<mc:AlternateContent><mc:Choice Requires="x14">` (Excel) or bare.
|
|
195
|
+
*/
|
|
196
|
+
export var readWorksheetControls = function (sheetDom) {
|
|
197
|
+
var e_4, _a, e_5, _b;
|
|
198
|
+
var _c;
|
|
199
|
+
var worksheet = (_c = childByLocalName(sheetDom, "worksheet")) !== null && _c !== void 0 ? _c : sheetDom;
|
|
200
|
+
var controls = childByLocalName(worksheet, "controls");
|
|
201
|
+
if (!controls)
|
|
202
|
+
return [];
|
|
203
|
+
var controlNodes = __spreadArray([], __read(asArray(childByLocalName(controls, "control"))), false);
|
|
204
|
+
try {
|
|
205
|
+
for (var _d = __values(asArray(childByLocalName(controls, "AlternateContent"))), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
206
|
+
var alternate = _e.value;
|
|
207
|
+
try {
|
|
208
|
+
for (var _f = (e_5 = void 0, __values(asArray(childByLocalName(alternate, "Choice")))), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
209
|
+
var choice = _g.value;
|
|
210
|
+
controlNodes.push.apply(controlNodes, __spreadArray([], __read(asArray(childByLocalName(choice, "control"))), false));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
214
|
+
finally {
|
|
215
|
+
try {
|
|
216
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
217
|
+
}
|
|
218
|
+
finally { if (e_5) throw e_5.error; }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
223
|
+
finally {
|
|
224
|
+
try {
|
|
225
|
+
if (_e && !_e.done && (_a = _d.return)) _a.call(_d);
|
|
226
|
+
}
|
|
227
|
+
finally { if (e_4) throw e_4.error; }
|
|
228
|
+
}
|
|
229
|
+
return controlNodes.map(function (node) {
|
|
230
|
+
var _a, _b;
|
|
231
|
+
var a = attrs(node);
|
|
232
|
+
var controlPr = childByLocalName(node, "controlPr");
|
|
233
|
+
var anchor = childByLocalName(controlPr, "anchor");
|
|
234
|
+
var anchorAttrs = attrs(anchor);
|
|
235
|
+
var shapeId = Number(a.shapeId);
|
|
236
|
+
return __assign(__assign(__assign(__assign(__assign(__assign(__assign({}, (Number.isFinite(shapeId) && a.shapeId ? { shapeId: shapeId } : {})), (a.name ? { name: a.name } : {})), (((_a = a["r:id"]) !== null && _a !== void 0 ? _a : a.id) ? { relId: (_b = a["r:id"]) !== null && _b !== void 0 ? _b : a.id } : {})), { controlProperties: attrs(controlPr) }), (anchorAttrs.moveWithCells !== undefined
|
|
237
|
+
? { moveWithCells: anchorAttrs.moveWithCells === "1" || anchorAttrs.moveWithCells === "true" }
|
|
238
|
+
: {})), (anchorAttrs.sizeWithCells !== undefined
|
|
239
|
+
? { sizeWithCells: anchorAttrs.sizeWithCells === "1" || anchorAttrs.sizeWithCells === "true" }
|
|
240
|
+
: {})), { from: readCellAnchor(childByLocalName(anchor, "from")), to: readCellAnchor(childByLocalName(anchor, "to")) });
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Assemble the sheet's form controls. `loadCtrlProp` resolves a control's
|
|
245
|
+
* `r:id` to its parsed `ctrlProp` DOM (undefined when the part is missing —
|
|
246
|
+
* the control is then skipped, Excel would repair it the same way).
|
|
247
|
+
*/
|
|
248
|
+
export var buildFormControlEmbeds = function (_a) {
|
|
249
|
+
var controls = _a.controls, sheetId = _a.sheetId, ctrlProps = _a.ctrlProps, captions = _a.captions;
|
|
250
|
+
var embeds = [];
|
|
251
|
+
controls.forEach(function (control, index) {
|
|
252
|
+
var _a;
|
|
253
|
+
var parsed = control.relId ? ctrlProps.get(control.relId) : undefined;
|
|
254
|
+
if (!parsed || !control.from)
|
|
255
|
+
return;
|
|
256
|
+
var spec = {
|
|
257
|
+
type: "formControl",
|
|
258
|
+
objectType: parsed.objectType,
|
|
259
|
+
properties: parsed.properties,
|
|
260
|
+
};
|
|
261
|
+
if (control.name)
|
|
262
|
+
spec.name = control.name;
|
|
263
|
+
if (control.shapeId !== undefined)
|
|
264
|
+
spec.shapeId = control.shapeId;
|
|
265
|
+
var caption = control.shapeId !== undefined ? captions.get(control.shapeId) : undefined;
|
|
266
|
+
if (caption)
|
|
267
|
+
spec.text = caption;
|
|
268
|
+
if (parsed.listItems)
|
|
269
|
+
spec.listItems = parsed.listItems;
|
|
270
|
+
if (Object.keys(control.controlProperties).length) {
|
|
271
|
+
spec.controlProperties = control.controlProperties;
|
|
272
|
+
}
|
|
273
|
+
if (control.moveWithCells !== undefined)
|
|
274
|
+
spec.moveWithCells = control.moveWithCells;
|
|
275
|
+
if (control.sizeWithCells !== undefined)
|
|
276
|
+
spec.sizeWithCells = control.sizeWithCells;
|
|
277
|
+
embeds.push({
|
|
278
|
+
embedId: "control-".concat(sheetId, "-").concat((_a = control.shapeId) !== null && _a !== void 0 ? _a : index + 1),
|
|
279
|
+
spec: spec,
|
|
280
|
+
position: {
|
|
281
|
+
sheetId: sheetId,
|
|
282
|
+
overlayPosition: controlAnchorToOverlayPosition(control.from, control.to),
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
return embeds;
|
|
287
|
+
};
|
|
288
|
+
/** The `r:id` of a worksheet's `<legacyDrawing>` (VML part), if any. */
|
|
289
|
+
export var readLegacyDrawingRelId = function (sheetDom) {
|
|
290
|
+
var _a, _b;
|
|
291
|
+
var worksheet = (_a = childByLocalName(sheetDom, "worksheet")) !== null && _a !== void 0 ? _a : sheetDom;
|
|
292
|
+
var legacy = childByLocalName(worksheet, "legacyDrawing");
|
|
293
|
+
var a = attrs(legacy);
|
|
294
|
+
return (_b = a["r:id"]) !== null && _b !== void 0 ? _b : a.id;
|
|
295
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CellFormat, ConditionalFormatRule, DataValidationRuleRecord, EmbeddedChart, EmbeddedObject, NamedRange, ProtectedRange, Sheet, Slicer, SpreadsheetTheme, TableView } from "@rowsncolumns/spreadsheet";
|
|
2
|
-
import type { CommentThread, TextFormat, TextFormatRun } from "@rowsncolumns/common-types";
|
|
2
|
+
import type { NamedCellStyle, CommentThread, TextFormat, TextFormatRun } from "@rowsncolumns/common-types";
|
|
3
3
|
import { XMLParser } from "fast-xml-parser";
|
|
4
4
|
import type { IWorkbookPlugin } from "../../interface";
|
|
5
5
|
import type { ExternalLink, ProcessSheetDataForSheetOptions, ProcessSheetDataResult, SheetCatalogEntry, WorkbookProperties } from "../../types";
|
|
@@ -252,6 +252,8 @@ export declare class XlsxPlugin extends BaseWorkbookPlugin implements IWorkbookP
|
|
|
252
252
|
getSheetData(rid: string): Promise<any>;
|
|
253
253
|
getStyles(): any;
|
|
254
254
|
getTheme(): SpreadsheetTheme;
|
|
255
|
+
/** `<cellStyles>` resolved to cell formats (toolbar "Workbook styles" gallery). */
|
|
256
|
+
getNamedCellStyles(): NamedCellStyle[];
|
|
255
257
|
/**
|
|
256
258
|
* The workbook default font — styles.xml fonts[0], the font every cell
|
|
257
259
|
* without an explicit font inherits. Exporters pass this through so the
|
|
@@ -294,6 +296,12 @@ export declare class XlsxPlugin extends BaseWorkbookPlugin implements IWorkbookP
|
|
|
294
296
|
releaseSheetCaches(sheetId: number): void;
|
|
295
297
|
private processOneSheet;
|
|
296
298
|
getDrawings(): Promise<EmbeddedObjectWithPosition[]>;
|
|
299
|
+
/**
|
|
300
|
+
* Form controls: `<controls><control r:id>` → `xl/ctrlProps/ctrlPropN.xml`
|
|
301
|
+
* (+ the caption from the sheet's legacy VML part), as `formControl`
|
|
302
|
+
* embeds. Nothing is rendered interactively — they round-trip.
|
|
303
|
+
*/
|
|
304
|
+
_getFormControls(rid: string, sheetId: number, sheetData: any): Promise<EmbeddedObject[]>;
|
|
297
305
|
getCharts(): Promise<EmbeddedChart[]>;
|
|
298
306
|
/**
|
|
299
307
|
* Phase D1 — extract every pivot table across every worksheet.
|