reamkit 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/esm/bidi/algorithm.d.ts +9 -0
- package/dist/esm/bidi/algorithm.js +458 -0
- package/dist/esm/bidi/char-types.d.ts +2 -0
- package/dist/esm/bidi/char-types.js +439 -0
- package/dist/esm/bidi/index.d.ts +14 -0
- package/dist/esm/bidi/index.js +25 -0
- package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
- package/dist/esm/converter/docx-to-pdf.js +227 -0
- package/dist/esm/converter/index.d.ts +4 -0
- package/dist/esm/converter/index.js +2 -0
- package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
- package/dist/esm/converter/xlsx-to-pdf.js +515 -0
- package/dist/esm/crypto/asn1.d.ts +23 -0
- package/dist/esm/crypto/asn1.js +123 -0
- package/dist/esm/crypto/cms.d.ts +9 -0
- package/dist/esm/crypto/cms.js +34 -0
- package/dist/esm/crypto/index.d.ts +2 -0
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/document-model/index.d.ts +1 -0
- package/dist/esm/document-model/index.js +0 -0
- package/dist/esm/document-model/types.d.ts +403 -0
- package/dist/esm/font/arabic-joining.d.ts +4 -0
- package/dist/esm/font/arabic-joining.js +97 -0
- package/dist/esm/font/binary-reader.d.ts +13 -0
- package/dist/esm/font/binary-reader.js +44 -0
- package/dist/esm/font/font-registry.d.ts +19 -0
- package/dist/esm/font/font-registry.js +39 -0
- package/dist/esm/font/index.d.ts +7 -0
- package/dist/esm/font/opentype-layout.d.ts +21 -0
- package/dist/esm/font/opentype-layout.js +329 -0
- package/dist/esm/font/ttf-parser.d.ts +29 -0
- package/dist/esm/font/ttf-parser.js +290 -0
- package/dist/esm/font/ttf-subset.d.ts +3 -0
- package/dist/esm/font/ttf-subset.js +201 -0
- package/dist/esm/fonts/index.d.ts +2 -0
- package/dist/esm/fonts/remote-fonts.d.ts +13 -0
- package/dist/esm/fonts/remote-fonts.js +94 -0
- package/dist/esm/hyphenation/index.d.ts +10 -0
- package/dist/esm/hyphenation/index.js +38 -0
- package/dist/esm/hyphenation/liang.d.ts +10 -0
- package/dist/esm/hyphenation/liang.js +79 -0
- package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-en-us.js +5 -0
- package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-ru.js +5 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/line-breaker/index.d.ts +2 -0
- package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
- package/dist/esm/line-breaker/knuth-plass.js +172 -0
- package/dist/esm/numbering/index.d.ts +1 -0
- package/dist/esm/numbering/state.d.ts +6 -0
- package/dist/esm/numbering/state.js +83 -0
- package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
- package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
- package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
- package/dist/esm/ooxml/drawingml/colors.js +125 -0
- package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
- package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
- package/dist/esm/ooxml/index.d.ts +1 -0
- package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
- package/dist/esm/ooxml/math/omml-parser.js +217 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
- package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
- package/dist/esm/ooxml/spreadsheet/index.js +7 -0
- package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
- package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
- package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
- package/dist/esm/ooxml/wordproc/font-table.js +82 -0
- package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
- package/dist/esm/ooxml/wordproc/index.js +9 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
- package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
- package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
- package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
- package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
- package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
- package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
- package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
- package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
- package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
- package/dist/esm/opc/core-properties.d.ts +11 -0
- package/dist/esm/opc/core-properties.js +51 -0
- package/dist/esm/opc/index.d.ts +5 -0
- package/dist/esm/opc/index.js +3 -0
- package/dist/esm/opc/package.d.ts +26 -0
- package/dist/esm/opc/package.js +113 -0
- package/dist/esm/opc/relationship-types.d.ts +3 -0
- package/dist/esm/opc/relationship-types.js +4 -0
- package/dist/esm/opc/relationships.d.ts +7 -0
- package/dist/esm/opc/relationships.js +28 -0
- package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
- package/dist/esm/pdf/arc-to-bezier.js +58 -0
- package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
- package/dist/esm/pdf/chart-geometry.d.ts +64 -0
- package/dist/esm/pdf/chart-geometry.js +674 -0
- package/dist/esm/pdf/cid-font.d.ts +15 -0
- package/dist/esm/pdf/cid-font.js +174 -0
- package/dist/esm/pdf/embedded-file.d.ts +11 -0
- package/dist/esm/pdf/embedded-file.js +23 -0
- package/dist/esm/pdf/icc-profile.d.ts +1 -0
- package/dist/esm/pdf/icc-profile.js +166 -0
- package/dist/esm/pdf/image-xobject.d.ts +13 -0
- package/dist/esm/pdf/image-xobject.js +335 -0
- package/dist/esm/pdf/index.d.ts +11 -0
- package/dist/esm/pdf/index.js +5 -0
- package/dist/esm/pdf/math-layout.d.ts +45 -0
- package/dist/esm/pdf/math-layout.js +1138 -0
- package/dist/esm/pdf/objects.d.ts +32 -0
- package/dist/esm/pdf/objects.js +54 -0
- package/dist/esm/pdf/preset-geometry.d.ts +6 -0
- package/dist/esm/pdf/preset-geometry.js +199 -0
- package/dist/esm/pdf/serialize.d.ts +3 -0
- package/dist/esm/pdf/serialize.js +54 -0
- package/dist/esm/pdf/signature.d.ts +25 -0
- package/dist/esm/pdf/signature.js +126 -0
- package/dist/esm/pdf/struct-tree.d.ts +31 -0
- package/dist/esm/pdf/struct-tree.js +109 -0
- package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
- package/dist/esm/pdf/styled-page-renderer.js +2317 -0
- package/dist/esm/pdf/text-encoding.d.ts +2 -0
- package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
- package/dist/esm/pdf/text-page-renderer.js +4 -0
- package/dist/esm/pdf/vector-graphics.d.ts +46 -0
- package/dist/esm/pdf/vector-graphics.js +103 -0
- package/dist/esm/pdf/writer.d.ts +10 -0
- package/dist/esm/pdf/writer.js +81 -0
- package/dist/esm/pdf/xmp.d.ts +13 -0
- package/dist/esm/pdf/xmp.js +38 -0
- package/dist/esm/style-cascade/index.d.ts +3 -0
- package/dist/esm/style-cascade/resolver.d.ts +4 -0
- package/dist/esm/style-cascade/resolver.js +96 -0
- package/dist/esm/style-cascade/types.d.ts +29 -0
- package/dist/esm/style-cascade/types.js +26 -0
- package/package.json +90 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
//#region src/ooxml/spreadsheet/number-format.ts
|
|
2
|
+
var BUILTIN = new Map([
|
|
3
|
+
[0, "General"],
|
|
4
|
+
[1, "0"],
|
|
5
|
+
[2, "0.00"],
|
|
6
|
+
[3, "#,##0"],
|
|
7
|
+
[4, "#,##0.00"],
|
|
8
|
+
[9, "0%"],
|
|
9
|
+
[10, "0.00%"],
|
|
10
|
+
[11, "0.00E+00"],
|
|
11
|
+
[37, "#,##0_);(#,##0)"],
|
|
12
|
+
[38, "#,##0_);[Red](#,##0)"],
|
|
13
|
+
[39, "#,##0.00_);(#,##0.00)"],
|
|
14
|
+
[40, "#,##0.00_);[Red](#,##0.00)"],
|
|
15
|
+
[49, "@"]
|
|
16
|
+
]);
|
|
17
|
+
var BUILTIN_DATE_FORMATS = new Map([
|
|
18
|
+
[14, "m/d/yyyy"],
|
|
19
|
+
[15, "d-mmm-yy"],
|
|
20
|
+
[16, "d-mmm"],
|
|
21
|
+
[17, "mmm-yy"],
|
|
22
|
+
[18, "h:mm AM/PM"],
|
|
23
|
+
[19, "h:mm:ss AM/PM"],
|
|
24
|
+
[20, "h:mm"],
|
|
25
|
+
[21, "h:mm:ss"],
|
|
26
|
+
[22, "m/d/yyyy h:mm"],
|
|
27
|
+
[45, "mm:ss"],
|
|
28
|
+
[46, "[h]:mm:ss"],
|
|
29
|
+
[47, "mm:ss.0"]
|
|
30
|
+
]);
|
|
31
|
+
function applyNumberFormat(rawValue, numFmtId, customFormats, date1904 = false) {
|
|
32
|
+
if (rawValue.length === 0) return "";
|
|
33
|
+
if (numFmtId === 0) return defaultNumberRender(rawValue);
|
|
34
|
+
if (numFmtId === 49) return rawValue;
|
|
35
|
+
const builtinDate = BUILTIN_DATE_FORMATS.get(numFmtId);
|
|
36
|
+
if (builtinDate !== void 0) return formatExcelDate(rawValue, builtinDate, date1904);
|
|
37
|
+
const custom = customFormats.get(numFmtId);
|
|
38
|
+
if (custom !== void 0 && isDateFormat(custom)) return formatExcelDate(rawValue, custom, date1904);
|
|
39
|
+
const format = custom ?? BUILTIN.get(numFmtId);
|
|
40
|
+
if (!format) return defaultNumberRender(rawValue);
|
|
41
|
+
if (format === "General") return defaultNumberRender(rawValue);
|
|
42
|
+
return applyFormatString(rawValue, format);
|
|
43
|
+
}
|
|
44
|
+
function excelSerialToDate(serial, date1904) {
|
|
45
|
+
const ms = serial * 86400 * 1e3;
|
|
46
|
+
if (date1904) return new Date(Date.UTC(1904, 0, 1) + ms);
|
|
47
|
+
return new Date(Date.UTC(1899, 11, 30) + ms);
|
|
48
|
+
}
|
|
49
|
+
var MONTH_ABBR = [
|
|
50
|
+
"Jan",
|
|
51
|
+
"Feb",
|
|
52
|
+
"Mar",
|
|
53
|
+
"Apr",
|
|
54
|
+
"May",
|
|
55
|
+
"Jun",
|
|
56
|
+
"Jul",
|
|
57
|
+
"Aug",
|
|
58
|
+
"Sep",
|
|
59
|
+
"Oct",
|
|
60
|
+
"Nov",
|
|
61
|
+
"Dec"
|
|
62
|
+
];
|
|
63
|
+
var MONTH_FULL = [
|
|
64
|
+
"January",
|
|
65
|
+
"February",
|
|
66
|
+
"March",
|
|
67
|
+
"April",
|
|
68
|
+
"May",
|
|
69
|
+
"June",
|
|
70
|
+
"July",
|
|
71
|
+
"August",
|
|
72
|
+
"September",
|
|
73
|
+
"October",
|
|
74
|
+
"November",
|
|
75
|
+
"December"
|
|
76
|
+
];
|
|
77
|
+
var DAY_ABBR = [
|
|
78
|
+
"Sun",
|
|
79
|
+
"Mon",
|
|
80
|
+
"Tue",
|
|
81
|
+
"Wed",
|
|
82
|
+
"Thu",
|
|
83
|
+
"Fri",
|
|
84
|
+
"Sat"
|
|
85
|
+
];
|
|
86
|
+
var DAY_FULL = [
|
|
87
|
+
"Sunday",
|
|
88
|
+
"Monday",
|
|
89
|
+
"Tuesday",
|
|
90
|
+
"Wednesday",
|
|
91
|
+
"Thursday",
|
|
92
|
+
"Friday",
|
|
93
|
+
"Saturday"
|
|
94
|
+
];
|
|
95
|
+
function pad2(n) {
|
|
96
|
+
return String(n).padStart(2, "0");
|
|
97
|
+
}
|
|
98
|
+
function isDateFormat(code) {
|
|
99
|
+
const cleaned = code.replace(/"[^"]*"/g, "").replace(/\[[^\]]*\]/g, "");
|
|
100
|
+
return /[dyhs]|m+/i.test(cleaned) && /[dyhs]/i.test(cleaned);
|
|
101
|
+
}
|
|
102
|
+
function tokenizeDateFormat(format) {
|
|
103
|
+
const tokens = [];
|
|
104
|
+
let i = 0;
|
|
105
|
+
while (i < format.length) {
|
|
106
|
+
const ch = format[i];
|
|
107
|
+
if (ch === "\"") {
|
|
108
|
+
let lit = "";
|
|
109
|
+
i++;
|
|
110
|
+
while (i < format.length && format[i] !== "\"") {
|
|
111
|
+
lit += format[i];
|
|
112
|
+
i++;
|
|
113
|
+
}
|
|
114
|
+
i++;
|
|
115
|
+
tokens.push({
|
|
116
|
+
kind: "lit",
|
|
117
|
+
text: lit
|
|
118
|
+
});
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (ch === "\\" && i + 1 < format.length) {
|
|
122
|
+
tokens.push({
|
|
123
|
+
kind: "lit",
|
|
124
|
+
text: format[i + 1]
|
|
125
|
+
});
|
|
126
|
+
i += 2;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (ch === "[") {
|
|
130
|
+
let body = "";
|
|
131
|
+
i++;
|
|
132
|
+
while (i < format.length && format[i] !== "]") {
|
|
133
|
+
body += format[i];
|
|
134
|
+
i++;
|
|
135
|
+
}
|
|
136
|
+
i++;
|
|
137
|
+
if (/^h+$/i.test(body)) tokens.push({
|
|
138
|
+
kind: "elapsed-h",
|
|
139
|
+
text: body
|
|
140
|
+
});
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const lower = ch.toLowerCase();
|
|
144
|
+
if (lower === "y" || lower === "m" || lower === "d" || lower === "h" || lower === "s") {
|
|
145
|
+
let run = ch;
|
|
146
|
+
i++;
|
|
147
|
+
while (i < format.length && format[i].toLowerCase() === lower) {
|
|
148
|
+
run += format[i];
|
|
149
|
+
i++;
|
|
150
|
+
}
|
|
151
|
+
if (lower === "y") tokens.push({
|
|
152
|
+
kind: "y",
|
|
153
|
+
text: run
|
|
154
|
+
});
|
|
155
|
+
else if (lower === "d") tokens.push({
|
|
156
|
+
kind: "d",
|
|
157
|
+
text: run
|
|
158
|
+
});
|
|
159
|
+
else if (lower === "h") tokens.push({
|
|
160
|
+
kind: "h",
|
|
161
|
+
text: run
|
|
162
|
+
});
|
|
163
|
+
else if (lower === "s") tokens.push({
|
|
164
|
+
kind: "s",
|
|
165
|
+
text: run
|
|
166
|
+
});
|
|
167
|
+
else tokens.push({
|
|
168
|
+
kind: "m",
|
|
169
|
+
text: run
|
|
170
|
+
});
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (format.startsWith("AM/PM", i) || format.startsWith("A/P", i)) {
|
|
174
|
+
const len = format.startsWith("AM/PM", i) ? 5 : 3;
|
|
175
|
+
tokens.push({
|
|
176
|
+
kind: "ampm",
|
|
177
|
+
text: format.substring(i, i + len)
|
|
178
|
+
});
|
|
179
|
+
i += len;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
tokens.push({
|
|
183
|
+
kind: "lit",
|
|
184
|
+
text: ch
|
|
185
|
+
});
|
|
186
|
+
i++;
|
|
187
|
+
}
|
|
188
|
+
return tokens;
|
|
189
|
+
}
|
|
190
|
+
function resolveMonthVsMinute(tokens) {
|
|
191
|
+
const resolved = tokens.map((t) => ({ ...t }));
|
|
192
|
+
for (let i = 0; i < resolved.length; i++) {
|
|
193
|
+
const t = resolved[i];
|
|
194
|
+
if (t.kind !== "m") continue;
|
|
195
|
+
let prev = i - 1;
|
|
196
|
+
while (prev >= 0 && resolved[prev].kind === "lit") prev--;
|
|
197
|
+
let next = i + 1;
|
|
198
|
+
while (next < resolved.length && resolved[next].kind === "lit") next++;
|
|
199
|
+
const prevIsHour = prev >= 0 && resolved[prev].kind === "h";
|
|
200
|
+
const nextIsSec = next < resolved.length && resolved[next].kind === "s";
|
|
201
|
+
if (prevIsHour || nextIsSec) continue;
|
|
202
|
+
resolved[i] = {
|
|
203
|
+
kind: "M",
|
|
204
|
+
text: t.text
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return resolved;
|
|
208
|
+
}
|
|
209
|
+
function formatExcelDate(rawValue, format, date1904) {
|
|
210
|
+
const serial = Number(rawValue);
|
|
211
|
+
if (!Number.isFinite(serial)) return rawValue;
|
|
212
|
+
format = splitSections(format)[0] ?? format;
|
|
213
|
+
const date = excelSerialToDate(serial, date1904);
|
|
214
|
+
const year = date.getUTCFullYear();
|
|
215
|
+
const month = date.getUTCMonth() + 1;
|
|
216
|
+
const day = date.getUTCDate();
|
|
217
|
+
const weekday = date.getUTCDay();
|
|
218
|
+
const hour24 = date.getUTCHours();
|
|
219
|
+
const minute = date.getUTCMinutes();
|
|
220
|
+
const second = date.getUTCSeconds();
|
|
221
|
+
const tokens = resolveMonthVsMinute(tokenizeDateFormat(format));
|
|
222
|
+
const hourValue = tokens.some((t) => t.kind === "ampm") ? hour24 % 12 === 0 ? 12 : hour24 % 12 : hour24;
|
|
223
|
+
const ampmLabel = (template) => {
|
|
224
|
+
const isUpper = template[0] === "A";
|
|
225
|
+
const isShort = template.length <= 3;
|
|
226
|
+
if (hour24 < 12) return isShort ? isUpper ? "A" : "a" : isUpper ? "AM" : "am";
|
|
227
|
+
return isShort ? isUpper ? "P" : "p" : isUpper ? "PM" : "pm";
|
|
228
|
+
};
|
|
229
|
+
let out = "";
|
|
230
|
+
for (const t of tokens) switch (t.kind) {
|
|
231
|
+
case "lit":
|
|
232
|
+
out += t.text;
|
|
233
|
+
break;
|
|
234
|
+
case "y":
|
|
235
|
+
out += t.text.length <= 2 ? pad2(year % 100) : String(year).padStart(4, "0");
|
|
236
|
+
break;
|
|
237
|
+
case "M": {
|
|
238
|
+
const len = t.text.length;
|
|
239
|
+
if (len === 5) out += MONTH_FULL[month - 1][0];
|
|
240
|
+
else if (len === 4) out += MONTH_FULL[month - 1];
|
|
241
|
+
else if (len === 3) out += MONTH_ABBR[month - 1];
|
|
242
|
+
else if (len === 2) out += pad2(month);
|
|
243
|
+
else out += String(month);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case "d": {
|
|
247
|
+
const len = t.text.length;
|
|
248
|
+
if (len >= 4) out += DAY_FULL[weekday];
|
|
249
|
+
else if (len === 3) out += DAY_ABBR[weekday];
|
|
250
|
+
else if (len === 2) out += pad2(day);
|
|
251
|
+
else out += String(day);
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case "h":
|
|
255
|
+
out += t.text.length >= 2 ? pad2(hourValue) : String(hourValue);
|
|
256
|
+
break;
|
|
257
|
+
case "elapsed-h":
|
|
258
|
+
out += String(Math.floor(serial * 24));
|
|
259
|
+
break;
|
|
260
|
+
case "m":
|
|
261
|
+
out += t.text.length >= 2 ? pad2(minute) : String(minute);
|
|
262
|
+
break;
|
|
263
|
+
case "s":
|
|
264
|
+
out += t.text.length >= 2 ? pad2(second) : String(second);
|
|
265
|
+
break;
|
|
266
|
+
case "ampm":
|
|
267
|
+
out += ampmLabel(t.text);
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
function defaultNumberRender(rawValue) {
|
|
273
|
+
const n = Number(rawValue);
|
|
274
|
+
if (!Number.isFinite(n)) return rawValue;
|
|
275
|
+
if (Number.isInteger(n)) return String(n);
|
|
276
|
+
return String(n);
|
|
277
|
+
}
|
|
278
|
+
function applyFormatString(rawValue, format) {
|
|
279
|
+
const n = Number(rawValue);
|
|
280
|
+
const sections = splitSections(format);
|
|
281
|
+
if (!Number.isFinite(n)) {
|
|
282
|
+
const textSection = sections[3];
|
|
283
|
+
if (textSection !== void 0) return textSection.replace(/@/g, rawValue);
|
|
284
|
+
return rawValue;
|
|
285
|
+
}
|
|
286
|
+
let sectionIdx;
|
|
287
|
+
if (n > 0) sectionIdx = 0;
|
|
288
|
+
else if (n < 0) sectionIdx = sections.length > 1 ? 1 : 0;
|
|
289
|
+
else sectionIdx = sections.length > 2 ? 2 : 0;
|
|
290
|
+
return applyNumericSection(n, sections[sectionIdx] ?? sections[0], sectionIdx === 1);
|
|
291
|
+
}
|
|
292
|
+
function splitSections(format) {
|
|
293
|
+
const out = [];
|
|
294
|
+
let current = "";
|
|
295
|
+
let inQuotes = false;
|
|
296
|
+
let bracketDepth = 0;
|
|
297
|
+
for (let i = 0; i < format.length; i++) {
|
|
298
|
+
const ch = format[i];
|
|
299
|
+
if (ch === "\"") {
|
|
300
|
+
inQuotes = !inQuotes;
|
|
301
|
+
current += ch;
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (!inQuotes) {
|
|
305
|
+
if (ch === "[") bracketDepth++;
|
|
306
|
+
else if (ch === "]") bracketDepth = Math.max(0, bracketDepth - 1);
|
|
307
|
+
else if (ch === "\\" && i + 1 < format.length) {
|
|
308
|
+
current += ch + format[i + 1];
|
|
309
|
+
i++;
|
|
310
|
+
continue;
|
|
311
|
+
} else if (ch === ";" && bracketDepth === 0) {
|
|
312
|
+
out.push(current);
|
|
313
|
+
current = "";
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
current += ch;
|
|
318
|
+
}
|
|
319
|
+
out.push(current);
|
|
320
|
+
return out;
|
|
321
|
+
}
|
|
322
|
+
function countDigitPlaceholders(s) {
|
|
323
|
+
let n = 0;
|
|
324
|
+
for (const c of s) if (c === "0" || c === "#" || c === "?") n++;
|
|
325
|
+
return n;
|
|
326
|
+
}
|
|
327
|
+
function formatScientific(value, cleaned, negativeSection) {
|
|
328
|
+
const m = /^(.*?)([eE])([+-])(.*)$/.exec(cleaned);
|
|
329
|
+
if (!m) return cleaned;
|
|
330
|
+
const mantissaFmt = m[1];
|
|
331
|
+
const eChar = m[2];
|
|
332
|
+
const expSignFmt = m[3];
|
|
333
|
+
const expFmt = m[4];
|
|
334
|
+
const dot = mantissaFmt.indexOf(".");
|
|
335
|
+
const intDigits = Math.max(1, countDigitPlaceholders(dot >= 0 ? mantissaFmt.slice(0, dot) : mantissaFmt));
|
|
336
|
+
const decimals = dot >= 0 ? countDigitPlaceholders(mantissaFmt.slice(dot + 1)) : 0;
|
|
337
|
+
let exp = 0;
|
|
338
|
+
let mant = Math.abs(value);
|
|
339
|
+
if (mant !== 0) {
|
|
340
|
+
exp = Math.floor(Math.log10(mant));
|
|
341
|
+
exp -= (exp % intDigits + intDigits) % intDigits;
|
|
342
|
+
mant = mant / Math.pow(10, exp);
|
|
343
|
+
if (Number(mant.toFixed(decimals)) >= Math.pow(10, intDigits)) {
|
|
344
|
+
exp += intDigits;
|
|
345
|
+
mant = mant / Math.pow(10, intDigits);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
const mantStr = mant.toFixed(decimals);
|
|
349
|
+
const expDigits = countDigitPlaceholders(expFmt) || 2;
|
|
350
|
+
const expStr = String(Math.abs(exp)).padStart(expDigits, "0");
|
|
351
|
+
return `${value < 0 && !negativeSection ? "-" : ""}${mantStr}${eChar}${exp < 0 ? "-" : expSignFmt === "+" ? "+" : ""}${expStr}`;
|
|
352
|
+
}
|
|
353
|
+
function applyNumericSection(value, format, negativeSection) {
|
|
354
|
+
const cleaned = format.replace(/\[[^\]]*\]/g, "");
|
|
355
|
+
if (/[eE][+-]/.test(cleaned)) return formatScientific(value, cleaned, negativeSection);
|
|
356
|
+
const isPercent = cleaned.includes("%");
|
|
357
|
+
let magnitude = Math.abs(value);
|
|
358
|
+
if (isPercent) magnitude *= 100;
|
|
359
|
+
const { intFormat, decFormat, literalPrefix, literalSuffix } = splitNumberFormat(cleaned);
|
|
360
|
+
let decimals = 0;
|
|
361
|
+
for (const c of decFormat) if (c === "0" || c === "#") decimals++;
|
|
362
|
+
const [intRaw, decRaw] = magnitude.toFixed(decimals).split(".");
|
|
363
|
+
let numberPart = /,(?=\d)/.test(intFormat) || /[0#],[0#]/.test(intFormat) ? intRaw.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : intRaw;
|
|
364
|
+
if (decimals > 0) {
|
|
365
|
+
let dec = decRaw ?? "".padEnd(decimals, "0");
|
|
366
|
+
if (dec.length < decimals) dec = dec.padEnd(decimals, "0");
|
|
367
|
+
let kept = "";
|
|
368
|
+
for (let i = 0; i < decFormat.length; i++) {
|
|
369
|
+
const placeholder = decFormat[i];
|
|
370
|
+
const digit = dec[i] ?? "0";
|
|
371
|
+
if (placeholder === "0") kept += digit;
|
|
372
|
+
else if (placeholder === "#") {
|
|
373
|
+
if (digit !== "0" || kept.length > 0) kept += digit;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (kept.length > 0) numberPart += "." + kept;
|
|
377
|
+
else if (decFormat.includes("0")) numberPart += "." + dec;
|
|
378
|
+
}
|
|
379
|
+
let signPrefix = "";
|
|
380
|
+
if (value < 0 && !negativeSection) signPrefix = "-";
|
|
381
|
+
return `${literalPrefix}${signPrefix}${numberPart}${isPercent ? "%" : ""}${literalSuffix}`;
|
|
382
|
+
}
|
|
383
|
+
function splitNumberFormat(cleaned) {
|
|
384
|
+
let firstDigit = -1;
|
|
385
|
+
let lastDigit = -1;
|
|
386
|
+
for (let i = 0; i < cleaned.length; i++) {
|
|
387
|
+
const ch = cleaned[i];
|
|
388
|
+
if (ch === "0" || ch === "#") {
|
|
389
|
+
if (firstDigit < 0) firstDigit = i;
|
|
390
|
+
lastDigit = i;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (firstDigit < 0) return {
|
|
394
|
+
literalPrefix: cleaned,
|
|
395
|
+
intFormat: "",
|
|
396
|
+
decFormat: "",
|
|
397
|
+
literalSuffix: ""
|
|
398
|
+
};
|
|
399
|
+
const literalPrefix = unquoteLiteral(cleaned.substring(0, firstDigit));
|
|
400
|
+
const literalSuffix = unquoteLiteral(cleaned.substring(lastDigit + 1));
|
|
401
|
+
const digitRange = cleaned.substring(firstDigit, lastDigit + 1);
|
|
402
|
+
const dotIdx = digitRange.indexOf(".");
|
|
403
|
+
return {
|
|
404
|
+
literalPrefix,
|
|
405
|
+
intFormat: dotIdx >= 0 ? digitRange.substring(0, dotIdx) : digitRange,
|
|
406
|
+
decFormat: dotIdx >= 0 ? digitRange.substring(dotIdx + 1) : "",
|
|
407
|
+
literalSuffix
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function unquoteLiteral(s) {
|
|
411
|
+
let out = "";
|
|
412
|
+
for (let i = 0; i < s.length; i++) {
|
|
413
|
+
const ch = s[i];
|
|
414
|
+
if (ch === "\"") {
|
|
415
|
+
i++;
|
|
416
|
+
while (i < s.length && s[i] !== "\"") {
|
|
417
|
+
out += s[i];
|
|
418
|
+
i++;
|
|
419
|
+
}
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (ch === "\\" && i + 1 < s.length) {
|
|
423
|
+
out += s[i + 1];
|
|
424
|
+
i++;
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
if (ch === "_" && i + 1 < s.length) {
|
|
428
|
+
out += " ";
|
|
429
|
+
i++;
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
if (ch === "%") continue;
|
|
433
|
+
out += ch;
|
|
434
|
+
}
|
|
435
|
+
return out;
|
|
436
|
+
}
|
|
437
|
+
//#endregion
|
|
438
|
+
export { applyNumberFormat };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function parseSharedStrings(data: Uint8Array): Array<string>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { XMLParser } from "fast-xml-parser";
|
|
2
|
+
//#region src/ooxml/spreadsheet/shared-strings-parser.ts
|
|
3
|
+
var decoder = new TextDecoder("utf-8");
|
|
4
|
+
var parser = new XMLParser({
|
|
5
|
+
ignoreAttributes: false,
|
|
6
|
+
attributeNamePrefix: "@_",
|
|
7
|
+
textNodeName: "#text",
|
|
8
|
+
parseAttributeValue: false,
|
|
9
|
+
parseTagValue: false,
|
|
10
|
+
trimValues: false,
|
|
11
|
+
removeNSPrefix: true
|
|
12
|
+
});
|
|
13
|
+
var MAX_CELL_CHARS = 32767;
|
|
14
|
+
function capLen(s) {
|
|
15
|
+
return s.length > MAX_CELL_CHARS ? s.slice(0, MAX_CELL_CHARS) : s;
|
|
16
|
+
}
|
|
17
|
+
function parseSharedStrings(data) {
|
|
18
|
+
const xml = decoder.decode(data);
|
|
19
|
+
const sst = parser.parse(xml)["sst"];
|
|
20
|
+
if (!sst || typeof sst !== "object") return [];
|
|
21
|
+
const siRaw = sst["si"];
|
|
22
|
+
return (Array.isArray(siRaw) ? siRaw : siRaw !== void 0 ? [siRaw] : []).map((item) => capLen(extractSiText(item)));
|
|
23
|
+
}
|
|
24
|
+
function extractSiText(si) {
|
|
25
|
+
if (typeof si === "string") return si;
|
|
26
|
+
if (typeof si === "number") return String(si);
|
|
27
|
+
if (!si || typeof si !== "object") return "";
|
|
28
|
+
const obj = si;
|
|
29
|
+
const t = obj["t"];
|
|
30
|
+
const direct = textOf(t);
|
|
31
|
+
if (direct) return direct;
|
|
32
|
+
const r = obj["r"];
|
|
33
|
+
if (Array.isArray(r)) return r.map((rr) => textOf(rr?.["t"])).join("");
|
|
34
|
+
if (r && typeof r === "object") return textOf(r["t"]);
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
function textOf(node) {
|
|
38
|
+
if (typeof node === "string") return node;
|
|
39
|
+
if (typeof node === "number") return String(node);
|
|
40
|
+
if (!node || typeof node !== "object") return "";
|
|
41
|
+
const inner = node["#text"];
|
|
42
|
+
if (typeof inner === "string") return inner;
|
|
43
|
+
if (typeof inner === "number") return String(inner);
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { parseSharedStrings };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface XlsxFont {
|
|
2
|
+
readonly sizePt?: number;
|
|
3
|
+
readonly bold?: boolean;
|
|
4
|
+
readonly italic?: boolean;
|
|
5
|
+
readonly underline?: boolean;
|
|
6
|
+
readonly colorHex?: string;
|
|
7
|
+
readonly name?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface XlsxFill {
|
|
10
|
+
readonly patternType?: string;
|
|
11
|
+
readonly fgColorHex?: string;
|
|
12
|
+
readonly bgColorHex?: string;
|
|
13
|
+
}
|
|
14
|
+
export type XlsxBorderStyleName = 'none' | 'thin' | 'medium' | 'thick' | 'hair' | 'dashed' | 'dotted' | 'double' | 'mediumDashed' | 'dashDot' | 'mediumDashDot' | 'dashDotDot' | 'mediumDashDotDot' | 'slantDashDot';
|
|
15
|
+
export interface XlsxBorderEdge {
|
|
16
|
+
readonly style?: XlsxBorderStyleName;
|
|
17
|
+
readonly colorHex?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface XlsxBorder {
|
|
20
|
+
readonly top?: XlsxBorderEdge;
|
|
21
|
+
readonly right?: XlsxBorderEdge;
|
|
22
|
+
readonly bottom?: XlsxBorderEdge;
|
|
23
|
+
readonly left?: XlsxBorderEdge;
|
|
24
|
+
}
|
|
25
|
+
export type XlsxHorizontalAlign = 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed';
|
|
26
|
+
export type XlsxVerticalAlign = 'top' | 'center' | 'bottom' | 'justify' | 'distributed';
|
|
27
|
+
export interface XlsxCellAlignment {
|
|
28
|
+
readonly horizontal?: XlsxHorizontalAlign;
|
|
29
|
+
readonly vertical?: XlsxVerticalAlign;
|
|
30
|
+
readonly wrapText?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface XlsxCellXf {
|
|
33
|
+
readonly numFmtId: number;
|
|
34
|
+
readonly fontId: number;
|
|
35
|
+
readonly fillId: number;
|
|
36
|
+
readonly borderId: number;
|
|
37
|
+
readonly applyNumberFormat?: boolean;
|
|
38
|
+
readonly applyFont?: boolean;
|
|
39
|
+
readonly applyFill?: boolean;
|
|
40
|
+
readonly applyBorder?: boolean;
|
|
41
|
+
readonly applyAlignment?: boolean;
|
|
42
|
+
readonly alignment?: XlsxCellAlignment;
|
|
43
|
+
}
|
|
44
|
+
export interface XlsxStyles {
|
|
45
|
+
readonly numFmts: ReadonlyMap<number, string>;
|
|
46
|
+
readonly fonts: ReadonlyArray<XlsxFont>;
|
|
47
|
+
readonly fills: ReadonlyArray<XlsxFill>;
|
|
48
|
+
readonly borders: ReadonlyArray<XlsxBorder>;
|
|
49
|
+
readonly cellXfs: ReadonlyArray<XlsxCellXf>;
|
|
50
|
+
}
|
|
51
|
+
export declare const EMPTY_XLSX_STYLES: XlsxStyles;
|
|
52
|
+
export declare function parseXlsxStyles(data: Uint8Array): XlsxStyles;
|