@ryuzaki13/react-foundation-lib 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/excel/index.js
CHANGED
|
@@ -4,21 +4,21 @@ import { d as c, t as l } from "../chunks/validate-DyzojM0w.js";
|
|
|
4
4
|
import { escapeXmlValue as u } from "../xml/index.js";
|
|
5
5
|
import d from "write-excel-file/browser";
|
|
6
6
|
//#region src/excel/excel.ts
|
|
7
|
-
var
|
|
7
|
+
var ee = {
|
|
8
8
|
information: "#2563EB",
|
|
9
9
|
success: "#107C10",
|
|
10
10
|
warning: "#B7791F",
|
|
11
11
|
error: "#C50F1F"
|
|
12
|
-
},
|
|
12
|
+
}, te = {
|
|
13
13
|
fontWeight: "bold",
|
|
14
14
|
bottomBorderStyle: "thin",
|
|
15
15
|
bottomBorderColor: "#D9D9D9"
|
|
16
|
-
},
|
|
17
|
-
function
|
|
18
|
-
let t = e ?
|
|
16
|
+
}, f = 31, ne = /[\u0000-\u001f[\]/\\:*?]+/g, p = /^'+|'+$/g, m = /\s+/g;
|
|
17
|
+
function h(e) {
|
|
18
|
+
let t = e ? ee[e] : void 0;
|
|
19
19
|
return t ? { textColor: t } : void 0;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function g(e) {
|
|
22
22
|
let t = e + 1, n = "";
|
|
23
23
|
for (; t > 0;) {
|
|
24
24
|
let e = (t - 1) % 26;
|
|
@@ -26,28 +26,28 @@ function _(e) {
|
|
|
26
26
|
}
|
|
27
27
|
return n;
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
if (!(e <= 0 || t <= 0)) return `A1:${
|
|
29
|
+
function _(e, t) {
|
|
30
|
+
if (!(e <= 0 || t <= 0)) return `A1:${g(e - 1)}${t}`;
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function v(e) {
|
|
33
33
|
if (e.some(Boolean)) return { files: { transform: { "xl/worksheets/sheet{id}.xml": { transform: (t, n, r) => {
|
|
34
34
|
let i = e[r.sheetIndex];
|
|
35
35
|
return i ? t.replace("</sheetData>", `</sheetData><autoFilter ref="${i}"/>`) : t;
|
|
36
36
|
} } } } };
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function y(e) {
|
|
39
39
|
let t = /* @__PURE__ */ new Set(), n = [];
|
|
40
40
|
for (let r = 0; r < e.length; r += 1) {
|
|
41
|
-
let i = `Лист ${r + 1}`, a = e[r]?.replace(
|
|
41
|
+
let i = `Лист ${r + 1}`, a = e[r]?.replace(ne, " ").replace(m, " ").trim().replace(p, "").trim() || i, o = a.slice(0, f), s = 2;
|
|
42
42
|
for (; t.has(o.toLocaleLowerCase());) {
|
|
43
43
|
let e = ` (${s})`;
|
|
44
|
-
o = `${a.slice(0,
|
|
44
|
+
o = `${a.slice(0, f - e.length)}${e}`, s += 1;
|
|
45
45
|
}
|
|
46
46
|
t.add(o.toLocaleLowerCase()), n.push(o);
|
|
47
47
|
}
|
|
48
48
|
return n;
|
|
49
49
|
}
|
|
50
|
-
function
|
|
50
|
+
function re(e, t) {
|
|
51
51
|
if (e != null && e !== "") {
|
|
52
52
|
if (t === Number) {
|
|
53
53
|
let t = typeof e == "number" ? e : Number(e);
|
|
@@ -56,16 +56,16 @@ function x(e, t) {
|
|
|
56
56
|
return t === String ? String(e) : t === Boolean ? !!e : t === Date ? e instanceof Date ? e : i(e) ?? void 0 : e;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
-
function
|
|
59
|
+
function b(e) {
|
|
60
60
|
let t = [e.columns.map((e) => ({
|
|
61
61
|
type: String,
|
|
62
62
|
value: e.header,
|
|
63
|
-
...
|
|
63
|
+
...te
|
|
64
64
|
}))];
|
|
65
65
|
for (let n = 0; n < e.rows.length; n++) {
|
|
66
66
|
let r = e.rows[n], i = [];
|
|
67
67
|
for (let t = 0; t < e.columns.length; t++) {
|
|
68
|
-
let a = e.columns[t], o =
|
|
68
|
+
let a = e.columns[t], o = re(r[a.id], a.type), s = e.getCellStyle?.({
|
|
69
69
|
row: r,
|
|
70
70
|
column: a,
|
|
71
71
|
rowIndex: n,
|
|
@@ -82,20 +82,20 @@ function S(e) {
|
|
|
82
82
|
}
|
|
83
83
|
return t;
|
|
84
84
|
}
|
|
85
|
-
async function
|
|
85
|
+
async function x(e) {
|
|
86
86
|
if (e.sheets.length === 0) throw Error("Для формирования Excel-книги нужен минимум один лист");
|
|
87
|
-
let t =
|
|
88
|
-
let i =
|
|
89
|
-
return n.push(e.autoFilter ?
|
|
87
|
+
let t = y(e.sheets.map((e) => e.name)), n = [], r = e.sheets.map((e, r) => {
|
|
88
|
+
let i = b(e);
|
|
89
|
+
return n.push(e.autoFilter ? _(e.columns.length, i.length) : void 0), {
|
|
90
90
|
data: i,
|
|
91
91
|
sheet: t[r],
|
|
92
92
|
columns: e.columns.map((e) => ({ width: e.width }))
|
|
93
93
|
};
|
|
94
|
-
}), i =
|
|
94
|
+
}), i = v(n);
|
|
95
95
|
await d(r, { features: i ? [i] : void 0 }).toFile(e.fileName);
|
|
96
96
|
}
|
|
97
|
-
async function
|
|
98
|
-
await
|
|
97
|
+
async function S(e) {
|
|
98
|
+
await x({
|
|
99
99
|
fileName: e.fileName,
|
|
100
100
|
sheets: [{
|
|
101
101
|
name: "Sheet1",
|
|
@@ -108,21 +108,21 @@ async function w(e) {
|
|
|
108
108
|
}
|
|
109
109
|
//#endregion
|
|
110
110
|
//#region src/excel/matrixWorkbook.ts
|
|
111
|
-
var
|
|
111
|
+
var C = {
|
|
112
112
|
left: .2,
|
|
113
113
|
right: .2,
|
|
114
114
|
top: .25,
|
|
115
115
|
bottom: .25,
|
|
116
116
|
header: .1,
|
|
117
117
|
footer: .1
|
|
118
|
-
},
|
|
118
|
+
}, w = {
|
|
119
119
|
a4: 9,
|
|
120
120
|
a3: 8
|
|
121
121
|
};
|
|
122
|
-
function
|
|
122
|
+
function T(e) {
|
|
123
123
|
return u(e.replaceAll("&", "&&"));
|
|
124
124
|
}
|
|
125
|
-
function
|
|
125
|
+
function E(e) {
|
|
126
126
|
let t = e, n = "";
|
|
127
127
|
for (; t > 0;) {
|
|
128
128
|
let e = (t - 1) % 26;
|
|
@@ -130,24 +130,27 @@ function D(e) {
|
|
|
130
130
|
}
|
|
131
131
|
return n;
|
|
132
132
|
}
|
|
133
|
-
function
|
|
133
|
+
function D(e, t) {
|
|
134
134
|
if (!Number.isInteger(e) || e <= 0) throw Error(`${t} должен быть положительным целым числом`);
|
|
135
135
|
}
|
|
136
|
+
function O(e, t) {
|
|
137
|
+
if (!Number.isInteger(e) || e < 0) throw Error(`${t} должен быть целым неотрицательным числом`);
|
|
138
|
+
}
|
|
136
139
|
function k(e, t) {
|
|
137
|
-
if (
|
|
140
|
+
if (D(e[0], `${t}: начало`), D(e[1], `${t}: конец`), e[0] > e[1]) throw Error(`${t}: начало не может быть больше конца`);
|
|
138
141
|
}
|
|
139
142
|
function A(e) {
|
|
140
143
|
e.fitToWidthPages !== void 0 && O(e.fitToWidthPages, "fitToWidthPages"), e.fitToHeightPages !== void 0 && O(e.fitToHeightPages, "fitToHeightPages"), e.repeatRows && k(e.repeatRows, "repeatRows"), e.repeatColumns && k(e.repeatColumns, "repeatColumns");
|
|
141
|
-
for (let t of e.columnBreaksAfter ?? [])
|
|
142
|
-
for (let t of e.rowBreaksAfter ?? [])
|
|
143
|
-
if (e.printArea && (
|
|
144
|
+
for (let t of e.columnBreaksAfter ?? []) D(t, "columnBreaksAfter");
|
|
145
|
+
for (let t of e.rowBreaksAfter ?? []) D(t, "rowBreaksAfter");
|
|
146
|
+
if (e.printArea && (D(e.printArea.firstRow, "printArea.firstRow"), D(e.printArea.lastRow, "printArea.lastRow"), D(e.printArea.firstColumn, "printArea.firstColumn"), D(e.printArea.lastColumn, "printArea.lastColumn"), e.printArea.firstRow > e.printArea.lastRow || e.printArea.firstColumn > e.printArea.lastColumn)) throw Error("printArea должен задавать непустой прямоугольник");
|
|
144
147
|
}
|
|
145
148
|
function j(e, t, n) {
|
|
146
149
|
if (!t && !n) return "";
|
|
147
150
|
let r = (e) => e ? [
|
|
148
|
-
e.left ? `&L${
|
|
149
|
-
e.center ? `&C${
|
|
150
|
-
e.right ? `&R${
|
|
151
|
+
e.left ? `&L${T(e.left)}` : "",
|
|
152
|
+
e.center ? `&C${T(e.center)}` : "",
|
|
153
|
+
e.right ? `&R${T(e.right)}` : "",
|
|
151
154
|
e.includePageNumber ? "&RСтраница &P из &N" : ""
|
|
152
155
|
].join("") : "", i = r(t), a = r(n);
|
|
153
156
|
return `<${e}>${i ? `<oddHeader>${i}</oddHeader>` : ""}${a ? `<oddFooter>${a}</oddFooter>` : ""}</${e}>`;
|
|
@@ -158,10 +161,10 @@ function M(e, t) {
|
|
|
158
161
|
return `<${e} count="${n.length}" manualBreakCount="${n.length}">${n.map((e) => `<brk id="${e}" min="0" max="16383" man="1"/>`).join("")}</${e}>`;
|
|
159
162
|
}
|
|
160
163
|
function N(e, t) {
|
|
161
|
-
let n = t.margins ??
|
|
164
|
+
let n = t.margins ?? C, r = t.fitToWidthPages !== void 0 || t.fitToHeightPages !== void 0 ? "<sheetPr><pageSetUpPr fitToPage=\"1\" autoPageBreaks=\"0\"/></sheetPr>" : "", i = r ? e.replace("<sheetViews", `${r}<sheetViews`) : e, a = [
|
|
162
165
|
`<pageMargins left="${n.left}" right="${n.right}" top="${n.top}" bottom="${n.bottom}" header="${n.header}" footer="${n.footer}"/>`,
|
|
163
166
|
`<pageSetup ${[
|
|
164
|
-
`paperSize="${
|
|
167
|
+
`paperSize="${w[t.paperSize ?? "a4"]}"`,
|
|
165
168
|
`orientation="${t.orientation}"`,
|
|
166
169
|
t.fitToWidthPages === void 0 ? "" : `fitToWidth="${t.fitToWidthPages}"`,
|
|
167
170
|
t.fitToHeightPages === void 0 ? "" : `fitToHeight="${t.fitToHeightPages}"`,
|
|
@@ -182,15 +185,18 @@ function F(e, t) {
|
|
|
182
185
|
for (let r = 0; r < t.length; r += 1) {
|
|
183
186
|
let i = t[r]?.print;
|
|
184
187
|
if (!i) continue;
|
|
185
|
-
let a = P(e[r] ?? `Лист ${r + 1}`), o = [i.repeatRows ? `${a}!$${i.repeatRows[0]}:$${i.repeatRows[1]}` : "", i.repeatColumns ? `${a}!$${
|
|
188
|
+
let a = P(e[r] ?? `Лист ${r + 1}`), o = [i.repeatRows ? `${a}!$${i.repeatRows[0]}:$${i.repeatRows[1]}` : "", i.repeatColumns ? `${a}!$${E(i.repeatColumns[0])}:$${E(i.repeatColumns[1])}` : ""].filter(Boolean).join(",");
|
|
186
189
|
if (o && n.push(`<definedName name="_xlnm.Print_Titles" localSheetId="${r}">${u(o)}</definedName>`), i.printArea) {
|
|
187
|
-
let { firstRow: e, lastRow: t, firstColumn: o, lastColumn: s } = i.printArea, c = `${a}!$${
|
|
190
|
+
let { firstRow: e, lastRow: t, firstColumn: o, lastColumn: s } = i.printArea, c = `${a}!$${E(o)}$${e}:$${E(s)}$${t}`;
|
|
188
191
|
n.push(`<definedName name="_xlnm.Print_Area" localSheetId="${r}">${u(c)}</definedName>`);
|
|
189
192
|
}
|
|
190
193
|
}
|
|
191
194
|
return n.join("");
|
|
192
195
|
}
|
|
193
196
|
function I(e, t) {
|
|
197
|
+
return /<definedNames\s*\/>/.test(e) ? e.replace(/<definedNames\s*\/>/, `<definedNames>${t}</definedNames>`) : e.includes("</definedNames>") ? e.replace("</definedNames>", `${t}</definedNames>`) : e.replace("</sheets>", `</sheets><definedNames>${t}</definedNames>`);
|
|
198
|
+
}
|
|
199
|
+
function L(e, t) {
|
|
194
200
|
if (!t.some(({ print: e }) => e)) return;
|
|
195
201
|
let n = F(e, t);
|
|
196
202
|
return { files: { transform: {
|
|
@@ -198,87 +204,87 @@ function I(e, t) {
|
|
|
198
204
|
let i = t[r.sheetIndex]?.print;
|
|
199
205
|
return i ? N(e, i) : e;
|
|
200
206
|
} },
|
|
201
|
-
"xl/workbook.xml": { transform: (e) => n ? e
|
|
207
|
+
"xl/workbook.xml": { transform: (e) => n ? I(e, n) : e }
|
|
202
208
|
} } };
|
|
203
209
|
}
|
|
204
|
-
async function
|
|
210
|
+
async function R(e) {
|
|
205
211
|
if (e.sheets.length === 0) throw Error("Для формирования Excel-книги нужен минимум один лист");
|
|
206
212
|
for (let t of e.sheets) {
|
|
207
213
|
if (t.rows.length === 0) throw Error(`Лист «${t.name}» не содержит строк`);
|
|
208
214
|
t.print && A(t.print);
|
|
209
215
|
}
|
|
210
|
-
let t =
|
|
216
|
+
let t = y(e.sheets.map(({ name: e }) => e)), n = e.sheets.map((e, n) => ({
|
|
211
217
|
data: e.rows.map((e) => [...e]),
|
|
212
218
|
sheet: t[n],
|
|
213
219
|
columns: e.columns?.map((e) => ({ width: e.width })),
|
|
214
220
|
showGridLines: e.showGridLines,
|
|
215
221
|
zoomScale: e.zoomScale
|
|
216
|
-
})), r =
|
|
222
|
+
})), r = L(t, e.sheets);
|
|
217
223
|
return d(n, { features: r ? [r] : void 0 }).toBlob();
|
|
218
224
|
}
|
|
219
|
-
async function
|
|
220
|
-
let r = await
|
|
225
|
+
async function z(t, n) {
|
|
226
|
+
let r = await R(n);
|
|
221
227
|
e(t, r);
|
|
222
228
|
}
|
|
223
229
|
//#endregion
|
|
224
230
|
//#region src/excel/tableExport.ts
|
|
225
|
-
var
|
|
226
|
-
function
|
|
231
|
+
var B = "#,##0", V = "#,##0.0", H = "dd.mm.yyyy", U = "dd.mm", ie = "d mmm", W = "d mmmm", G = "mmm yyyy", K = "mmmm yyyy", q = "hh:mm", J = "hh:mm:ss", Y = `${H} ${q}`, X = `${H} ${J}`;
|
|
232
|
+
function Z(e) {
|
|
227
233
|
let t = l(e).plan?.steps.find((e) => e.type === "typedValueFormat");
|
|
228
234
|
return t?.type === "typedValueFormat" ? t.config : void 0;
|
|
229
235
|
}
|
|
230
|
-
function
|
|
236
|
+
function Q(e) {
|
|
231
237
|
return e.clientOnly ? Number : n(e.odataType) ? Date : a(e.odataType) ? Boolean : o(e.odataType) || e.role === "measure" ? Number : String;
|
|
232
238
|
}
|
|
233
|
-
function ie(e) {
|
|
234
|
-
let t = X(e.formattersPipeline)?.numberPresetName?.trim();
|
|
235
|
-
return t && c(t) ? t : r(e.odataType) ? "integer" : "decimal";
|
|
236
|
-
}
|
|
237
239
|
function ae(e) {
|
|
238
|
-
let t =
|
|
239
|
-
return t
|
|
240
|
+
let t = Z(e.formattersPipeline)?.numberPresetName?.trim();
|
|
241
|
+
return t && c(t) ? t : r(e.odataType) ? "integer" : "decimal";
|
|
240
242
|
}
|
|
241
243
|
function oe(e) {
|
|
242
|
-
|
|
244
|
+
let t = c(ae(e));
|
|
245
|
+
return t ? t.decimals > 0 ? `#,##0.${"0".repeat(t.decimals)}` : B : V;
|
|
243
246
|
}
|
|
244
|
-
function
|
|
245
|
-
return e.
|
|
247
|
+
function se(e) {
|
|
248
|
+
return Z(e.formattersPipeline)?.datePresetName?.trim() || (e.odataType === "time" ? s.time : e.odataType === "datetime" || e.odataType === "datetimeOffset" ? s.datetime : s.date);
|
|
246
249
|
}
|
|
247
250
|
function $(e) {
|
|
248
|
-
|
|
249
|
-
if (e === s.odataDate || e === s.abapDate) return V;
|
|
250
|
-
if (e === s.monthShort) return H;
|
|
251
|
-
if (e === s.monthMedium) return U;
|
|
252
|
-
if (e === s.monthLong) return re;
|
|
253
|
-
if (e === s.monthYearMedium) return W;
|
|
254
|
-
if (e === s.monthYearLong) return G;
|
|
255
|
-
if (e.startsWith("datetime")) return e === s.datetime || e === s.datetimeShort ? J : Y;
|
|
256
|
-
if (e.startsWith("time")) return e === s.time || e === s.timeShort ? K : q;
|
|
257
|
-
if (e.startsWith("date")) return V;
|
|
258
|
-
}
|
|
259
|
-
function se(e, t) {
|
|
260
|
-
return $(e) || (t?.pattern ? Q(t.pattern) : Q(e));
|
|
251
|
+
return e.replace(/H/g, "h").replace(/M/g, "m");
|
|
261
252
|
}
|
|
262
253
|
function ce(e) {
|
|
263
|
-
|
|
264
|
-
|
|
254
|
+
if (e === s.odataDatetime || e === s.abapDatetime) return X;
|
|
255
|
+
if (e === s.odataDate || e === s.abapDate) return H;
|
|
256
|
+
if (e === s.monthShort) return U;
|
|
257
|
+
if (e === s.monthMedium) return ie;
|
|
258
|
+
if (e === s.monthLong) return W;
|
|
259
|
+
if (e === s.monthYearMedium) return G;
|
|
260
|
+
if (e === s.monthYearLong) return K;
|
|
261
|
+
if (e.startsWith("datetime")) return e === s.datetime || e === s.datetimeShort ? Y : X;
|
|
262
|
+
if (e.startsWith("time")) return e === s.time || e === s.timeShort ? q : J;
|
|
263
|
+
if (e.startsWith("date")) return H;
|
|
265
264
|
}
|
|
266
265
|
function le(e, t) {
|
|
267
|
-
|
|
268
|
-
if (t === Date) return ce(e);
|
|
266
|
+
return ce(e) || (t?.pattern ? $(t.pattern) : $(e));
|
|
269
267
|
}
|
|
270
268
|
function ue(e) {
|
|
271
|
-
let
|
|
269
|
+
let n = se(e);
|
|
270
|
+
return le(n, t(n));
|
|
271
|
+
}
|
|
272
|
+
function de(e, t) {
|
|
273
|
+
if (t === Number) return oe(e);
|
|
274
|
+
if (t === Date) return ue(e);
|
|
275
|
+
}
|
|
276
|
+
function fe(e) {
|
|
277
|
+
let t = Q(e);
|
|
272
278
|
return {
|
|
273
279
|
id: e.id,
|
|
274
280
|
header: e.header,
|
|
275
281
|
width: e.width,
|
|
276
282
|
type: t,
|
|
277
|
-
format:
|
|
283
|
+
format: de(e, t)
|
|
278
284
|
};
|
|
279
285
|
}
|
|
280
|
-
async function
|
|
281
|
-
await
|
|
286
|
+
async function pe({ fileName: e, table: t, autoFilter: n = !0 }) {
|
|
287
|
+
await S({
|
|
282
288
|
fileName: e,
|
|
283
289
|
columns: t.columns,
|
|
284
290
|
rows: t.rows,
|
|
@@ -286,8 +292,8 @@ async function de({ fileName: e, table: t, autoFilter: n = !0 }) {
|
|
|
286
292
|
getCellStyle: ({ rowIndex: e, column: n }) => t.cellStyles?.[e]?.[n.id]
|
|
287
293
|
});
|
|
288
294
|
}
|
|
289
|
-
async function
|
|
290
|
-
await
|
|
295
|
+
async function me({ fileName: e, sheets: t }) {
|
|
296
|
+
await x({
|
|
291
297
|
fileName: e,
|
|
292
298
|
sheets: t.map(({ name: e, table: t, autoFilter: n = !0 }) => ({
|
|
293
299
|
name: e,
|
|
@@ -299,6 +305,6 @@ async function fe({ fileName: e, sheets: t }) {
|
|
|
299
305
|
});
|
|
300
306
|
}
|
|
301
307
|
//#endregion
|
|
302
|
-
export {
|
|
308
|
+
export { _ as buildExcelAutoFilterRef, b as buildExcelSheetData, R as createExcelMatrixWorkbookBlob, fe as createTableExcelColumn, S as downloadExcelFile, z as downloadExcelMatrixWorkbook, x as downloadExcelWorkbook, pe as downloadResolvedExcelTable, me as downloadResolvedExcelWorkbook, h as resolveExcelCellStyleFromState, y as resolveExcelSheetNames, Q as resolveTableExcelColumnType };
|
|
303
309
|
|
|
304
310
|
//# sourceMappingURL=index.js.map
|
package/dist/excel/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excel.ts","../../src/excel/matrixWorkbook.ts","../../src/excel/tableExport.ts"],"sourcesContent":["import writeXlsxFile, { type Cell, type CellObject, type Feature, type Sheet, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\n/** Описание одного табличного листа внутри Excel-книги. */\nexport type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, \"fileName\"> & {\n\t/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */\n\tname: string;\n};\n\n/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */\nexport type DownloadExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Листы книги в порядке отображения в Excel. */\n\tsheets: ExcelWorkbookSheet[];\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_INVALID_CHARACTERS = /[\\u0000-\\u001f[\\]/\\\\:*?]+/g;\nconst EXCEL_SHEET_NAME_EDGE_APOSTROPHES = /^'+|'+$/g;\nconst EXCEL_SHEET_NAME_WHITESPACE = /\\s+/g;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tout = String.fromCharCode(65 + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(refs: readonly (string | undefined)[]): Feature<FileContent> | undefined {\n\tif (!refs.some(Boolean)) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst ref = refs[properties.sheetIndex];\n\t\t\t\t\t\treturn ref ? content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`) : content;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Нормализует имена листов по ограничениям Excel и делает их уникальными.\n *\n * Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или\n * совпадать между несколькими представлениями одной конфигурации. Нормализация\n * выполняется централизованно, чтобы все consumers получали открываемую книгу.\n */\nexport function resolveExcelSheetNames(names: readonly string[]): string[] {\n\tconst usedNames = new Set<string>();\n\tconst resolvedNames: string[] = [];\n\n\tfor (let index = 0; index < names.length; index += 1) {\n\t\tconst fallbackName = `Лист ${index + 1}`;\n\t\tconst normalizedName = names[index]\n\t\t\t?.replace(EXCEL_SHEET_NAME_INVALID_CHARACTERS, \" \")\n\t\t\t.replace(EXCEL_SHEET_NAME_WHITESPACE, \" \")\n\t\t\t.trim()\n\t\t\t.replace(EXCEL_SHEET_NAME_EDGE_APOSTROPHES, \"\")\n\t\t\t.trim();\n\t\tconst baseName = normalizedName || fallbackName;\n\t\tlet resolvedName = baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n\t\tlet duplicateIndex = 2;\n\n\t\twhile (usedNames.has(resolvedName.toLocaleLowerCase())) {\n\t\t\tconst suffix = ` (${duplicateIndex})`;\n\t\t\tresolvedName = `${baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;\n\t\t\tduplicateIndex += 1;\n\t\t}\n\n\t\tusedNames.add(resolvedName.toLocaleLowerCase());\n\t\tresolvedNames.push(resolvedName);\n\t}\n\n\treturn resolvedNames;\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает Excel-книгу с независимыми табличными листами.\n *\n * Каждый лист получает собственные ширины колонок, стили ячеек и диапазон\n * автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.\n */\nexport async function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void> {\n\tif (args.sheets.length === 0) {\n\t\tthrow new Error(\"Для формирования Excel-книги нужен минимум один лист\");\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map((sheet) => sheet.name));\n\tconst autoFilterRefs: Array<string | undefined> = [];\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => {\n\t\tconst data = buildExcelSheetData(sheet);\n\t\tautoFilterRefs.push(sheet.autoFilter ? buildExcelAutoFilterRef(sheet.columns.length, data.length) : undefined);\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tsheet: sheetNames[index],\n\t\t\tcolumns: sheet.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t};\n\t});\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRefs);\n\n\tawait writeXlsxFile(sheets, {\n\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t}).toFile(args.fileName);\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName: args.fileName,\n\t\tsheets: [\n\t\t\t{\n\t\t\t\tname: \"Sheet1\",\n\t\t\t\tcolumns: args.columns,\n\t\t\t\trows: args.rows,\n\t\t\t\tautoFilter: args.autoFilter,\n\t\t\t\tgetCellStyle: args.getCellStyle\n\t\t\t}\n\t\t]\n\t});\n}\n","import writeXlsxFile, { type Cell, type Feature, type Sheet } from \"write-excel-file/browser\";\n\nimport { downloadFileFromBlob } from \"../dom\";\nimport { escapeXmlValue } from \"../xml\";\n\nimport { resolveExcelSheetNames } from \"./excel\";\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\n/** Одна строка произвольной Excel-матрицы. Объединения задаются стилями первой ячейки диапазона. */\nexport type ExcelMatrixRow = readonly Cell[];\n\n/** Поля задаются в дюймах, как в OpenXML и диалоге параметров страницы Excel. */\nexport type ExcelPrintMargins = {\n\treadonly left: number;\n\treadonly right: number;\n\treadonly top: number;\n\treadonly bottom: number;\n\treadonly header: number;\n\treadonly footer: number;\n};\n\n/** Видимый колонтитул не принимает raw Excel-коды, чтобы текст не мог случайно изменить разметку секций. */\nexport type ExcelPrintHeaderFooter = {\n\treadonly left?: string;\n\treadonly center?: string;\n\treadonly right?: string;\n\treadonly includePageNumber?: boolean;\n};\n\n/** One-based прямоугольник печати соответствует координатам строк и столбцов Excel. */\nexport type ExcelPrintArea = {\n\treadonly firstRow: number;\n\treadonly lastRow: number;\n\treadonly firstColumn: number;\n\treadonly lastColumn: number;\n};\n\n/**\n * Печатный контракт одного листа.\n *\n * `columnBreaksAfter` и `rowBreaksAfter` используют one-based координату\n * последней ячейки страницы. Явная модель не позволяет consumer перепутать\n * индекс массива с адресом Excel и разрезать составной блок на печати.\n */\nexport type ExcelPrintSetup = {\n\treadonly orientation: \"portrait\" | \"landscape\";\n\treadonly paperSize?: \"a4\" | \"a3\";\n\treadonly fitToWidthPages?: number;\n\treadonly fitToHeightPages?: number;\n\treadonly pageOrder?: \"downThenOver\" | \"overThenDown\";\n\treadonly margins?: ExcelPrintMargins;\n\treadonly repeatRows?: readonly [firstRow: number, lastRow: number];\n\treadonly repeatColumns?: readonly [firstColumn: number, lastColumn: number];\n\treadonly printArea?: ExcelPrintArea;\n\treadonly columnBreaksAfter?: readonly number[];\n\treadonly rowBreaksAfter?: readonly number[];\n\treadonly header?: ExcelPrintHeaderFooter;\n\treadonly footer?: ExcelPrintHeaderFooter;\n};\n\n/** Произвольный лист сохраняет готовую матрицу и не навязывает табличную строку заголовков. */\nexport type ExcelMatrixWorkbookSheet = {\n\treadonly name: string;\n\treadonly rows: readonly ExcelMatrixRow[];\n\treadonly columns?: readonly { readonly width?: number }[];\n\treadonly showGridLines?: boolean;\n\treadonly zoomScale?: number;\n\treadonly print?: ExcelPrintSetup;\n};\n\n/** Аргументы generic-книги, пригодной как для скачивания, так и для file validation. */\nexport type ExcelMatrixWorkbookArgs = {\n\treadonly sheets: readonly ExcelMatrixWorkbookSheet[];\n};\n\nconst DEFAULT_PRINT_MARGINS = {\n\tleft: 0.2,\n\tright: 0.2,\n\ttop: 0.25,\n\tbottom: 0.25,\n\theader: 0.1,\n\tfooter: 0.1\n} as const satisfies ExcelPrintMargins;\n\nconst PAPER_SIZE = { a4: 9, a3: 8 } as const;\n\nfunction escapeHeaderFooterText(value: string): string {\n\treturn escapeXmlValue(value.replaceAll(\"&\", \"&&\"));\n}\n\nfunction numberToColumnName(index: number): string {\n\tlet value = index;\n\tlet result = \"\";\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tresult = String.fromCharCode(65 + remainder) + result;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\treturn result;\n}\n\nfunction assertPositiveInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value <= 0) throw new Error(`${name} должен быть положительным целым числом`);\n}\n\nfunction validateRange(range: readonly [number, number], name: string): void {\n\tassertPositiveInteger(range[0], `${name}: начало`);\n\tassertPositiveInteger(range[1], `${name}: конец`);\n\tif (range[0] > range[1]) throw new Error(`${name}: начало не может быть больше конца`);\n}\n\nfunction validatePrintSetup(print: ExcelPrintSetup): void {\n\tif (print.fitToWidthPages !== undefined) assertPositiveInteger(print.fitToWidthPages, \"fitToWidthPages\");\n\tif (print.fitToHeightPages !== undefined) assertPositiveInteger(print.fitToHeightPages, \"fitToHeightPages\");\n\tif (print.repeatRows) validateRange(print.repeatRows, \"repeatRows\");\n\tif (print.repeatColumns) validateRange(print.repeatColumns, \"repeatColumns\");\n\tfor (const value of print.columnBreaksAfter ?? []) assertPositiveInteger(value, \"columnBreaksAfter\");\n\tfor (const value of print.rowBreaksAfter ?? []) assertPositiveInteger(value, \"rowBreaksAfter\");\n\tif (print.printArea) {\n\t\tassertPositiveInteger(print.printArea.firstRow, \"printArea.firstRow\");\n\t\tassertPositiveInteger(print.printArea.lastRow, \"printArea.lastRow\");\n\t\tassertPositiveInteger(print.printArea.firstColumn, \"printArea.firstColumn\");\n\t\tassertPositiveInteger(print.printArea.lastColumn, \"printArea.lastColumn\");\n\t\tif (print.printArea.firstRow > print.printArea.lastRow || print.printArea.firstColumn > print.printArea.lastColumn) {\n\t\t\tthrow new Error(\"printArea должен задавать непустой прямоугольник\");\n\t\t}\n\t}\n}\n\nfunction buildHeaderFooterXml(\n\ttagName: \"headerFooter\",\n\theader: ExcelPrintHeaderFooter | undefined,\n\tfooter: ExcelPrintHeaderFooter | undefined\n): string {\n\tif (!header && !footer) return \"\";\n\tconst buildSection = (value: ExcelPrintHeaderFooter | undefined) => {\n\t\tif (!value) return \"\";\n\t\tconst content = [\n\t\t\tvalue.left ? `&L${escapeHeaderFooterText(value.left)}` : \"\",\n\t\t\tvalue.center ? `&C${escapeHeaderFooterText(value.center)}` : \"\",\n\t\t\tvalue.right ? `&R${escapeHeaderFooterText(value.right)}` : \"\",\n\t\t\tvalue.includePageNumber ? \"&RСтраница &P из &N\" : \"\"\n\t\t].join(\"\");\n\t\treturn content;\n\t};\n\tconst oddHeader = buildSection(header);\n\tconst oddFooter = buildSection(footer);\n\treturn `<${tagName}>${oddHeader ? `<oddHeader>${oddHeader}</oddHeader>` : \"\"}${oddFooter ? `<oddFooter>${oddFooter}</oddFooter>` : \"\"}</${tagName}>`;\n}\n\nfunction buildBreaksXml(tagName: \"colBreaks\" | \"rowBreaks\", values: readonly number[] | undefined): string {\n\tif (!values || values.length === 0) return \"\";\n\tconst uniqueValues = [...new Set(values)].sort((left, right) => left - right);\n\treturn `<${tagName} count=\"${uniqueValues.length}\" manualBreakCount=\"${uniqueValues.length}\">${uniqueValues\n\t\t.map((value) => `<brk id=\"${value}\" min=\"0\" max=\"16383\" man=\"1\"/>`)\n\t\t.join(\"\")}</${tagName}>`;\n}\n\nfunction applyWorksheetPrintSetup(content: string, print: ExcelPrintSetup): string {\n\tconst margins = print.margins ?? DEFAULT_PRINT_MARGINS;\n\tconst fitToPage = print.fitToWidthPages !== undefined || print.fitToHeightPages !== undefined;\n\tconst sheetProperties = fitToPage ? '<sheetPr><pageSetUpPr fitToPage=\"1\" autoPageBreaks=\"0\"/></sheetPr>' : \"\";\n\tconst result = sheetProperties ? content.replace(\"<sheetViews\", `${sheetProperties}<sheetViews`) : content;\n\tconst pageMargins = `<pageMargins left=\"${margins.left}\" right=\"${margins.right}\" top=\"${margins.top}\" bottom=\"${margins.bottom}\" header=\"${margins.header}\" footer=\"${margins.footer}\"/>`;\n\tconst pageSetupAttributes = [\n\t\t`paperSize=\"${PAPER_SIZE[print.paperSize ?? \"a4\"]}\"`,\n\t\t`orientation=\"${print.orientation}\"`,\n\t\tprint.fitToWidthPages !== undefined ? `fitToWidth=\"${print.fitToWidthPages}\"` : \"\",\n\t\tprint.fitToHeightPages !== undefined ? `fitToHeight=\"${print.fitToHeightPages}\"` : \"\",\n\t\tprint.pageOrder ? `pageOrder=\"${print.pageOrder}\"` : \"\",\n\t\t'usePrinterDefaults=\"0\"'\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n\tconst additions = [\n\t\tpageMargins,\n\t\t`<pageSetup ${pageSetupAttributes}/>`,\n\t\tbuildHeaderFooterXml(\"headerFooter\", print.header, print.footer),\n\t\tbuildBreaksXml(\"rowBreaks\", print.rowBreaksAfter),\n\t\tbuildBreaksXml(\"colBreaks\", print.columnBreaksAfter)\n\t].join(\"\");\n\tconst drawingIndex = result.indexOf(\"<drawing\");\n\treturn drawingIndex >= 0\n\t\t? `${result.slice(0, drawingIndex)}${additions}${result.slice(drawingIndex)}`\n\t\t: result.replace(\"</worksheet>\", `${additions}</worksheet>`);\n}\n\nfunction quoteFormulaSheetName(name: string): string {\n\treturn `'${name.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction buildDefinedNames(sheetNames: readonly string[], sheets: readonly ExcelMatrixWorkbookSheet[]): string {\n\tconst definitions: string[] = [];\n\tfor (let sheetIndex = 0; sheetIndex < sheets.length; sheetIndex += 1) {\n\t\tconst print = sheets[sheetIndex]?.print;\n\t\tif (!print) continue;\n\t\tconst sheetName = quoteFormulaSheetName(sheetNames[sheetIndex] ?? `Лист ${sheetIndex + 1}`);\n\t\tconst titles = [\n\t\t\tprint.repeatRows ? `${sheetName}!$${print.repeatRows[0]}:$${print.repeatRows[1]}` : \"\",\n\t\t\tprint.repeatColumns\n\t\t\t\t? `${sheetName}!$${numberToColumnName(print.repeatColumns[0])}:$${numberToColumnName(print.repeatColumns[1])}`\n\t\t\t\t: \"\"\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\",\");\n\t\tif (titles) {\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Titles\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(titles)}</definedName>`);\n\t\t}\n\t\tif (print.printArea) {\n\t\t\tconst { firstRow, lastRow, firstColumn, lastColumn } = print.printArea;\n\t\t\tconst area = `${sheetName}!$${numberToColumnName(firstColumn)}$${firstRow}:$${numberToColumnName(lastColumn)}$${lastRow}`;\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Area\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(area)}</definedName>`);\n\t\t}\n\t}\n\treturn definitions.join(\"\");\n}\n\n/** Настройки печати требуют двух согласованных OpenXML-частей: worksheet и workbook defined names. */\nfunction createMatrixPrintFeature(\n\tsheetNames: readonly string[],\n\tsheets: readonly ExcelMatrixWorkbookSheet[]\n): Feature<BrowserExcelFileContent> | undefined {\n\tif (!sheets.some(({ print }) => print)) return undefined;\n\tconst definedNames = buildDefinedNames(sheetNames, sheets);\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst setup = sheets[properties.sheetIndex]?.print;\n\t\t\t\t\t\treturn setup ? applyWorksheetPrintSetup(content, setup) : content;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"xl/workbook.xml\": {\n\t\t\t\t\ttransform: (content) =>\n\t\t\t\t\t\tdefinedNames ? content.replace(\"</sheets>\", `</sheets><definedNames>${definedNames}</definedNames>`) : content\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Формирует Blob без побочного эффекта скачивания.\n *\n * Этот вход нужен предпросмотру, file validation и сценариям, где download\n * выполняет отдельный browser-owner. KTK-specific layout сюда не передаётся.\n */\nexport async function createExcelMatrixWorkbookBlob(args: ExcelMatrixWorkbookArgs): Promise<Blob> {\n\tif (args.sheets.length === 0) throw new Error(\"Для формирования Excel-книги нужен минимум один лист\");\n\tfor (const sheet of args.sheets) {\n\t\tif (sheet.rows.length === 0) throw new Error(`Лист «${sheet.name}» не содержит строк`);\n\t\tif (sheet.print) validatePrintSetup(sheet.print);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map(({ name }) => name));\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => ({\n\t\tdata: sheet.rows.map((row) => [...row]),\n\t\tsheet: sheetNames[index],\n\t\tcolumns: sheet.columns?.map((column) => ({ width: column.width })),\n\t\tshowGridLines: sheet.showGridLines,\n\t\tzoomScale: sheet.zoomScale\n\t}));\n\tconst printFeature = createMatrixPrintFeature(sheetNames, args.sheets);\n\treturn writeXlsxFile(sheets, { features: printFeature ? [printFeature] : undefined }).toBlob();\n}\n\n/** Скачивает готовую матричную книгу из явного пользовательского действия. */\nexport async function downloadExcelMatrixWorkbook(fileName: string, args: ExcelMatrixWorkbookArgs): Promise<void> {\n\tconst blob = await createExcelMatrixWorkbookBlob(args);\n\tdownloadFileFromBlob(fileName, blob);\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { getNumberPreset } from \"../formatters/number\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport {\n\tisODataBooleanType,\n\tisODataDateType,\n\tisODataIntegerType,\n\tisODataNumericType,\n\ttype ColumnRole,\n\ttype ODataMetaType\n} from \"../odata-service\";\n\nimport { downloadExcelFile, downloadExcelWorkbook, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ODataMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\n/** Один подготовленный табличный лист generic Excel-книги. */\nexport type ResolvedExcelWorkbookSheet = {\n\t/** Желаемое имя листа. */\n\tname: string;\n\t/** Подготовленные колонки, строки и optional стили ячеек. */\n\ttable: ResolvedExcelTable;\n\t/** Включить автофильтр для этого листа. По умолчанию включён. */\n\tautoFilter?: boolean;\n};\n\n/** Аргументы скачивания книги из нескольких подготовленных таблиц. */\nexport type DownloadResolvedExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Табличные листы в порядке отображения в книге. */\n\tsheets: ResolvedExcelWorkbookSheet[];\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\n/**\n * Excel-маски календарных пресетов сохраняют экранную детализацию:\n * month-* выводит день и месяц без года, а month-year-* — месяц и год без дня.\n */\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"dd.mm\";\nconst EXCEL_DAY_MONTH_MEDIUM_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_MONTH_YEAR_MEDIUM_FORMAT = \"mmm yyyy\";\nconst EXCEL_MONTH_YEAR_LONG_FORMAT = \"mmmm yyyy\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === \"typedValueFormat\");\n\n\treturn typedValueFormatStep?.type === \"typedValueFormat\" ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isODataDateType(descriptor.odataType)) return Date;\n\tif (isODataBooleanType(descriptor.odataType)) return Boolean;\n\tif (isODataNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === \"measure\") return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isODataIntegerType(descriptor.odataType)) return \"integer\";\n\treturn \"decimal\";\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\treturn preset.decimals > 0 ? `#,##0.${\"0\".repeat(preset.decimals)}` : INTEGER_EXCEL_FORMAT;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === \"time\") return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === \"datetime\" || descriptor.odataType === \"datetimeOffset\") return DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthMedium) {\n\t\treturn EXCEL_DAY_MONTH_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearMedium) {\n\t\treturn EXCEL_MONTH_YEAR_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearLong) {\n\t\treturn EXCEL_MONTH_YEAR_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"datetime\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"time\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"date\")) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n\n/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */\nexport async function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName,\n\t\tsheets: sheets.map(({ name, table, autoFilter = true }) => ({\n\t\t\tname,\n\t\t\tcolumns: table.columns,\n\t\t\trows: table.rows,\n\t\t\tautoFilter,\n\t\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t\t}))\n\t});\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/excel/excel.ts","../../src/excel/matrixWorkbook.ts","../../src/excel/tableExport.ts"],"sourcesContent":["import writeXlsxFile, { type Cell, type CellObject, type Feature, type Sheet, type SheetData } from \"write-excel-file/browser\";\n\nimport { parseDate } from \"../formatters/date\";\nimport { type State } from \"../types\";\n\nexport type ExcelColumn = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\ttype?: StringConstructor | NumberConstructor | DateConstructor | BooleanConstructor;\n\tformat?: string;\n};\n\nexport type ExcelRow = Record<string, unknown>;\n\nexport type ExcelCellStyle = Omit<CellObject, \"value\" | \"type\" | \"format\">;\n\nexport type DownloadExcelFileArgs = {\n\tfileName: string;\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tautoFilter?: boolean;\n\tgetCellStyle?: (args: { row: ExcelRow; column: ExcelColumn; rowIndex: number; columnIndex: number }) => ExcelCellStyle | undefined;\n};\n\n/** Описание одного табличного листа внутри Excel-книги. */\nexport type ExcelWorkbookSheet = Omit<DownloadExcelFileArgs, \"fileName\"> & {\n\t/** Желаемое имя листа; writer нормализует ограничения формата и конфликты имён. */\n\tname: string;\n};\n\n/** Аргументы формирования Excel-книги с одним или несколькими табличными листами. */\nexport type DownloadExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Листы книги в порядке отображения в Excel. */\n\tsheets: ExcelWorkbookSheet[];\n};\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\nconst VALUE_STATE_TEXT_COLORS: Partial<Record<State, string>> = {\n\tinformation: \"#2563EB\",\n\tsuccess: \"#107C10\",\n\twarning: \"#B7791F\",\n\terror: \"#C50F1F\"\n};\n\nconst HEADER_CELL_STYLE = {\n\tfontWeight: \"bold\",\n\tbottomBorderStyle: \"thin\",\n\tbottomBorderColor: \"#D9D9D9\"\n} satisfies ExcelCellStyle;\n\nconst EXCEL_SHEET_NAME_MAX_LENGTH = 31;\nconst EXCEL_SHEET_NAME_INVALID_CHARACTERS = /[\\u0000-\\u001f[\\]/\\\\:*?]+/g;\nconst EXCEL_SHEET_NAME_EDGE_APOSTROPHES = /^'+|'+$/g;\nconst EXCEL_SHEET_NAME_WHITESPACE = /\\s+/g;\n\n/**\n * Приводит общий value-state проекта к базовому Excel-стилю.\n *\n * Helper живет в shared Excel-слое, чтобы analytical/detail экспорт не\n * дублировали палитру статусов и одинаково подсвечивали warning/error/success.\n */\nexport function resolveExcelCellStyleFromState(state: State | undefined): ExcelCellStyle | undefined {\n\tconst textColor = state ? VALUE_STATE_TEXT_COLORS[state] : undefined;\n\treturn textColor ? { textColor } : undefined;\n}\n\n/**\n * Переводит zero-based индекс колонки в Excel-адрес (`0 -> A`, `27 -> AB`).\n * Нужен для XML-диапазонов, потому что `write-excel-file` не предоставляет\n * отдельного API для построения ссылок вида `A1:C10`.\n */\nfunction numberToColumnName(index: number): string {\n\tlet value = index + 1;\n\tlet out = \"\";\n\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tout = String.fromCharCode(65 + remainder) + out;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\n\treturn out;\n}\n\n/**\n * Строит диапазон автофильтра для всей выгруженной таблицы.\n *\n * Возвращает `undefined` для пустой сетки, чтобы не вставлять в xlsx\n * невалидный `<autoFilter>` без реального диапазона.\n */\nexport function buildExcelAutoFilterRef(columnCount: number, rowCount: number): string | undefined {\n\tif (columnCount <= 0 || rowCount <= 0) return undefined;\n\n\treturn `A1:${numberToColumnName(columnCount - 1)}${rowCount}`;\n}\n\n/**\n * Добавляет autoFilter через feature-transform `write-excel-file`.\n *\n * Библиотека умеет трансформировать XML листа, но не имеет высокоуровневого\n * параметра `autoFilter`, поэтому здесь изолирован низкоуровневый OpenXML-хук.\n */\nfunction createAutoFilterFeature<FileContent>(refs: readonly (string | undefined)[]): Feature<FileContent> | undefined {\n\tif (!refs.some(Boolean)) return undefined;\n\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst ref = refs[properties.sheetIndex];\n\t\t\t\t\t\treturn ref ? content.replace(\"</sheetData>\", `</sheetData><autoFilter ref=\"${ref}\"/>`) : content;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Нормализует имена листов по ограничениям Excel и делает их уникальными.\n *\n * Runtime-заголовки могут содержать запрещённые символы, превышать 31 знак или\n * совпадать между несколькими представлениями одной конфигурации. Нормализация\n * выполняется централизованно, чтобы все consumers получали открываемую книгу.\n */\nexport function resolveExcelSheetNames(names: readonly string[]): string[] {\n\tconst usedNames = new Set<string>();\n\tconst resolvedNames: string[] = [];\n\n\tfor (let index = 0; index < names.length; index += 1) {\n\t\tconst fallbackName = `Лист ${index + 1}`;\n\t\tconst normalizedName = names[index]\n\t\t\t?.replace(EXCEL_SHEET_NAME_INVALID_CHARACTERS, \" \")\n\t\t\t.replace(EXCEL_SHEET_NAME_WHITESPACE, \" \")\n\t\t\t.trim()\n\t\t\t.replace(EXCEL_SHEET_NAME_EDGE_APOSTROPHES, \"\")\n\t\t\t.trim();\n\t\tconst baseName = normalizedName || fallbackName;\n\t\tlet resolvedName = baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH);\n\t\tlet duplicateIndex = 2;\n\n\t\twhile (usedNames.has(resolvedName.toLocaleLowerCase())) {\n\t\t\tconst suffix = ` (${duplicateIndex})`;\n\t\t\tresolvedName = `${baseName.slice(0, EXCEL_SHEET_NAME_MAX_LENGTH - suffix.length)}${suffix}`;\n\t\t\tduplicateIndex += 1;\n\t\t}\n\n\t\tusedNames.add(resolvedName.toLocaleLowerCase());\n\t\tresolvedNames.push(resolvedName);\n\t}\n\n\treturn resolvedNames;\n}\n\n/**\n * Приводит входное значение к типу Excel-ячейки.\n *\n * Важный смысл: если колонка числовая, в файл должен попасть настоящий Number,\n * а не уже отформатированная строка. Тогда Excel сможет применять `format`.\n */\nfunction normalizeCellValue(value: unknown, type: ExcelColumn[\"type\"]) {\n\tif (value == null || value === \"\") return undefined;\n\n\tif (type === Number) {\n\t\tconst numberValue = typeof value === \"number\" ? value : Number(value);\n\t\treturn Number.isFinite(numberValue) ? numberValue : undefined;\n\t}\n\n\tif (type === String) return String(value);\n\tif (type === Boolean) return Boolean(value);\n\tif (type === Date) return value instanceof Date ? value : (parseDate(value) ?? undefined);\n\n\treturn value as CellObject[\"value\"];\n}\n\n/**\n * Собирает SheetData для `write-excel-file`.\n *\n * Функция намеренно не знает о бизнес-сущностях: ей передают уже готовые\n * колонки/строки и необязательный callback стилей конкретных ячеек.\n */\nexport function buildExcelSheetData(args: Omit<DownloadExcelFileArgs, \"fileName\" | \"autoFilter\">): SheetData {\n\tconst headerRow: Cell[] = args.columns.map((column) => ({\n\t\ttype: String,\n\t\tvalue: column.header,\n\t\t...HEADER_CELL_STYLE\n\t}));\n\n\tconst sheetRows: SheetData = [headerRow];\n\n\tfor (let rowIndex = 0; rowIndex < args.rows.length; rowIndex++) {\n\t\tconst row = args.rows[rowIndex];\n\t\tconst sheetRow: Cell[] = [];\n\n\t\tfor (let columnIndex = 0; columnIndex < args.columns.length; columnIndex++) {\n\t\t\tconst column = args.columns[columnIndex];\n\t\t\tconst value = normalizeCellValue(row[column.id], column.type);\n\t\t\tconst style = args.getCellStyle?.({ row, column, rowIndex, columnIndex });\n\n\t\t\tsheetRow.push({\n\t\t\t\tvalue,\n\t\t\t\ttype: column.type,\n\t\t\t\tformat: column.format,\n\t\t\t\t...style\n\t\t\t});\n\t\t}\n\n\t\tsheetRows.push(sheetRow);\n\t}\n\n\treturn sheetRows;\n}\n\n/**\n * Формирует и скачивает Excel-книгу с независимыми табличными листами.\n *\n * Каждый лист получает собственные ширины колонок, стили ячеек и диапазон\n * автофильтра. Доменная подготовка колонок и строк остаётся у вызывающей стороны.\n */\nexport async function downloadExcelWorkbook(args: DownloadExcelWorkbookArgs): Promise<void> {\n\tif (args.sheets.length === 0) {\n\t\tthrow new Error(\"Для формирования Excel-книги нужен минимум один лист\");\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map((sheet) => sheet.name));\n\tconst autoFilterRefs: Array<string | undefined> = [];\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => {\n\t\tconst data = buildExcelSheetData(sheet);\n\t\tautoFilterRefs.push(sheet.autoFilter ? buildExcelAutoFilterRef(sheet.columns.length, data.length) : undefined);\n\n\t\treturn {\n\t\t\tdata,\n\t\t\tsheet: sheetNames[index],\n\t\t\tcolumns: sheet.columns.map((column) => ({\n\t\t\t\twidth: column.width\n\t\t\t}))\n\t\t};\n\t});\n\tconst autoFilterFeature = createAutoFilterFeature<BrowserExcelFileContent>(autoFilterRefs);\n\n\tawait writeXlsxFile(sheets, {\n\t\tfeatures: autoFilterFeature ? [autoFilterFeature] : undefined\n\t}).toFile(args.fileName);\n}\n\n/**\n * Формирует и скачивает `.xlsx` в браузере.\n *\n * Это публичная generic-точка shared-слоя: она отвечает только за Excel-файл,\n * а подготовка доменных данных остаётся на вызывающей стороне.\n */\nexport async function downloadExcelFile(args: DownloadExcelFileArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName: args.fileName,\n\t\tsheets: [\n\t\t\t{\n\t\t\t\tname: \"Sheet1\",\n\t\t\t\tcolumns: args.columns,\n\t\t\t\trows: args.rows,\n\t\t\t\tautoFilter: args.autoFilter,\n\t\t\t\tgetCellStyle: args.getCellStyle\n\t\t\t}\n\t\t]\n\t});\n}\n","import writeXlsxFile, { type Cell, type Feature, type Sheet } from \"write-excel-file/browser\";\n\nimport { downloadFileFromBlob } from \"../dom\";\nimport { escapeXmlValue } from \"../xml\";\n\nimport { resolveExcelSheetNames } from \"./excel\";\n\ntype BrowserExcelFileContent = File | Blob | ArrayBuffer;\n\n/** Одна строка произвольной Excel-матрицы. Объединения задаются стилями первой ячейки диапазона. */\nexport type ExcelMatrixRow = readonly Cell[];\n\n/** Поля задаются в дюймах, как в OpenXML и диалоге параметров страницы Excel. */\nexport type ExcelPrintMargins = {\n\treadonly left: number;\n\treadonly right: number;\n\treadonly top: number;\n\treadonly bottom: number;\n\treadonly header: number;\n\treadonly footer: number;\n};\n\n/** Видимый колонтитул не принимает raw Excel-коды, чтобы текст не мог случайно изменить разметку секций. */\nexport type ExcelPrintHeaderFooter = {\n\treadonly left?: string;\n\treadonly center?: string;\n\treadonly right?: string;\n\treadonly includePageNumber?: boolean;\n};\n\n/** One-based прямоугольник печати соответствует координатам строк и столбцов Excel. */\nexport type ExcelPrintArea = {\n\treadonly firstRow: number;\n\treadonly lastRow: number;\n\treadonly firstColumn: number;\n\treadonly lastColumn: number;\n};\n\n/**\n * Печатный контракт одного листа.\n *\n * `columnBreaksAfter` и `rowBreaksAfter` используют one-based координату\n * последней ячейки страницы. Явная модель не позволяет consumer перепутать\n * индекс массива с адресом Excel и разрезать составной блок на печати.\n */\nexport type ExcelPrintSetup = {\n\treadonly orientation: \"portrait\" | \"landscape\";\n\treadonly paperSize?: \"a4\" | \"a3\";\n\treadonly fitToWidthPages?: number;\n\treadonly fitToHeightPages?: number;\n\treadonly pageOrder?: \"downThenOver\" | \"overThenDown\";\n\treadonly margins?: ExcelPrintMargins;\n\treadonly repeatRows?: readonly [firstRow: number, lastRow: number];\n\treadonly repeatColumns?: readonly [firstColumn: number, lastColumn: number];\n\treadonly printArea?: ExcelPrintArea;\n\treadonly columnBreaksAfter?: readonly number[];\n\treadonly rowBreaksAfter?: readonly number[];\n\treadonly header?: ExcelPrintHeaderFooter;\n\treadonly footer?: ExcelPrintHeaderFooter;\n};\n\n/** Произвольный лист сохраняет готовую матрицу и не навязывает табличную строку заголовков. */\nexport type ExcelMatrixWorkbookSheet = {\n\treadonly name: string;\n\treadonly rows: readonly ExcelMatrixRow[];\n\treadonly columns?: readonly { readonly width?: number }[];\n\treadonly showGridLines?: boolean;\n\treadonly zoomScale?: number;\n\treadonly print?: ExcelPrintSetup;\n};\n\n/** Аргументы generic-книги, пригодной как для скачивания, так и для file validation. */\nexport type ExcelMatrixWorkbookArgs = {\n\treadonly sheets: readonly ExcelMatrixWorkbookSheet[];\n};\n\nconst DEFAULT_PRINT_MARGINS = {\n\tleft: 0.2,\n\tright: 0.2,\n\ttop: 0.25,\n\tbottom: 0.25,\n\theader: 0.1,\n\tfooter: 0.1\n} as const satisfies ExcelPrintMargins;\n\nconst PAPER_SIZE = { a4: 9, a3: 8 } as const;\n\nfunction escapeHeaderFooterText(value: string): string {\n\treturn escapeXmlValue(value.replaceAll(\"&\", \"&&\"));\n}\n\nfunction numberToColumnName(index: number): string {\n\tlet value = index;\n\tlet result = \"\";\n\twhile (value > 0) {\n\t\tconst remainder = (value - 1) % 26;\n\t\tresult = String.fromCharCode(65 + remainder) + result;\n\t\tvalue = Math.floor((value - 1) / 26);\n\t}\n\treturn result;\n}\n\nfunction assertPositiveInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value <= 0) throw new Error(`${name} должен быть положительным целым числом`);\n}\n\nfunction assertNonnegativeInteger(value: number, name: string): void {\n\tif (!Number.isInteger(value) || value < 0) throw new Error(`${name} должен быть целым неотрицательным числом`);\n}\n\nfunction validateRange(range: readonly [number, number], name: string): void {\n\tassertPositiveInteger(range[0], `${name}: начало`);\n\tassertPositiveInteger(range[1], `${name}: конец`);\n\tif (range[0] > range[1]) throw new Error(`${name}: начало не может быть больше конца`);\n}\n\nfunction validatePrintSetup(print: ExcelPrintSetup): void {\n\t// В OpenXML ноль означает автоматическое число страниц по соответствующей оси.\n\tif (print.fitToWidthPages !== undefined) assertNonnegativeInteger(print.fitToWidthPages, \"fitToWidthPages\");\n\tif (print.fitToHeightPages !== undefined) assertNonnegativeInteger(print.fitToHeightPages, \"fitToHeightPages\");\n\tif (print.repeatRows) validateRange(print.repeatRows, \"repeatRows\");\n\tif (print.repeatColumns) validateRange(print.repeatColumns, \"repeatColumns\");\n\tfor (const value of print.columnBreaksAfter ?? []) assertPositiveInteger(value, \"columnBreaksAfter\");\n\tfor (const value of print.rowBreaksAfter ?? []) assertPositiveInteger(value, \"rowBreaksAfter\");\n\tif (print.printArea) {\n\t\tassertPositiveInteger(print.printArea.firstRow, \"printArea.firstRow\");\n\t\tassertPositiveInteger(print.printArea.lastRow, \"printArea.lastRow\");\n\t\tassertPositiveInteger(print.printArea.firstColumn, \"printArea.firstColumn\");\n\t\tassertPositiveInteger(print.printArea.lastColumn, \"printArea.lastColumn\");\n\t\tif (print.printArea.firstRow > print.printArea.lastRow || print.printArea.firstColumn > print.printArea.lastColumn) {\n\t\t\tthrow new Error(\"printArea должен задавать непустой прямоугольник\");\n\t\t}\n\t}\n}\n\nfunction buildHeaderFooterXml(\n\ttagName: \"headerFooter\",\n\theader: ExcelPrintHeaderFooter | undefined,\n\tfooter: ExcelPrintHeaderFooter | undefined\n): string {\n\tif (!header && !footer) return \"\";\n\tconst buildSection = (value: ExcelPrintHeaderFooter | undefined) => {\n\t\tif (!value) return \"\";\n\t\tconst content = [\n\t\t\tvalue.left ? `&L${escapeHeaderFooterText(value.left)}` : \"\",\n\t\t\tvalue.center ? `&C${escapeHeaderFooterText(value.center)}` : \"\",\n\t\t\tvalue.right ? `&R${escapeHeaderFooterText(value.right)}` : \"\",\n\t\t\tvalue.includePageNumber ? \"&RСтраница &P из &N\" : \"\"\n\t\t].join(\"\");\n\t\treturn content;\n\t};\n\tconst oddHeader = buildSection(header);\n\tconst oddFooter = buildSection(footer);\n\treturn `<${tagName}>${oddHeader ? `<oddHeader>${oddHeader}</oddHeader>` : \"\"}${oddFooter ? `<oddFooter>${oddFooter}</oddFooter>` : \"\"}</${tagName}>`;\n}\n\nfunction buildBreaksXml(tagName: \"colBreaks\" | \"rowBreaks\", values: readonly number[] | undefined): string {\n\tif (!values || values.length === 0) return \"\";\n\tconst uniqueValues = [...new Set(values)].sort((left, right) => left - right);\n\treturn `<${tagName} count=\"${uniqueValues.length}\" manualBreakCount=\"${uniqueValues.length}\">${uniqueValues\n\t\t.map((value) => `<brk id=\"${value}\" min=\"0\" max=\"16383\" man=\"1\"/>`)\n\t\t.join(\"\")}</${tagName}>`;\n}\n\nfunction applyWorksheetPrintSetup(content: string, print: ExcelPrintSetup): string {\n\tconst margins = print.margins ?? DEFAULT_PRINT_MARGINS;\n\tconst fitToPage = print.fitToWidthPages !== undefined || print.fitToHeightPages !== undefined;\n\tconst sheetProperties = fitToPage ? '<sheetPr><pageSetUpPr fitToPage=\"1\" autoPageBreaks=\"0\"/></sheetPr>' : \"\";\n\tconst result = sheetProperties ? content.replace(\"<sheetViews\", `${sheetProperties}<sheetViews`) : content;\n\tconst pageMargins = `<pageMargins left=\"${margins.left}\" right=\"${margins.right}\" top=\"${margins.top}\" bottom=\"${margins.bottom}\" header=\"${margins.header}\" footer=\"${margins.footer}\"/>`;\n\tconst pageSetupAttributes = [\n\t\t`paperSize=\"${PAPER_SIZE[print.paperSize ?? \"a4\"]}\"`,\n\t\t`orientation=\"${print.orientation}\"`,\n\t\tprint.fitToWidthPages !== undefined ? `fitToWidth=\"${print.fitToWidthPages}\"` : \"\",\n\t\tprint.fitToHeightPages !== undefined ? `fitToHeight=\"${print.fitToHeightPages}\"` : \"\",\n\t\tprint.pageOrder ? `pageOrder=\"${print.pageOrder}\"` : \"\",\n\t\t'usePrinterDefaults=\"0\"'\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\" \");\n\tconst additions = [\n\t\tpageMargins,\n\t\t`<pageSetup ${pageSetupAttributes}/>`,\n\t\tbuildHeaderFooterXml(\"headerFooter\", print.header, print.footer),\n\t\tbuildBreaksXml(\"rowBreaks\", print.rowBreaksAfter),\n\t\tbuildBreaksXml(\"colBreaks\", print.columnBreaksAfter)\n\t].join(\"\");\n\tconst drawingIndex = result.indexOf(\"<drawing\");\n\treturn drawingIndex >= 0\n\t\t? `${result.slice(0, drawingIndex)}${additions}${result.slice(drawingIndex)}`\n\t\t: result.replace(\"</worksheet>\", `${additions}</worksheet>`);\n}\n\nfunction quoteFormulaSheetName(name: string): string {\n\treturn `'${name.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction buildDefinedNames(sheetNames: readonly string[], sheets: readonly ExcelMatrixWorkbookSheet[]): string {\n\tconst definitions: string[] = [];\n\tfor (let sheetIndex = 0; sheetIndex < sheets.length; sheetIndex += 1) {\n\t\tconst print = sheets[sheetIndex]?.print;\n\t\tif (!print) continue;\n\t\tconst sheetName = quoteFormulaSheetName(sheetNames[sheetIndex] ?? `Лист ${sheetIndex + 1}`);\n\t\tconst titles = [\n\t\t\tprint.repeatRows ? `${sheetName}!$${print.repeatRows[0]}:$${print.repeatRows[1]}` : \"\",\n\t\t\tprint.repeatColumns\n\t\t\t\t? `${sheetName}!$${numberToColumnName(print.repeatColumns[0])}:$${numberToColumnName(print.repeatColumns[1])}`\n\t\t\t\t: \"\"\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\",\");\n\t\tif (titles) {\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Titles\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(titles)}</definedName>`);\n\t\t}\n\t\tif (print.printArea) {\n\t\t\tconst { firstRow, lastRow, firstColumn, lastColumn } = print.printArea;\n\t\t\tconst area = `${sheetName}!$${numberToColumnName(firstColumn)}$${firstRow}:$${numberToColumnName(lastColumn)}$${lastRow}`;\n\t\t\tdefinitions.push(`<definedName name=\"_xlnm.Print_Area\" localSheetId=\"${sheetIndex}\">${escapeXmlValue(area)}</definedName>`);\n\t\t}\n\t}\n\treturn definitions.join(\"\");\n}\n\n/**\n * Дополняет штатный контейнер definedNames, который write-excel-file уже\n * создаёт в workbook.xml. Два одноимённых контейнера формально нарушают схему\n * OOXML: Numbers читает такую книгу, а Microsoft Excel отклоняет её.\n */\nfunction applyWorkbookDefinedNames(content: string, definedNames: string): string {\n\tif (/<definedNames\\s*\\/>/.test(content)) {\n\t\treturn content.replace(/<definedNames\\s*\\/>/, `<definedNames>${definedNames}</definedNames>`);\n\t}\n\tif (content.includes(\"</definedNames>\")) {\n\t\treturn content.replace(\"</definedNames>\", `${definedNames}</definedNames>`);\n\t}\n\treturn content.replace(\"</sheets>\", `</sheets><definedNames>${definedNames}</definedNames>`);\n}\n\n/** Настройки печати требуют двух согласованных OpenXML-частей: worksheet и workbook defined names. */\nfunction createMatrixPrintFeature(\n\tsheetNames: readonly string[],\n\tsheets: readonly ExcelMatrixWorkbookSheet[]\n): Feature<BrowserExcelFileContent> | undefined {\n\tif (!sheets.some(({ print }) => print)) return undefined;\n\tconst definedNames = buildDefinedNames(sheetNames, sheets);\n\treturn {\n\t\tfiles: {\n\t\t\ttransform: {\n\t\t\t\t\"xl/worksheets/sheet{id}.xml\": {\n\t\t\t\t\ttransform: (content, _options, properties) => {\n\t\t\t\t\t\tconst setup = sheets[properties.sheetIndex]?.print;\n\t\t\t\t\t\treturn setup ? applyWorksheetPrintSetup(content, setup) : content;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"xl/workbook.xml\": {\n\t\t\t\t\ttransform: (content) => (definedNames ? applyWorkbookDefinedNames(content, definedNames) : content)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Формирует Blob без побочного эффекта скачивания.\n *\n * Этот вход нужен предпросмотру, file validation и сценариям, где download\n * выполняет отдельный browser-owner. KTK-specific layout сюда не передаётся.\n */\nexport async function createExcelMatrixWorkbookBlob(args: ExcelMatrixWorkbookArgs): Promise<Blob> {\n\tif (args.sheets.length === 0) throw new Error(\"Для формирования Excel-книги нужен минимум один лист\");\n\tfor (const sheet of args.sheets) {\n\t\tif (sheet.rows.length === 0) throw new Error(`Лист «${sheet.name}» не содержит строк`);\n\t\tif (sheet.print) validatePrintSetup(sheet.print);\n\t}\n\n\tconst sheetNames = resolveExcelSheetNames(args.sheets.map(({ name }) => name));\n\tconst sheets: Sheet<BrowserExcelFileContent>[] = args.sheets.map((sheet, index) => ({\n\t\tdata: sheet.rows.map((row) => [...row]),\n\t\tsheet: sheetNames[index],\n\t\tcolumns: sheet.columns?.map((column) => ({ width: column.width })),\n\t\tshowGridLines: sheet.showGridLines,\n\t\tzoomScale: sheet.zoomScale\n\t}));\n\tconst printFeature = createMatrixPrintFeature(sheetNames, args.sheets);\n\treturn writeXlsxFile(sheets, { features: printFeature ? [printFeature] : undefined }).toBlob();\n}\n\n/** Скачивает готовую матричную книгу из явного пользовательского действия. */\nexport async function downloadExcelMatrixWorkbook(fileName: string, args: ExcelMatrixWorkbookArgs): Promise<void> {\n\tconst blob = await createExcelMatrixWorkbookBlob(args);\n\tdownloadFileFromBlob(fileName, blob);\n}\n","import { DEFAULT_DATE_PRESET_NAMES, getDatePreset, type DateFormatPreset } from \"../formatters/date\";\nimport { getNumberPreset } from \"../formatters/number\";\nimport {\n\tvalidateFormattersPipelineConfig,\n\ttype FormattersPipelineConfig,\n\ttype FormattersPipelineTypedValueFormatConfig\n} from \"../formatters/pipeline\";\nimport {\n\tisODataBooleanType,\n\tisODataDateType,\n\tisODataIntegerType,\n\tisODataNumericType,\n\ttype ColumnRole,\n\ttype ODataMetaType\n} from \"../odata-service\";\n\nimport { downloadExcelFile, downloadExcelWorkbook, type ExcelCellStyle, type ExcelColumn, type ExcelRow } from \"./excel\";\n\nexport type TableExcelColumnDescriptor = {\n\tid: string;\n\theader: string;\n\twidth?: number;\n\trole?: ColumnRole;\n\todataType?: ODataMetaType;\n\tclientOnly?: boolean;\n\tformattersPipeline?: FormattersPipelineConfig;\n};\n\nexport type ResolvedExcelTable = {\n\tcolumns: ExcelColumn[];\n\trows: ExcelRow[];\n\tcellStyles?: ReadonlyArray<Readonly<Record<string, ExcelCellStyle | undefined>>>;\n};\n\nexport type DownloadResolvedExcelTableArgs = {\n\tfileName: string;\n\ttable: ResolvedExcelTable;\n\tautoFilter?: boolean;\n};\n\n/** Один подготовленный табличный лист generic Excel-книги. */\nexport type ResolvedExcelWorkbookSheet = {\n\t/** Желаемое имя листа. */\n\tname: string;\n\t/** Подготовленные колонки, строки и optional стили ячеек. */\n\ttable: ResolvedExcelTable;\n\t/** Включить автофильтр для этого листа. По умолчанию включён. */\n\tautoFilter?: boolean;\n};\n\n/** Аргументы скачивания книги из нескольких подготовленных таблиц. */\nexport type DownloadResolvedExcelWorkbookArgs = {\n\t/** Имя скачиваемого `.xlsx` файла. */\n\tfileName: string;\n\t/** Табличные листы в порядке отображения в книге. */\n\tsheets: ResolvedExcelWorkbookSheet[];\n};\n\nconst INTEGER_EXCEL_FORMAT = \"#,##0\";\nconst DEFAULT_DECIMAL_EXCEL_FORMAT = \"#,##0.0\";\nconst EXCEL_DATE_FORMAT = \"dd.mm.yyyy\";\n/**\n * Excel-маски календарных пресетов сохраняют экранную детализацию:\n * month-* выводит день и месяц без года, а month-year-* — месяц и год без дня.\n */\nconst EXCEL_DAY_MONTH_SHORT_FORMAT = \"dd.mm\";\nconst EXCEL_DAY_MONTH_MEDIUM_FORMAT = \"d mmm\";\nconst EXCEL_DAY_MONTH_LONG_FORMAT = \"d mmmm\";\nconst EXCEL_MONTH_YEAR_MEDIUM_FORMAT = \"mmm yyyy\";\nconst EXCEL_MONTH_YEAR_LONG_FORMAT = \"mmmm yyyy\";\nconst EXCEL_TIME_FORMAT = \"hh:mm\";\nconst EXCEL_TIME_SECONDS_FORMAT = \"hh:mm:ss\";\nconst EXCEL_DATETIME_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_FORMAT}`;\nconst EXCEL_DATETIME_SECONDS_FORMAT = `${EXCEL_DATE_FORMAT} ${EXCEL_TIME_SECONDS_FORMAT}`;\n\nfunction resolveTypedValueFormatConfig(\n\tformattersPipeline: FormattersPipelineConfig | undefined\n): FormattersPipelineTypedValueFormatConfig | undefined {\n\tconst validation = validateFormattersPipelineConfig(formattersPipeline);\n\tconst typedValueFormatStep = validation.plan?.steps.find((step) => step.type === \"typedValueFormat\");\n\n\treturn typedValueFormatStep?.type === \"typedValueFormat\" ? typedValueFormatStep.config : undefined;\n}\n\nexport function resolveTableExcelColumnType(descriptor: TableExcelColumnDescriptor): ExcelColumn[\"type\"] {\n\tif (descriptor.clientOnly) return Number;\n\tif (isODataDateType(descriptor.odataType)) return Date;\n\tif (isODataBooleanType(descriptor.odataType)) return Boolean;\n\tif (isODataNumericType(descriptor.odataType)) return Number;\n\tif (descriptor.role === \"measure\") return Number;\n\treturn String;\n}\n\nfunction resolveNumberPresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.numberPresetName?.trim();\n\tif (configuredPresetName && getNumberPreset(configuredPresetName)) return configuredPresetName;\n\tif (isODataIntegerType(descriptor.odataType)) return \"integer\";\n\treturn \"decimal\";\n}\n\nfunction resolveExcelNumberFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst preset = getNumberPreset(resolveNumberPresetName(descriptor));\n\tif (!preset) return DEFAULT_DECIMAL_EXCEL_FORMAT;\n\treturn preset.decimals > 0 ? `#,##0.${\"0\".repeat(preset.decimals)}` : INTEGER_EXCEL_FORMAT;\n}\n\nfunction resolveDatePresetName(descriptor: TableExcelColumnDescriptor): string {\n\tconst configuredPresetName = resolveTypedValueFormatConfig(descriptor.formattersPipeline)?.datePresetName?.trim();\n\tif (configuredPresetName) return configuredPresetName;\n\tif (descriptor.odataType === \"time\") return DEFAULT_DATE_PRESET_NAMES.time;\n\tif (descriptor.odataType === \"datetime\" || descriptor.odataType === \"datetimeOffset\") return DEFAULT_DATE_PRESET_NAMES.datetime;\n\treturn DEFAULT_DATE_PRESET_NAMES.date;\n}\n\nfunction normalizeDatePatternForExcel(pattern: string): string {\n\treturn pattern.replace(/H/g, \"h\").replace(/M/g, \"m\");\n}\n\nfunction resolveBuiltinDatePresetExcelFormat(presetName: string): string | undefined {\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDatetime || presetName === DEFAULT_DATE_PRESET_NAMES.abapDatetime) {\n\t\treturn EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.odataDate || presetName === DEFAULT_DATE_PRESET_NAMES.abapDate) {\n\t\treturn EXCEL_DATE_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthShort) {\n\t\treturn EXCEL_DAY_MONTH_SHORT_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthMedium) {\n\t\treturn EXCEL_DAY_MONTH_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthLong) {\n\t\treturn EXCEL_DAY_MONTH_LONG_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearMedium) {\n\t\treturn EXCEL_MONTH_YEAR_MEDIUM_FORMAT;\n\t}\n\n\tif (presetName === DEFAULT_DATE_PRESET_NAMES.monthYearLong) {\n\t\treturn EXCEL_MONTH_YEAR_LONG_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"datetime\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.datetime || presetName === DEFAULT_DATE_PRESET_NAMES.datetimeShort\n\t\t\t? EXCEL_DATETIME_FORMAT\n\t\t\t: EXCEL_DATETIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"time\")) {\n\t\treturn presetName === DEFAULT_DATE_PRESET_NAMES.time || presetName === DEFAULT_DATE_PRESET_NAMES.timeShort\n\t\t\t? EXCEL_TIME_FORMAT\n\t\t\t: EXCEL_TIME_SECONDS_FORMAT;\n\t}\n\n\tif (presetName.startsWith(\"date\")) return EXCEL_DATE_FORMAT;\n\n\treturn undefined;\n}\n\nfunction resolveExcelDateFormatFromPreset(presetName: string, preset: DateFormatPreset | undefined): string {\n\tconst builtinFormat = resolveBuiltinDatePresetExcelFormat(presetName);\n\tif (builtinFormat) return builtinFormat;\n\tif (preset?.pattern) return normalizeDatePatternForExcel(preset.pattern);\n\n\t// Настройка datePresetName исторически хранит и ручной шаблон. Если имени\n\t// нет в реестре, передаём шаблон в Excel как есть после нормализации токенов.\n\treturn normalizeDatePatternForExcel(presetName);\n}\n\nfunction resolveExcelDateFormat(descriptor: TableExcelColumnDescriptor): string {\n\tconst presetName = resolveDatePresetName(descriptor);\n\treturn resolveExcelDateFormatFromPreset(presetName, getDatePreset(presetName));\n}\n\nfunction resolveTableExcelColumnFormat(descriptor: TableExcelColumnDescriptor, type: ExcelColumn[\"type\"]): string | undefined {\n\tif (type === Number) return resolveExcelNumberFormat(descriptor);\n\tif (type === Date) return resolveExcelDateFormat(descriptor);\n\treturn undefined;\n}\n\nexport function createTableExcelColumn(descriptor: TableExcelColumnDescriptor): ExcelColumn {\n\tconst type = resolveTableExcelColumnType(descriptor);\n\treturn {\n\t\tid: descriptor.id,\n\t\theader: descriptor.header,\n\t\twidth: descriptor.width,\n\t\ttype,\n\t\tformat: resolveTableExcelColumnFormat(descriptor, type)\n\t};\n}\n\nexport async function downloadResolvedExcelTable({ fileName, table, autoFilter = true }: DownloadResolvedExcelTableArgs): Promise<void> {\n\tawait downloadExcelFile({\n\t\tfileName,\n\t\tcolumns: table.columns,\n\t\trows: table.rows,\n\t\tautoFilter,\n\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t});\n}\n\n/** Скачивает многолистовую книгу из таблиц, уже подготовленных доменными consumers. */\nexport async function downloadResolvedExcelWorkbook({ fileName, sheets }: DownloadResolvedExcelWorkbookArgs): Promise<void> {\n\tawait downloadExcelWorkbook({\n\t\tfileName,\n\t\tsheets: sheets.map(({ name, table, autoFilter = true }) => ({\n\t\t\tname,\n\t\t\tcolumns: table.columns,\n\t\t\trows: table.rows,\n\t\t\tautoFilter,\n\t\t\tgetCellStyle: ({ rowIndex, column }) => table.cellStyles?.[rowIndex]?.[column.id]\n\t\t}))\n\t});\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrixWorkbook.d.ts","sourceRoot":"","sources":["../../src/excel/matrixWorkbook.ts"],"names":[],"mappings":"AAAA,OAAsB,EAAE,KAAK,IAAI,EAA4B,MAAM,0BAA0B,CAAC;AAS9F,oGAAoG;AACpG,MAAM,MAAM,cAAc,GAAG,SAAS,IAAI,EAAE,CAAC;AAE7C,iFAAiF;AACjF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,4GAA4G;AAC5G,MAAM,MAAM,sBAAsB,GAAG;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACrC,CAAC;AAEF,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/C,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,cAAc,CAAC;IACrD,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACnE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC;CACzC,CAAC;AAEF,+FAA+F;AAC/F,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,cAAc,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CACjC,CAAC;AAEF,wFAAwF;AACxF,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;CACrD,CAAC;
|
|
1
|
+
{"version":3,"file":"matrixWorkbook.d.ts","sourceRoot":"","sources":["../../src/excel/matrixWorkbook.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/excel/README.mdx
CHANGED
|
@@ -262,6 +262,7 @@ await downloadExcelMatrixWorkbook("Расписание.xlsx", {
|
|
|
262
262
|
print: {
|
|
263
263
|
orientation: "portrait",
|
|
264
264
|
paperSize: "a4",
|
|
265
|
+
fitToWidthPages: 0,
|
|
265
266
|
fitToHeightPages: 1,
|
|
266
267
|
repeatRows: [1, 1],
|
|
267
268
|
columnBreaksAfter: [12],
|
|
@@ -276,8 +277,8 @@ await downloadExcelMatrixWorkbook("Расписание.xlsx", {
|
|
|
276
277
|
`columnBreaksAfter` и `rowBreaksAfter` используют one-based номер последней
|
|
277
278
|
колонки или строки страницы. Например, `columnBreaksAfter: [12]` переносит
|
|
278
279
|
колонку `M` на следующую страницу. `fitToHeightPages` и `fitToWidthPages` должны
|
|
279
|
-
быть
|
|
280
|
-
|
|
280
|
+
быть целыми неотрицательными: ноль означает автоматическое число страниц по
|
|
281
|
+
этой оси.
|
|
281
282
|
|
|
282
283
|
`createExcelMatrixWorkbookBlob` не инициирует скачивание и подходит для preview
|
|
283
284
|
и проверки сформированного файла. `downloadExcelMatrixWorkbook` делегирует
|