@vdhewei/xlsx-template-lib 1.2.1
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 +7 -0
- package/dist/index.d.mts +470 -0
- package/dist/index.d.ts +470 -0
- package/dist/index.js +4017 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3941 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +44 -0
- package/src/index.ts +3 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4017 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
AddCommand: () => AddCommand,
|
|
34
|
+
AddCommandMust: () => AddCommandMust,
|
|
35
|
+
ArgumentData: () => ArgumentData,
|
|
36
|
+
ArgumentValue: () => ArgumentValue,
|
|
37
|
+
ArgumentValueLoader: () => ArgumentValueLoader,
|
|
38
|
+
BufferType: () => BufferType,
|
|
39
|
+
CompileContext: () => CompileContext,
|
|
40
|
+
DefaultPlaceholderCellValue: () => DefaultPlaceholderCellValue,
|
|
41
|
+
ExprResolver: () => ExprResolver,
|
|
42
|
+
RuleMapOptions: () => RuleMapOptions,
|
|
43
|
+
RuleToken: () => RuleToken,
|
|
44
|
+
TokenParserManger: () => TokenParserManger,
|
|
45
|
+
Workbook: () => Workbook,
|
|
46
|
+
columnLetterToNumber: () => columnLetterToNumber,
|
|
47
|
+
columnNumberToLetter: () => columnNumberToLetter,
|
|
48
|
+
commandExtendQuery: () => commandExtendQuery,
|
|
49
|
+
compileRuleSheetName: () => compileRuleSheetName,
|
|
50
|
+
compileWorkSheet: () => compileWorkSheet,
|
|
51
|
+
compileWorkSheetPlaceholder: () => compileWorkSheetPlaceholder,
|
|
52
|
+
defaultExtractPlaceholders: () => defaultExtractPlaceholders,
|
|
53
|
+
defaultFormatters: () => defaultFormatters,
|
|
54
|
+
defaultValueDotGet: () => defaultValueDotGet,
|
|
55
|
+
exceljs: () => import_exceljs.default,
|
|
56
|
+
generateCommandsXlsxTemplate: () => generateCommandsXlsxTemplate,
|
|
57
|
+
generateCommandsXlsxTemplateWithCompile: () => generateCommandsXlsxTemplateWithCompile,
|
|
58
|
+
generateXlsxTemplate: () => generateXlsxTemplate,
|
|
59
|
+
getCommands: () => getCommands,
|
|
60
|
+
getTokenParser: () => getTokenParser,
|
|
61
|
+
hasGeneratorToken: () => hasGeneratorToken,
|
|
62
|
+
isRuleToken: () => isRuleToken,
|
|
63
|
+
isUrl: () => isUrl,
|
|
64
|
+
loadWorkbook: () => loadWorkbook,
|
|
65
|
+
parseWorkSheetRules: () => parseWorkSheetRules,
|
|
66
|
+
registerTokenParser: () => registerTokenParser,
|
|
67
|
+
registerTokenParserMust: () => registerTokenParserMust,
|
|
68
|
+
resolveArgument: () => resolveArgument,
|
|
69
|
+
scanCellSetPlaceholder: () => scanCellSetPlaceholder,
|
|
70
|
+
toArrayBuffer: () => toArrayBuffer,
|
|
71
|
+
valueDotGet: () => valueDotGet,
|
|
72
|
+
workSheetSetPlaceholder: () => workSheetSetPlaceholder
|
|
73
|
+
});
|
|
74
|
+
module.exports = __toCommonJS(index_exports);
|
|
75
|
+
|
|
76
|
+
// src/core.ts
|
|
77
|
+
var path = __toESM(require("path"));
|
|
78
|
+
var fs = __toESM(require("fs"));
|
|
79
|
+
var etree = __toESM(require("elementtree"));
|
|
80
|
+
var import_jszip = __toESM(require("jszip"));
|
|
81
|
+
var console = __toESM(require("console"));
|
|
82
|
+
var import_image_size = require("image-size");
|
|
83
|
+
var import_types = require("util/types");
|
|
84
|
+
var DOCUMENT_RELATIONSHIP = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
|
|
85
|
+
var CALC_CHAIN_RELATIONSHIP = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain";
|
|
86
|
+
var SHARED_STRINGS_RELATIONSHIP = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
|
|
87
|
+
var HYPERLINK_RELATIONSHIP = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
|
|
88
|
+
var BufferType = /* @__PURE__ */ ((BufferType2) => {
|
|
89
|
+
BufferType2["Base64"] = "base64";
|
|
90
|
+
BufferType2["String"] = "string";
|
|
91
|
+
BufferType2["Text"] = "text";
|
|
92
|
+
BufferType2["Blob"] = "blob";
|
|
93
|
+
BufferType2["Array"] = "array";
|
|
94
|
+
BufferType2["NodeBuffer"] = "nodebuffer";
|
|
95
|
+
BufferType2["Uint8array"] = "uint8array";
|
|
96
|
+
BufferType2["Arraybuffer"] = "arraybuffer";
|
|
97
|
+
BufferType2["BinaryString"] = "binarystring";
|
|
98
|
+
return BufferType2;
|
|
99
|
+
})(BufferType || {});
|
|
100
|
+
function _getSimple(obj, key) {
|
|
101
|
+
if (key.includes("[")) {
|
|
102
|
+
const parts = key.split(/[\[\]]/);
|
|
103
|
+
const property = parts[0];
|
|
104
|
+
const index = parts[1];
|
|
105
|
+
if (property && index !== void 0) {
|
|
106
|
+
return obj?.[property]?.[index];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if ((0, import_types.isMap)(obj)) {
|
|
110
|
+
return obj.get(key);
|
|
111
|
+
}
|
|
112
|
+
return obj?.[key];
|
|
113
|
+
}
|
|
114
|
+
function valueDotGet(obj, path2, defaultValue) {
|
|
115
|
+
if (!path2 || !obj) return defaultValue;
|
|
116
|
+
const keys = path2.split(".");
|
|
117
|
+
let current = obj;
|
|
118
|
+
for (const key of keys) {
|
|
119
|
+
if (current === null || current === void 0) return defaultValue;
|
|
120
|
+
current = _getSimple(current, key);
|
|
121
|
+
}
|
|
122
|
+
return current === void 0 ? defaultValue : current;
|
|
123
|
+
}
|
|
124
|
+
function defaultValueDotGet(obj, p) {
|
|
125
|
+
return valueDotGet(obj, p.name, p.default || "");
|
|
126
|
+
}
|
|
127
|
+
var dateFormatter = (value, _placeholder, _key) => {
|
|
128
|
+
if (value instanceof Date) {
|
|
129
|
+
return Number(value.getTime() / (1e3 * 60 * 60 * 24) + 25569).toString();
|
|
130
|
+
}
|
|
131
|
+
return void 0;
|
|
132
|
+
};
|
|
133
|
+
var numberFormatter = (value, _placeholder, _key) => {
|
|
134
|
+
if (typeof value === "number") {
|
|
135
|
+
return value.toString();
|
|
136
|
+
}
|
|
137
|
+
return void 0;
|
|
138
|
+
};
|
|
139
|
+
var booleanFormatter = (value, _placeholder, _key) => {
|
|
140
|
+
if (typeof value === "boolean") {
|
|
141
|
+
return Number(value).toString();
|
|
142
|
+
}
|
|
143
|
+
return void 0;
|
|
144
|
+
};
|
|
145
|
+
var stringFormatter = (value, _placeholder, _key) => {
|
|
146
|
+
if (typeof value === "string") {
|
|
147
|
+
return value.toString();
|
|
148
|
+
}
|
|
149
|
+
return void 0;
|
|
150
|
+
};
|
|
151
|
+
var defaultRe = /\${(?:([^{}:]+?):)?([^{}:]+?)(?:\.([^{}:]+?))?(?::([^{}:]+?))??}/g;
|
|
152
|
+
var defaultExtractPlaceholders = (inputString, options) => {
|
|
153
|
+
const matches = [];
|
|
154
|
+
const re = options.customPlaceholderRegex || defaultRe;
|
|
155
|
+
if (options.enableDefaultParsing && options.customPlaceholderRegex) {
|
|
156
|
+
let match2;
|
|
157
|
+
while ((match2 = defaultRe.exec(inputString)) !== null) {
|
|
158
|
+
matches.push({
|
|
159
|
+
placeholder: match2[0],
|
|
160
|
+
type: match2[1] || "normal",
|
|
161
|
+
name: match2[2],
|
|
162
|
+
key: match2[3],
|
|
163
|
+
subType: match2[4],
|
|
164
|
+
full: match2[0].length === inputString.length
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
let match;
|
|
169
|
+
re.lastIndex = 0;
|
|
170
|
+
while ((match = re.exec(inputString)) !== null) {
|
|
171
|
+
if (options.enableDefaultParsing && options.customPlaceholderRegex) {
|
|
172
|
+
const isDuplicate = matches.some((m) => m.placeholder === match[0]);
|
|
173
|
+
if (isDuplicate) continue;
|
|
174
|
+
}
|
|
175
|
+
matches.push({
|
|
176
|
+
placeholder: match[0],
|
|
177
|
+
type: match[1] || "normal",
|
|
178
|
+
name: match[2],
|
|
179
|
+
key: match[3],
|
|
180
|
+
subType: match[4],
|
|
181
|
+
full: match[0].length === inputString.length
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return matches;
|
|
185
|
+
};
|
|
186
|
+
var defaultFormatters = [
|
|
187
|
+
dateFormatter,
|
|
188
|
+
numberFormatter,
|
|
189
|
+
booleanFormatter,
|
|
190
|
+
stringFormatter
|
|
191
|
+
];
|
|
192
|
+
var pattern = new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$", "i");
|
|
193
|
+
var isUrl = function(str) {
|
|
194
|
+
return !!pattern.test(str);
|
|
195
|
+
};
|
|
196
|
+
var toArrayBuffer = function(buffer) {
|
|
197
|
+
const ab = new ArrayBuffer(buffer.length);
|
|
198
|
+
const view = new Uint8Array(ab);
|
|
199
|
+
for (let i = 0; i < buffer.length; ++i) {
|
|
200
|
+
view[i] = buffer[i];
|
|
201
|
+
}
|
|
202
|
+
return ab;
|
|
203
|
+
};
|
|
204
|
+
var Workbook = class _Workbook {
|
|
205
|
+
// ==================== 构造函数 ====================
|
|
206
|
+
constructor(option) {
|
|
207
|
+
this.sharedStrings = [];
|
|
208
|
+
this.sharedStringsLookup = {};
|
|
209
|
+
this.sharedStringsPath = "";
|
|
210
|
+
this.sheets = [];
|
|
211
|
+
this.sheet = null;
|
|
212
|
+
this.workbook = null;
|
|
213
|
+
this.workbookPath = null;
|
|
214
|
+
this.contentTypes = null;
|
|
215
|
+
this.prefix = null;
|
|
216
|
+
this.workbookRels = null;
|
|
217
|
+
this.calChainRel = null;
|
|
218
|
+
this.calcChainPath = "";
|
|
219
|
+
// RichData 相关属性
|
|
220
|
+
this.richDataIsInit = false;
|
|
221
|
+
this._relsrichValueRel = null;
|
|
222
|
+
this.rdrichvalue = null;
|
|
223
|
+
this.rdrichvaluestructure = null;
|
|
224
|
+
this.rdRichValueTypes = null;
|
|
225
|
+
this.richValueRel = null;
|
|
226
|
+
this.metadata = null;
|
|
227
|
+
this.option = {
|
|
228
|
+
moveImages: false,
|
|
229
|
+
substituteAllTableRow: false,
|
|
230
|
+
moveSameLineImages: false,
|
|
231
|
+
imageRatio: 100,
|
|
232
|
+
pushDownPageBreakOnTableSubstitution: false,
|
|
233
|
+
imageRootPath: null,
|
|
234
|
+
handleImageError: null,
|
|
235
|
+
...option
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// ==================== parse 构造函数 ====================
|
|
239
|
+
static async parse(data, option) {
|
|
240
|
+
const w = new _Workbook(option);
|
|
241
|
+
await w.loadTemplate(data);
|
|
242
|
+
return w;
|
|
243
|
+
}
|
|
244
|
+
// ==================== 扩展方法 ====================
|
|
245
|
+
/**
|
|
246
|
+
* 添加自定义替换器
|
|
247
|
+
* @param replacer - 替换函数
|
|
248
|
+
* @returns this(支持链式调用)
|
|
249
|
+
*/
|
|
250
|
+
addReplacer(replacer) {
|
|
251
|
+
if (!this.option.replacers) {
|
|
252
|
+
this.option.replacers = [];
|
|
253
|
+
}
|
|
254
|
+
this.option.replacers.push(replacer);
|
|
255
|
+
return this;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* 添加自定义格式化器
|
|
259
|
+
* @param formatter - 格式化函数
|
|
260
|
+
* @returns this(支持链式调用)
|
|
261
|
+
*/
|
|
262
|
+
addFormatter(formatter) {
|
|
263
|
+
if (!this.option.formatters) {
|
|
264
|
+
this.option.formatters = [];
|
|
265
|
+
}
|
|
266
|
+
this.option.formatters.push(formatter);
|
|
267
|
+
return this;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* 设置替换前钩子
|
|
271
|
+
* @param hook - 钩子函数
|
|
272
|
+
* @returns this(支持链式调用)
|
|
273
|
+
*/
|
|
274
|
+
setBeforeReplaceHook(hook) {
|
|
275
|
+
this.option.beforeReplace = hook;
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* 设置替换后钩子
|
|
280
|
+
* @param hook - 钩子函数
|
|
281
|
+
* @returns this(支持链式调用)
|
|
282
|
+
*/
|
|
283
|
+
setAfterReplaceHook(hook) {
|
|
284
|
+
this.option.afterReplace = hook;
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 设置自定义占位符提取器
|
|
289
|
+
* @param extractor - 提取函数
|
|
290
|
+
* @returns this(支持链式调用)
|
|
291
|
+
*/
|
|
292
|
+
setPlaceholderExtractor(extractor) {
|
|
293
|
+
this.option.customPlaceholderExtractor = extractor;
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* 设置自定义模板正则表达式
|
|
298
|
+
* @param regex - 正则表达式
|
|
299
|
+
* @param enableDefaultParsing - 是否同时启用默认解析,默认 false
|
|
300
|
+
* @returns this(支持链式调用)
|
|
301
|
+
*/
|
|
302
|
+
setPlaceholderRegex(regex, enableDefaultParsing = false) {
|
|
303
|
+
this.option.customPlaceholderRegex = regex;
|
|
304
|
+
this.option.enableDefaultParsing = enableDefaultParsing;
|
|
305
|
+
return this;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* 设置数值查询器
|
|
309
|
+
* @param h QueryFunction - 设置数值查询器
|
|
310
|
+
* @returns this(支持链式调用)
|
|
311
|
+
*/
|
|
312
|
+
setQueryFunctionHandler(h) {
|
|
313
|
+
this.option.customQueryFunction = h;
|
|
314
|
+
return this;
|
|
315
|
+
}
|
|
316
|
+
// ==================== 扩展点执行方法 ====================
|
|
317
|
+
/**
|
|
318
|
+
* 执行自定义替换器链
|
|
319
|
+
* @param cell - 单元格元素
|
|
320
|
+
* @param stringValue - 字符串值
|
|
321
|
+
* @param placeholder - 占位符信息
|
|
322
|
+
* @param substitution - 替换值
|
|
323
|
+
* @returns 替换结果或 undefined
|
|
324
|
+
*/
|
|
325
|
+
executeReplacers(cell, stringValue, placeholder, substitution) {
|
|
326
|
+
if (this.option.customReplacer) {
|
|
327
|
+
const result = this.option.customReplacer(cell, stringValue, placeholder, substitution);
|
|
328
|
+
if (result !== void 0 && result !== null) {
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (this.option.replacers && this.option.replacers.length > 0) {
|
|
333
|
+
for (const replacer of this.option.replacers) {
|
|
334
|
+
const result = replacer(cell, stringValue, placeholder, substitution);
|
|
335
|
+
if (result !== void 0 && result !== null) {
|
|
336
|
+
return result;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return void 0;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 执行格式化器链
|
|
344
|
+
* @param value - 原始值
|
|
345
|
+
* @param placeholder - 占位符信息
|
|
346
|
+
* @param key - 可选键名
|
|
347
|
+
* @returns 格式化后的字符串
|
|
348
|
+
*/
|
|
349
|
+
executeFormatters(value, placeholder, key) {
|
|
350
|
+
if (this.option.formatters && this.option.formatters.length > 0) {
|
|
351
|
+
for (const formatter of this.option.formatters) {
|
|
352
|
+
const result = formatter(value, placeholder, key);
|
|
353
|
+
if (result !== void 0 && result !== null) {
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
for (const formatter of defaultFormatters) {
|
|
359
|
+
const result = formatter(value, placeholder, key);
|
|
360
|
+
if (result !== void 0 && result !== null) {
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return "";
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* 执行替换前钩子
|
|
368
|
+
*/
|
|
369
|
+
executeBeforeReplaceHook(stringValue, substitutions) {
|
|
370
|
+
if (this.option.beforeReplace) {
|
|
371
|
+
const result = this.option.beforeReplace(stringValue, substitutions);
|
|
372
|
+
if (result !== void 0 && result !== null) {
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return stringValue;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* 执行替换后钩子
|
|
380
|
+
*/
|
|
381
|
+
executeAfterReplaceHook(resultString, stringValue, substitutions) {
|
|
382
|
+
if (this.option.afterReplace) {
|
|
383
|
+
return this.option.afterReplace(resultString, stringValue, substitutions);
|
|
384
|
+
}
|
|
385
|
+
return resultString;
|
|
386
|
+
}
|
|
387
|
+
// ==================== 核心方法 ====================
|
|
388
|
+
/**
|
|
389
|
+
* 删除工作表
|
|
390
|
+
*/
|
|
391
|
+
async deleteSheet(sheetName) {
|
|
392
|
+
const sheet = await this.loadSheet(sheetName);
|
|
393
|
+
const sh = this.workbook.find(`sheets/sheet[@sheetId='${sheet.id}']`);
|
|
394
|
+
const sheets = this.workbook.findall("sheets/sheet");
|
|
395
|
+
const sheetIndex = sheets.indexOf(sh);
|
|
396
|
+
const definedNamesParent = this.workbook.find("definedNames");
|
|
397
|
+
if (definedNamesParent) {
|
|
398
|
+
const toRemove = [];
|
|
399
|
+
this.workbook.findall("definedNames/definedName").forEach((def) => {
|
|
400
|
+
if (def.attrib.localSheetId !== void 0) {
|
|
401
|
+
const localId = parseInt(def.attrib.localSheetId);
|
|
402
|
+
if (localId === sheetIndex) {
|
|
403
|
+
toRemove.push(def);
|
|
404
|
+
} else if (localId > sheetIndex) {
|
|
405
|
+
def.attrib.localSheetId = (localId - 1).toString();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
toRemove.forEach((def) => {
|
|
410
|
+
definedNamesParent.remove(def);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
this.workbook.find("sheets").remove(sh);
|
|
414
|
+
const rel = this.workbookRels.find(`Relationship[@Id='${sh.attrib["r:id"]}']`);
|
|
415
|
+
this.workbookRels.remove(rel);
|
|
416
|
+
this._rebuild();
|
|
417
|
+
return this;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* 复制工作表
|
|
421
|
+
*/
|
|
422
|
+
async copySheet(sheetName, copyName, binary = true) {
|
|
423
|
+
if (binary === false && !process.env.JEST_WORKER_ID) {
|
|
424
|
+
console.warn("Warning: copySheet() called with binary=false. UTF-8 characters may be corrupted.");
|
|
425
|
+
}
|
|
426
|
+
const sheet = await this.loadSheet(sheetName);
|
|
427
|
+
const newSheetIndex = (this.workbook.findall("sheets/sheet").length + 1).toString();
|
|
428
|
+
const fileName = "worksheets/sheet" + newSheetIndex + ".xml";
|
|
429
|
+
const arcName = this.prefix + "/" + fileName;
|
|
430
|
+
const sourceSheetFile = this.archive.file(sheet.filename);
|
|
431
|
+
let sheetContent = await sourceSheetFile.async(`nodebuffer`);
|
|
432
|
+
this.archive.file(arcName, sheetContent);
|
|
433
|
+
this.archive.files[arcName].options.compression = binary ? "STORE" : "DEFLATE";
|
|
434
|
+
const sheetContentType = etree.SubElement(this.contentTypes, "Override");
|
|
435
|
+
sheetContentType.attrib.PartName = "/" + arcName;
|
|
436
|
+
sheetContentType.attrib.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
|
|
437
|
+
const newSheet = etree.SubElement(this.workbook.find("sheets"), "sheet");
|
|
438
|
+
const finalSheetName = copyName || "Sheet" + newSheetIndex;
|
|
439
|
+
newSheet.attrib.name = finalSheetName;
|
|
440
|
+
newSheet.attrib.sheetId = newSheetIndex;
|
|
441
|
+
newSheet.attrib["r:id"] = "rId" + newSheetIndex;
|
|
442
|
+
this.workbook.findall("definedNames/definedName").forEach((element) => {
|
|
443
|
+
if (element.text && element.text.split("!").length && element.text.split("!")[0] == sheetName) {
|
|
444
|
+
const newDefinedName = etree.SubElement(this.workbook.find("definedNames"), "definedName", element.attrib);
|
|
445
|
+
newDefinedName.text = finalSheetName + "!" + element.text.split("!")[1];
|
|
446
|
+
const index = Number.parseInt(newSheetIndex, 10) - 1;
|
|
447
|
+
newDefinedName.attrib.localSheetId = `${index}`;
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const newRel = etree.SubElement(this.workbookRels, "Relationship");
|
|
451
|
+
newRel.attrib.Type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
|
|
452
|
+
newRel.attrib.Target = fileName;
|
|
453
|
+
const sourceRels = await this.loadSheetRels(sheet.filename);
|
|
454
|
+
const relFileName = "worksheets/_rels/sheet" + newSheetIndex + ".xml.rels";
|
|
455
|
+
const relArcName = this.prefix + "/" + relFileName;
|
|
456
|
+
const newRelsRoot = this.cloneElement(sourceRels.root, true);
|
|
457
|
+
const newCommentUuid = this.generateUUID();
|
|
458
|
+
sourceRels.root.findall("Relationship").forEach((rel, index) => {
|
|
459
|
+
const relType = rel.attrib.Type;
|
|
460
|
+
const target = rel.attrib.Target;
|
|
461
|
+
const needsFileCopy = [
|
|
462
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
|
|
463
|
+
"http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
|
|
464
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
|
|
465
|
+
];
|
|
466
|
+
if (needsFileCopy.indexOf(relType) !== -1) {
|
|
467
|
+
const sheetDirectory = path.dirname(sheet.filename);
|
|
468
|
+
const sourceFilePath = path.join(sheetDirectory, target).replace(/\\/g, "/");
|
|
469
|
+
const sourceFile = this.archive.file(sourceFilePath);
|
|
470
|
+
if (sourceFile) {
|
|
471
|
+
const fileExtension = path.extname(target);
|
|
472
|
+
const fileBaseName = path.basename(target, fileExtension);
|
|
473
|
+
const fileDir = path.dirname(target);
|
|
474
|
+
const baseNameWithoutNumber = fileBaseName.replace(/\d+$/, "");
|
|
475
|
+
const newFileName = baseNameWithoutNumber + newSheetIndex + fileExtension;
|
|
476
|
+
const newTarget = path.join(fileDir, newFileName).replace(/\\/g, "/");
|
|
477
|
+
const newFilePath = path.join(sheetDirectory, newTarget).replace(/\\/g, "/");
|
|
478
|
+
const content = sourceFile.async(`string`);
|
|
479
|
+
content.then((binaryContent) => {
|
|
480
|
+
if (relType === "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing") {
|
|
481
|
+
binaryContent = binaryContent.replace(/data="\d+"/, 'data="' + newSheetIndex + '"');
|
|
482
|
+
} else if (relType === "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments") {
|
|
483
|
+
const uuidWithoutBraces = newCommentUuid.replace(/[{}]/g, "");
|
|
484
|
+
binaryContent = binaryContent.replace(/(<author>tc=\{)[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}(\}<\/author>)/gi, "$1" + uuidWithoutBraces + "$2");
|
|
485
|
+
binaryContent = binaryContent.replace(/(xr:uid="\{)[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}(\}\")/gi, "$1" + uuidWithoutBraces + "$2");
|
|
486
|
+
const commentsContentType = etree.SubElement(this.contentTypes, "Override");
|
|
487
|
+
commentsContentType.attrib.PartName = "/" + newFilePath;
|
|
488
|
+
commentsContentType.attrib.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml";
|
|
489
|
+
} else if (relType === "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment") {
|
|
490
|
+
const uuidWithoutBraces = newCommentUuid.replace(/[{}]/g, "");
|
|
491
|
+
binaryContent = binaryContent.replace(/(\sid="\{)[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}(\}")/gi, "$1" + uuidWithoutBraces + "$2");
|
|
492
|
+
const threadedCommentContentType = etree.SubElement(this.contentTypes, "Override");
|
|
493
|
+
threadedCommentContentType.attrib.PartName = "/" + newFilePath;
|
|
494
|
+
threadedCommentContentType.attrib.ContentType = "application/vnd.ms-excel.threadedcomments+xml";
|
|
495
|
+
}
|
|
496
|
+
this.archive.file(newFilePath, binaryContent);
|
|
497
|
+
this.archive.files[newFilePath].options.compression = binary ? "STORE" : "DEFLATE";
|
|
498
|
+
const newRelInRels = newRelsRoot.findall("Relationship")[index];
|
|
499
|
+
if (newRelInRels) {
|
|
500
|
+
newRelInRels.attrib.Target = newTarget;
|
|
501
|
+
}
|
|
502
|
+
}).catch((err) => {
|
|
503
|
+
console.log(err);
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
this.archive.file(relArcName, etree.tostring(newRelsRoot, { encoding: "utf-8" }));
|
|
509
|
+
this.archive.files[relArcName].options.compression = binary ? "STORE" : "DEFLATE";
|
|
510
|
+
this.archive.file("[Content_Types].xml", etree.tostring(this.contentTypes, { encoding: "utf-8" }));
|
|
511
|
+
this._rebuild();
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* 部分重建(复制/删除工作表后)
|
|
516
|
+
*/
|
|
517
|
+
_rebuild() {
|
|
518
|
+
const order = ["worksheet", "theme", "styles", "sharedStrings"];
|
|
519
|
+
this.workbookRels.findall("*").sort((rel1, rel2) => {
|
|
520
|
+
const index1 = order.indexOf(path.basename(rel1.attrib.Type));
|
|
521
|
+
const index2 = order.indexOf(path.basename(rel2.attrib.Type));
|
|
522
|
+
if (index1 < 0 && index2 >= 0) return 1;
|
|
523
|
+
if (index1 >= 0 && index2 < 0) return -1;
|
|
524
|
+
if (index1 < 0 && index2 < 0) return 0;
|
|
525
|
+
if (index1 + index2 === 0) {
|
|
526
|
+
if (rel1.attrib.Id && rel2.attrib.Id) {
|
|
527
|
+
return rel1.attrib.Id.substring(3) - rel2.attrib.Id.substring(3);
|
|
528
|
+
}
|
|
529
|
+
return rel1._id - rel2._id;
|
|
530
|
+
}
|
|
531
|
+
return index1 - index2;
|
|
532
|
+
}).forEach((item, index) => {
|
|
533
|
+
item.attrib.Id = "rId" + (index + 1);
|
|
534
|
+
});
|
|
535
|
+
this.workbook.findall("sheets/sheet").forEach((item, index) => {
|
|
536
|
+
item.attrib["r:id"] = "rId" + (index + 1);
|
|
537
|
+
item.attrib.sheetId = (index + 1).toString();
|
|
538
|
+
});
|
|
539
|
+
this.archive.file(
|
|
540
|
+
this.prefix + "/_rels/" + path.basename(this.workbookPath) + ".rels",
|
|
541
|
+
etree.tostring(this.workbookRels, { encoding: "utf-8" })
|
|
542
|
+
);
|
|
543
|
+
this.archive.file(this.workbookPath, etree.tostring(this.workbook, { encoding: "utf-8" }));
|
|
544
|
+
this.sheets = this.loadSheets(this.prefix, this.workbook, this.workbookRels);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* 从字节数组加载 .xlsx 文件
|
|
548
|
+
*/
|
|
549
|
+
async loadTemplate(data) {
|
|
550
|
+
if (Buffer.isBuffer(data)) {
|
|
551
|
+
data = data.toString("binary");
|
|
552
|
+
}
|
|
553
|
+
this.archive = await import_jszip.default.loadAsync(data, { base64: false, checkCRC32: true });
|
|
554
|
+
const text = await this.archive.file("_rels/.rels").async("string");
|
|
555
|
+
const rels = etree.parse(text).getroot();
|
|
556
|
+
const workbookPath = rels.find(`Relationship[@Type='${DOCUMENT_RELATIONSHIP}']`).attrib.Target;
|
|
557
|
+
this.workbookPath = workbookPath;
|
|
558
|
+
this.prefix = path.dirname(workbookPath);
|
|
559
|
+
const workbookText = await this.archive.file(workbookPath).async(`string`);
|
|
560
|
+
this.workbook = etree.parse(workbookText).getroot();
|
|
561
|
+
const refText = await this.archive.file(this.prefix + "/_rels/" + path.basename(workbookPath) + ".rels").async(`string`);
|
|
562
|
+
this.workbookRels = etree.parse(refText).getroot();
|
|
563
|
+
this.sheets = this.loadSheets(this.prefix, this.workbook, this.workbookRels);
|
|
564
|
+
this.calChainRel = this.workbookRels.find(`Relationship[@Type='${CALC_CHAIN_RELATIONSHIP}']`);
|
|
565
|
+
if (this.calChainRel) {
|
|
566
|
+
this.calcChainPath = this.prefix + "/" + this.calChainRel.attrib.Target;
|
|
567
|
+
}
|
|
568
|
+
this.sharedStringsPath = this.prefix + "/" + this.workbookRels.find(`Relationship[@Type='${SHARED_STRINGS_RELATIONSHIP}']`).attrib.Target;
|
|
569
|
+
this.sharedStrings = [];
|
|
570
|
+
this.sharedStringsLookup = {};
|
|
571
|
+
const sharedText = await this.archive.file(this.sharedStringsPath).async(`string`);
|
|
572
|
+
etree.parse(sharedText).getroot().findall("si").forEach((si) => {
|
|
573
|
+
const t = { text: "" };
|
|
574
|
+
si.findall("t").forEach((tmp) => {
|
|
575
|
+
t.text += tmp.text;
|
|
576
|
+
});
|
|
577
|
+
si.findall("r/t").forEach((tmp) => {
|
|
578
|
+
t.text += tmp.text;
|
|
579
|
+
});
|
|
580
|
+
this.sharedStrings.push(t.text);
|
|
581
|
+
this.sharedStringsLookup[t.text] = this.sharedStrings.length - 1;
|
|
582
|
+
});
|
|
583
|
+
const contentTypeText = await this.archive.file("[Content_Types].xml").async(`string`);
|
|
584
|
+
this.contentTypes = etree.parse(contentTypeText).getroot();
|
|
585
|
+
const jpgType = this.contentTypes.find('Default[@Extension="jpg"]');
|
|
586
|
+
if (jpgType === null) {
|
|
587
|
+
etree.SubElement(this.contentTypes, "Default", { "ContentType": "image/png", "Extension": "jpg" });
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* 使用给定的替换数据对所有工作表进行插值
|
|
592
|
+
*/
|
|
593
|
+
async substituteAll(substitutions) {
|
|
594
|
+
const sheets = this.loadSheets(this.prefix, this.workbook, this.workbookRels);
|
|
595
|
+
for (let sheet of sheets) {
|
|
596
|
+
await this.substitute(sheet.id, substitutions);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* 使用给定的替换数据对指定工作表进行插值
|
|
601
|
+
*/
|
|
602
|
+
async substitute(sheetName, substitutions) {
|
|
603
|
+
const sheet = await this.loadSheet(sheetName);
|
|
604
|
+
this.sheet = sheet;
|
|
605
|
+
const dimension = sheet.root.find("dimension");
|
|
606
|
+
const sheetData = sheet.root.find("sheetData");
|
|
607
|
+
let currentRow = null;
|
|
608
|
+
let totalRowsInserted = 0;
|
|
609
|
+
let totalColumnsInserted = 0;
|
|
610
|
+
const namedTables = await this.loadTables(sheet.root, sheet.filename);
|
|
611
|
+
const rows = [];
|
|
612
|
+
let drawing = null;
|
|
613
|
+
const rels = await this.loadSheetRels(sheet.filename);
|
|
614
|
+
for (let row of sheetData.findall("row")) {
|
|
615
|
+
currentRow = this.getCurrentRow(row, totalRowsInserted);
|
|
616
|
+
row.attrib.r = `${currentRow}`;
|
|
617
|
+
rows.push(row);
|
|
618
|
+
let cells = [];
|
|
619
|
+
let cellsInserted = 0;
|
|
620
|
+
const newTableRows = [];
|
|
621
|
+
const cellsSubstituteTable = [];
|
|
622
|
+
for (let cell of row.findall("c")) {
|
|
623
|
+
let appendCell = true;
|
|
624
|
+
cell.attrib.r = this.getCurrentCell(cell, currentRow, cellsInserted);
|
|
625
|
+
if (cell.attrib.t === "s") {
|
|
626
|
+
const cellValue = cell.find("v");
|
|
627
|
+
const stringIndex = parseInt(cellValue.text.toString(), 10);
|
|
628
|
+
let strValue = this.sharedStrings[stringIndex];
|
|
629
|
+
if (strValue === void 0) {
|
|
630
|
+
break;
|
|
631
|
+
}
|
|
632
|
+
strValue = this.executeBeforeReplaceHook(strValue, substitutions);
|
|
633
|
+
for (let placeholder of this.extractPlaceholders(strValue)) {
|
|
634
|
+
let newCellsInserted = 0;
|
|
635
|
+
let substitution = this.valueGet(substitutions, placeholder);
|
|
636
|
+
const customResult = this.executeReplacers(cell, strValue, placeholder, substitution);
|
|
637
|
+
if (customResult !== void 0) {
|
|
638
|
+
strValue = customResult;
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
if (placeholder.full && placeholder.type === "table" && substitution instanceof Array) {
|
|
642
|
+
if (placeholder.subType === "image" && drawing == null) {
|
|
643
|
+
if (rels) {
|
|
644
|
+
drawing = await this.loadDrawing(sheet.root, sheet.filename, rels.root);
|
|
645
|
+
} else {
|
|
646
|
+
console.log("Need to implement initRels. Or init this with Excel");
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
cellsSubstituteTable.push(cell);
|
|
650
|
+
newCellsInserted = await this.substituteTable(
|
|
651
|
+
row,
|
|
652
|
+
newTableRows,
|
|
653
|
+
cells,
|
|
654
|
+
cell,
|
|
655
|
+
namedTables,
|
|
656
|
+
substitution,
|
|
657
|
+
placeholder,
|
|
658
|
+
drawing
|
|
659
|
+
);
|
|
660
|
+
if (newCellsInserted !== 0 || substitution.length) {
|
|
661
|
+
if (substitution.length === 1) {
|
|
662
|
+
appendCell = true;
|
|
663
|
+
}
|
|
664
|
+
if (substitution[0][placeholder.key] instanceof Array) {
|
|
665
|
+
appendCell = false;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
if (newCellsInserted !== 0) {
|
|
669
|
+
cellsInserted += newCellsInserted;
|
|
670
|
+
this.pushRight(this.workbook, sheet.root, cell.attrib.r, newCellsInserted);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (placeholder.full && placeholder.type === "normal" && substitution instanceof Array) {
|
|
674
|
+
appendCell = false;
|
|
675
|
+
newCellsInserted = this.substituteArray(cells, cell, substitution);
|
|
676
|
+
if (newCellsInserted !== 0) {
|
|
677
|
+
cellsInserted += newCellsInserted;
|
|
678
|
+
this.pushRight(this.workbook, sheet.root, cell.attrib.r, newCellsInserted);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (placeholder.type === "image" && placeholder.full) {
|
|
682
|
+
if (rels != null) {
|
|
683
|
+
if (drawing == null) {
|
|
684
|
+
drawing = await this.loadDrawing(sheet.root, sheet.filename, rels.root);
|
|
685
|
+
}
|
|
686
|
+
this.substituteImage(cell, strValue, placeholder, substitution, drawing);
|
|
687
|
+
} else {
|
|
688
|
+
console.log("Need to implement initRels. Or init this with Excel");
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (placeholder.type === "imageincell" && placeholder.full) {
|
|
692
|
+
await this.substituteImageInCell(cell, substitution);
|
|
693
|
+
} else {
|
|
694
|
+
if (placeholder.key) {
|
|
695
|
+
substitution = this.valueGet(substitutions, placeholder, true);
|
|
696
|
+
}
|
|
697
|
+
strValue = this.substituteScalar(cell, strValue, placeholder, substitution);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
strValue = this.executeAfterReplaceHook(strValue, strValue, substitutions);
|
|
701
|
+
}
|
|
702
|
+
if (appendCell) {
|
|
703
|
+
cells.push(cell);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
this.replaceChildren(row, cells);
|
|
707
|
+
if (cellsInserted !== 0) {
|
|
708
|
+
this.updateRowSpan(row, cellsInserted);
|
|
709
|
+
if (cellsInserted > totalColumnsInserted) {
|
|
710
|
+
totalColumnsInserted = cellsInserted;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
if (newTableRows.length > 0) {
|
|
714
|
+
if (this.option["moveImages"] && rels) {
|
|
715
|
+
if (drawing == null) {
|
|
716
|
+
drawing = await this.loadDrawing(sheet.root, sheet.filename, rels.root);
|
|
717
|
+
}
|
|
718
|
+
if (drawing != null) {
|
|
719
|
+
this.moveAllImages(drawing, row.attrib.r, newTableRows.length);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
const cellsOverTable = row.findall("c").filter(
|
|
723
|
+
(cell) => !cellsSubstituteTable.includes(cell)
|
|
724
|
+
);
|
|
725
|
+
newTableRows.forEach((newRow) => {
|
|
726
|
+
if (this.option && this.option.substituteAllTableRow) {
|
|
727
|
+
cellsOverTable.forEach((cellOverTable) => {
|
|
728
|
+
const newCell = this.cloneElement(cellOverTable);
|
|
729
|
+
newCell.attrib.r = this.joinRef({
|
|
730
|
+
row: newRow.attrib.r,
|
|
731
|
+
col: this.splitRef(newCell.attrib.r).col
|
|
732
|
+
});
|
|
733
|
+
newRow.append(newCell);
|
|
734
|
+
});
|
|
735
|
+
const newSortRow = newRow.findall("c").sort((a, b) => {
|
|
736
|
+
const colA = this.splitRef(a.attrib.r).col;
|
|
737
|
+
const colB = this.splitRef(b.attrib.r).col;
|
|
738
|
+
return this.charToNum(colA) - this.charToNum(colB);
|
|
739
|
+
});
|
|
740
|
+
this.replaceChildren(newRow, newSortRow);
|
|
741
|
+
}
|
|
742
|
+
rows.push(newRow);
|
|
743
|
+
++totalRowsInserted;
|
|
744
|
+
});
|
|
745
|
+
this.pushDown(this.workbook, sheet.root, namedTables, currentRow, newTableRows.length);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
this.replaceChildren(sheetData, rows);
|
|
749
|
+
this.substituteTableColumnHeaders(namedTables, substitutions);
|
|
750
|
+
this.substituteHyperlinks(rels, substitutions);
|
|
751
|
+
if (dimension) {
|
|
752
|
+
if (totalRowsInserted > 0 || totalColumnsInserted > 0) {
|
|
753
|
+
const dimensionRange = this.splitRange(dimension.attrib.ref);
|
|
754
|
+
const dimensionEndRef = this.splitRef(dimensionRange.end);
|
|
755
|
+
dimensionEndRef.row += totalRowsInserted;
|
|
756
|
+
dimensionEndRef.col = this.numToChar(this.charToNum(dimensionEndRef.col) + totalColumnsInserted);
|
|
757
|
+
dimensionRange.end = this.joinRef(dimensionEndRef);
|
|
758
|
+
dimension.attrib.ref = this.joinRange(dimensionRange);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
sheetData.findall("row").forEach((row) => {
|
|
762
|
+
row.findall("c").forEach((cell) => {
|
|
763
|
+
const formulas = cell.findall("f");
|
|
764
|
+
if (formulas && formulas.length > 0) {
|
|
765
|
+
cell.findall("v").forEach((v) => {
|
|
766
|
+
cell.remove(v);
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
});
|
|
771
|
+
this.archive.file(sheet.filename, etree.tostring(sheet.root, { encoding: "utf-8" }));
|
|
772
|
+
this.archive.file(this.workbookPath, etree.tostring(this.workbook, { encoding: "utf-8" }));
|
|
773
|
+
if (rels) {
|
|
774
|
+
this.archive.file(rels.filename, etree.tostring(rels.root, { encoding: "utf-8" }));
|
|
775
|
+
}
|
|
776
|
+
this.writeRichData();
|
|
777
|
+
this.archive.file("[Content_Types].xml", etree.tostring(this.contentTypes, { encoding: "utf-8" }));
|
|
778
|
+
if (this.calcChainPath && this.archive.file(this.calcChainPath)) {
|
|
779
|
+
this.archive.remove(this.calcChainPath);
|
|
780
|
+
}
|
|
781
|
+
await this.writeSharedStrings();
|
|
782
|
+
this.writeTables(namedTables);
|
|
783
|
+
this.writeDrawing(drawing);
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* 生成新的二进制 .xlsx 文件
|
|
787
|
+
*/
|
|
788
|
+
async generate(options) {
|
|
789
|
+
return await this.archive.generateAsync(options);
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* 查询占位符合数据值
|
|
793
|
+
* @param substitutions 数据对象
|
|
794
|
+
* @param p 占位符
|
|
795
|
+
* @param full 是否fullKey
|
|
796
|
+
* @return any
|
|
797
|
+
*/
|
|
798
|
+
valueGet(substitutions, p, full) {
|
|
799
|
+
if (this.option.customQueryFunction === void 0) {
|
|
800
|
+
if (full !== void 0 && typeof full === "boolean" && full && p.key) {
|
|
801
|
+
return valueDotGet(substitutions, p.name + "." + p.key, p.default || "");
|
|
802
|
+
}
|
|
803
|
+
return valueDotGet(substitutions, p.name, p.default || "");
|
|
804
|
+
}
|
|
805
|
+
if (full !== void 0 && typeof full === "boolean" && full && p.key && !p.name.endsWith(`.${p.key}`)) {
|
|
806
|
+
p.name = p.name + "." + p.key;
|
|
807
|
+
}
|
|
808
|
+
return this.option.customQueryFunction(substitutions, p);
|
|
809
|
+
}
|
|
810
|
+
// ==================== 辅助方法 ====================
|
|
811
|
+
async writeSharedStrings() {
|
|
812
|
+
const content = await this.archive.file(this.sharedStringsPath).async("string");
|
|
813
|
+
const root = etree.parse(content).getroot();
|
|
814
|
+
const children = root.getchildren();
|
|
815
|
+
root.delSlice(0, children.length);
|
|
816
|
+
this.sharedStrings.forEach((string) => {
|
|
817
|
+
const si = etree.Element("si");
|
|
818
|
+
const t = etree.Element("t");
|
|
819
|
+
t.text = string;
|
|
820
|
+
si.append(t);
|
|
821
|
+
root.append(si);
|
|
822
|
+
});
|
|
823
|
+
root.attrib.count = `${this.sharedStrings.length}`;
|
|
824
|
+
root.attrib.uniqueCount = `${this.sharedStrings.length}`;
|
|
825
|
+
this.archive.file(this.sharedStringsPath, etree.tostring(root, { encoding: "utf-8" }));
|
|
826
|
+
}
|
|
827
|
+
addSharedString(s) {
|
|
828
|
+
const idx = this.sharedStrings.length;
|
|
829
|
+
this.sharedStrings.push(s);
|
|
830
|
+
this.sharedStringsLookup[s] = idx;
|
|
831
|
+
return idx;
|
|
832
|
+
}
|
|
833
|
+
stringIndex(s) {
|
|
834
|
+
let idx = this.sharedStringsLookup[s];
|
|
835
|
+
if (idx === void 0) {
|
|
836
|
+
idx = this.addSharedString(s);
|
|
837
|
+
}
|
|
838
|
+
return idx;
|
|
839
|
+
}
|
|
840
|
+
replaceString(oldString, newString) {
|
|
841
|
+
let idx = this.sharedStringsLookup[oldString];
|
|
842
|
+
if (idx === void 0) {
|
|
843
|
+
idx = this.addSharedString(newString);
|
|
844
|
+
} else {
|
|
845
|
+
this.sharedStrings[idx] = newString;
|
|
846
|
+
delete this.sharedStringsLookup[oldString];
|
|
847
|
+
this.sharedStringsLookup[newString] = idx;
|
|
848
|
+
}
|
|
849
|
+
return idx;
|
|
850
|
+
}
|
|
851
|
+
loadSheets(prefix, workbook, workbookRels) {
|
|
852
|
+
const sheets = [];
|
|
853
|
+
for (const sheet of workbook.findall("sheets/sheet")) {
|
|
854
|
+
const sheetId = sheet.attrib.sheetId;
|
|
855
|
+
const relId = sheet.attrib["r:id"];
|
|
856
|
+
const relationship = workbookRels.find(`Relationship[@Id='${relId}']`);
|
|
857
|
+
const filename = prefix + "/" + relationship.attrib.Target;
|
|
858
|
+
sheets.push({
|
|
859
|
+
root: sheet,
|
|
860
|
+
filename,
|
|
861
|
+
name: sheet.attrib.name,
|
|
862
|
+
id: parseInt(sheetId, 10)
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
return sheets;
|
|
866
|
+
}
|
|
867
|
+
async loadSheet(sheet) {
|
|
868
|
+
let info = null;
|
|
869
|
+
for (let i = 0; i < this.sheets.length; ++i) {
|
|
870
|
+
if (typeof sheet === "number" && this.sheets[i].id === sheet || this.sheets[i].name === sheet) {
|
|
871
|
+
info = this.sheets[i];
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (info === null && typeof sheet === "number") {
|
|
876
|
+
info = this.sheets[sheet - 1];
|
|
877
|
+
}
|
|
878
|
+
if (info === null) {
|
|
879
|
+
throw new Error("Sheet " + sheet + " not found");
|
|
880
|
+
}
|
|
881
|
+
const content = await this.archive.file(info.filename).async("string");
|
|
882
|
+
return {
|
|
883
|
+
filename: info.filename,
|
|
884
|
+
name: info.name,
|
|
885
|
+
id: info.id,
|
|
886
|
+
root: etree.parse(content).getroot()
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
async loadSheetRels(sheetFilename) {
|
|
890
|
+
const sheetDirectory = path.dirname(sheetFilename);
|
|
891
|
+
const sheetName = path.basename(sheetFilename);
|
|
892
|
+
const relsFilename = path.join(sheetDirectory, "_rels", sheetName + ".rels").replace(/\\/g, "/");
|
|
893
|
+
const relsFile = this.archive.file(relsFilename);
|
|
894
|
+
if (relsFile === null) {
|
|
895
|
+
return this.initSheetRels(sheetFilename);
|
|
896
|
+
}
|
|
897
|
+
const content = await relsFile.async("string");
|
|
898
|
+
return {
|
|
899
|
+
filename: relsFilename,
|
|
900
|
+
root: etree.parse(content).getroot()
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
initSheetRels(sheetFilename) {
|
|
904
|
+
const sheetDirectory = path.dirname(sheetFilename);
|
|
905
|
+
const sheetName = path.basename(sheetFilename);
|
|
906
|
+
const relsFilename = path.join(sheetDirectory, "_rels", sheetName + ".rels").replace(/\\/g, "/");
|
|
907
|
+
const element = etree.Element;
|
|
908
|
+
const ElementTree2 = etree.ElementTree;
|
|
909
|
+
const root = element("Relationships");
|
|
910
|
+
root.set("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
|
|
911
|
+
const relsEtree = new ElementTree2(root);
|
|
912
|
+
return {
|
|
913
|
+
filename: relsFilename,
|
|
914
|
+
root: relsEtree.getroot()
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
async loadDrawing(sheet, sheetFilename, rels) {
|
|
918
|
+
const sheetDirectory = path.dirname(sheetFilename);
|
|
919
|
+
const drawing = { filename: "", root: null };
|
|
920
|
+
const drawingPart = sheet.find("drawing");
|
|
921
|
+
if (drawingPart === null) {
|
|
922
|
+
return this.initDrawing(sheet, rels);
|
|
923
|
+
}
|
|
924
|
+
const relationshipId = drawingPart.attrib["r:id"];
|
|
925
|
+
const target = rels.find(`Relationship[@Id='${relationshipId}']`).attrib.Target;
|
|
926
|
+
const drawingFilename = path.join(sheetDirectory, target).replace(/\\/g, "/");
|
|
927
|
+
const drawContent = await this.archive.file(drawingFilename).async("string");
|
|
928
|
+
const drawingTree = etree.parse(drawContent);
|
|
929
|
+
drawing.filename = drawingFilename;
|
|
930
|
+
drawing.root = drawingTree.getroot();
|
|
931
|
+
drawing.relFilename = path.dirname(drawingFilename) + "/_rels/" + path.basename(drawingFilename) + ".rels";
|
|
932
|
+
const relFile = this.archive.file(drawing.relFilename);
|
|
933
|
+
if (relFile === null) {
|
|
934
|
+
drawing.relRoot = etree.Element("Relationships");
|
|
935
|
+
drawing.relRoot.set("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
|
|
936
|
+
} else {
|
|
937
|
+
const relContent = await relFile.async("string");
|
|
938
|
+
drawing.relRoot = etree.parse(relContent).getroot();
|
|
939
|
+
}
|
|
940
|
+
return drawing;
|
|
941
|
+
}
|
|
942
|
+
addContentType(partName, contentType) {
|
|
943
|
+
etree.SubElement(this.contentTypes, "Override", { "ContentType": contentType, "PartName": partName });
|
|
944
|
+
}
|
|
945
|
+
initDrawing(sheet, rels) {
|
|
946
|
+
const maxId = this.findMaxId(rels, "Relationship", "Id", /rId(\d*)/);
|
|
947
|
+
const rel = etree.SubElement(rels, "Relationship");
|
|
948
|
+
sheet.insert(sheet._children.length, etree.Element("drawing", { "r:id": "rId" + maxId }));
|
|
949
|
+
rel.set("Id", "rId" + maxId);
|
|
950
|
+
rel.set("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing");
|
|
951
|
+
const drawing = {};
|
|
952
|
+
const drawingFilename = "drawing" + this.findMaxFileId(/xl\/drawings\/drawing\d*\.xml/, /drawing(\d*)\.xml/) + ".xml";
|
|
953
|
+
rel.set("Target", "../drawings/" + drawingFilename);
|
|
954
|
+
drawing.root = etree.Element("xdr:wsDr");
|
|
955
|
+
drawing.root.set("xmlns:xdr", "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing");
|
|
956
|
+
drawing.root.set("xmlns:a", "http://schemas.openxmlformats.org/drawingml/2006/main");
|
|
957
|
+
drawing.filename = "xl/drawings/" + drawingFilename;
|
|
958
|
+
drawing.relFilename = "xl/drawings/_rels/" + drawingFilename + ".rels";
|
|
959
|
+
drawing.relRoot = etree.Element("Relationships");
|
|
960
|
+
drawing.relRoot.set("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
|
|
961
|
+
this.addContentType("/" + drawing.filename, "application/vnd.openxmlformats-officedocument.drawing+xml");
|
|
962
|
+
return drawing;
|
|
963
|
+
}
|
|
964
|
+
writeDrawing(drawing) {
|
|
965
|
+
if (drawing !== null) {
|
|
966
|
+
this.archive.file(drawing.filename, etree.tostring(drawing.root, { encoding: "utf-8" }));
|
|
967
|
+
this.archive.file(drawing.relFilename, etree.tostring(drawing.relRoot, { encoding: "utf-8" }));
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
moveAllImages(drawing, fromRow, nbRow) {
|
|
971
|
+
drawing.root.getchildren().forEach((drawElement) => {
|
|
972
|
+
if (drawElement.tag == "xdr:twoCellAnchor") {
|
|
973
|
+
this._moveTwoCellAnchor(drawElement, fromRow, nbRow);
|
|
974
|
+
}
|
|
975
|
+
});
|
|
976
|
+
}
|
|
977
|
+
_moveTwoCellAnchor(drawingElement, fromRow, nbRow) {
|
|
978
|
+
const _moveImage = (drawingElement2, fromRow2, nbRow2) => {
|
|
979
|
+
let num;
|
|
980
|
+
if (typeof nbRow2 === "string") {
|
|
981
|
+
num = Number.parseInt(nbRow2, 10);
|
|
982
|
+
} else {
|
|
983
|
+
num = nbRow2;
|
|
984
|
+
}
|
|
985
|
+
drawingElement2.find("xdr:from").find("xdr:row").text = Number.parseInt(drawingElement2.find("xdr:from").find("xdr:row").text, 10) + num;
|
|
986
|
+
drawingElement2.find("xdr:to").find("xdr:row").text = Number.parseInt(drawingElement2.find("xdr:to").find("xdr:row").text, 10) + num;
|
|
987
|
+
};
|
|
988
|
+
if (this.option["moveSameLineImages"]) {
|
|
989
|
+
if (parseInt(drawingElement.find("xdr:from").find("xdr:row").text) + 1 >= parseInt(fromRow)) {
|
|
990
|
+
_moveImage(drawingElement, fromRow, nbRow);
|
|
991
|
+
}
|
|
992
|
+
} else {
|
|
993
|
+
if (parseInt(drawingElement.find("xdr:from").find("xdr:row").text) + 1 > parseInt(fromRow)) {
|
|
994
|
+
_moveImage(drawingElement, fromRow, nbRow);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
async loadTables(sheet, sheetFilename) {
|
|
999
|
+
const sheetDirectory = path.dirname(sheetFilename);
|
|
1000
|
+
const sheetName = path.basename(sheetFilename);
|
|
1001
|
+
const relsFilename = sheetDirectory + "/_rels/" + sheetName + ".rels";
|
|
1002
|
+
const relsFile = this.archive.file(relsFilename);
|
|
1003
|
+
const tables = [];
|
|
1004
|
+
if (relsFile === null) {
|
|
1005
|
+
return tables;
|
|
1006
|
+
}
|
|
1007
|
+
const relsContent = await relsFile.async("string");
|
|
1008
|
+
const rels = etree.parse(relsContent).getroot();
|
|
1009
|
+
for (let tablePart of sheet.findall("tableParts/tablePart")) {
|
|
1010
|
+
const relationshipId = tablePart.attrib["r:id"];
|
|
1011
|
+
const target = rels.find(`Relationship[@Id='${relationshipId}']`).attrib.Target;
|
|
1012
|
+
const tableFilename = target.replace("..", this.prefix);
|
|
1013
|
+
const content = await this.archive.file(tableFilename).async("string");
|
|
1014
|
+
const tableTree = etree.parse(content);
|
|
1015
|
+
tables.push({
|
|
1016
|
+
filename: tableFilename,
|
|
1017
|
+
root: tableTree.getroot()
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
return tables;
|
|
1021
|
+
}
|
|
1022
|
+
writeTables(tables) {
|
|
1023
|
+
tables.forEach((namedTable) => {
|
|
1024
|
+
this.archive.file(namedTable.filename, etree.tostring(namedTable.root, { encoding: "utf-8" }));
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
substituteHyperlinks(rels, substitutions) {
|
|
1028
|
+
if (rels === null) {
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
const relationships = rels.root._children;
|
|
1032
|
+
relationships.forEach((relationship) => {
|
|
1033
|
+
if (relationship.attrib.Type === HYPERLINK_RELATIONSHIP) {
|
|
1034
|
+
let target = relationship.attrib.Target;
|
|
1035
|
+
target = decodeURI(decodeURI(target));
|
|
1036
|
+
this.extractPlaceholders(target).forEach((placeholder) => {
|
|
1037
|
+
const substitution = substitutions[placeholder.name];
|
|
1038
|
+
if (substitution === void 0) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
target = target.replace(placeholder.placeholder, this.stringify(substitution));
|
|
1042
|
+
relationship.attrib.Target = encodeURI(target);
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
substituteTableColumnHeaders(tables, substitutions) {
|
|
1048
|
+
tables.forEach((table) => {
|
|
1049
|
+
const root = table.root;
|
|
1050
|
+
const columns = root.find("tableColumns");
|
|
1051
|
+
const autoFilter = root.find("autoFilter");
|
|
1052
|
+
const tableRange = this.splitRange(root.attrib.ref);
|
|
1053
|
+
let idx = 0;
|
|
1054
|
+
let inserted = 0;
|
|
1055
|
+
const newColumns = [];
|
|
1056
|
+
columns.findall("tableColumn").forEach((col) => {
|
|
1057
|
+
++idx;
|
|
1058
|
+
col.attrib.id = Number(idx).toString();
|
|
1059
|
+
newColumns.push(col);
|
|
1060
|
+
let name = col.attrib.name;
|
|
1061
|
+
this.extractPlaceholders(name).forEach((placeholder) => {
|
|
1062
|
+
const substitution = substitutions[placeholder.name];
|
|
1063
|
+
if (substitution === void 0) {
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
if (placeholder.full && placeholder.type === "normal" && substitution instanceof Array) {
|
|
1067
|
+
substitution.forEach((element, i) => {
|
|
1068
|
+
let newCol = col;
|
|
1069
|
+
if (i > 0) {
|
|
1070
|
+
newCol = this.cloneElement(newCol);
|
|
1071
|
+
newCol.attrib.id = Number(++idx).toString();
|
|
1072
|
+
newColumns.push(newCol);
|
|
1073
|
+
++inserted;
|
|
1074
|
+
tableRange.end = this.nextCol(tableRange.end);
|
|
1075
|
+
}
|
|
1076
|
+
newCol.attrib.name = this.stringify(element);
|
|
1077
|
+
});
|
|
1078
|
+
} else {
|
|
1079
|
+
name = name.replace(placeholder.placeholder, this.stringify(substitution));
|
|
1080
|
+
col.attrib.name = name;
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
1084
|
+
this.replaceChildren(columns, newColumns);
|
|
1085
|
+
if (inserted > 0) {
|
|
1086
|
+
columns.attrib.count = Number(idx).toString();
|
|
1087
|
+
root.attrib.ref = this.joinRange(tableRange);
|
|
1088
|
+
if (autoFilter !== null) {
|
|
1089
|
+
autoFilter.attrib.ref = this.joinRange(tableRange);
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
const tableRoot = table.root;
|
|
1093
|
+
const tableRange2 = this.splitRange(tableRoot.attrib.ref);
|
|
1094
|
+
const tableStart = this.splitRef(tableRange2.start);
|
|
1095
|
+
const tableEnd = this.splitRef(tableRange2.end);
|
|
1096
|
+
if (tableRoot.attrib.totalsRowCount) {
|
|
1097
|
+
const autoFilter2 = tableRoot.find("autoFilter");
|
|
1098
|
+
if (autoFilter2 !== null) {
|
|
1099
|
+
autoFilter2.attrib.ref = this.joinRange({
|
|
1100
|
+
start: this.joinRef(tableStart),
|
|
1101
|
+
end: this.joinRef(tableEnd)
|
|
1102
|
+
});
|
|
1103
|
+
}
|
|
1104
|
+
++tableEnd.row;
|
|
1105
|
+
tableRoot.attrib.ref = this.joinRange({
|
|
1106
|
+
start: this.joinRef(tableStart),
|
|
1107
|
+
end: this.joinRef(tableEnd)
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* 提取字符串中可能存在的占位符标记
|
|
1114
|
+
* 支持扩展:自定义正则表达式和自定义提取器
|
|
1115
|
+
*/
|
|
1116
|
+
extractPlaceholders(inputString) {
|
|
1117
|
+
if (this.option.customPlaceholderExtractor) {
|
|
1118
|
+
return this.option.customPlaceholderExtractor(inputString, this.option);
|
|
1119
|
+
}
|
|
1120
|
+
return defaultExtractPlaceholders(inputString, this.option);
|
|
1121
|
+
}
|
|
1122
|
+
splitRef(ref) {
|
|
1123
|
+
const match = ref.match(/(?:(.+)!)?(\$)?([A-Z]+)?(\$)?([0-9]+)/);
|
|
1124
|
+
return {
|
|
1125
|
+
table: match && match[1] || null,
|
|
1126
|
+
colAbsolute: Boolean(match && match[2]),
|
|
1127
|
+
col: match && match[3] || "",
|
|
1128
|
+
rowAbsolute: Boolean(match && match[4]),
|
|
1129
|
+
row: parseInt(match && match[5], 10)
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
joinRef(ref) {
|
|
1133
|
+
return (ref.table ? ref.table + "!" : "") + (ref.colAbsolute ? "$" : "") + ref.col.toUpperCase() + (ref.rowAbsolute ? "$" : "") + Number(ref.row).toString();
|
|
1134
|
+
}
|
|
1135
|
+
nextCol(ref) {
|
|
1136
|
+
ref = ref.toUpperCase();
|
|
1137
|
+
return ref.replace(/[A-Z]+/, (match) => {
|
|
1138
|
+
return this.numToChar(this.charToNum(match) + 1);
|
|
1139
|
+
});
|
|
1140
|
+
}
|
|
1141
|
+
nextRow(ref) {
|
|
1142
|
+
ref = ref.toUpperCase();
|
|
1143
|
+
return ref.replace(/[0-9]+/, (match) => {
|
|
1144
|
+
return (parseInt(match, 10) + 1).toString();
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
charToNum(str) {
|
|
1148
|
+
let num = 0;
|
|
1149
|
+
if (typeof str === "string") {
|
|
1150
|
+
for (let idx = str.length - 1, iteration = 0; idx >= 0; --idx, ++iteration) {
|
|
1151
|
+
const thisChar = str.charCodeAt(idx) - 64;
|
|
1152
|
+
const multiplier = Math.pow(26, iteration);
|
|
1153
|
+
num += multiplier * thisChar;
|
|
1154
|
+
}
|
|
1155
|
+
} else {
|
|
1156
|
+
num = str;
|
|
1157
|
+
}
|
|
1158
|
+
return num;
|
|
1159
|
+
}
|
|
1160
|
+
numToChar(num) {
|
|
1161
|
+
let str = "";
|
|
1162
|
+
for (let i = 0; num > 0; ++i) {
|
|
1163
|
+
let remainder = num % 26;
|
|
1164
|
+
let charCode = remainder + 64;
|
|
1165
|
+
num = (num - remainder) / 26;
|
|
1166
|
+
if (remainder === 0) {
|
|
1167
|
+
charCode = 90;
|
|
1168
|
+
--num;
|
|
1169
|
+
}
|
|
1170
|
+
str = String.fromCharCode(charCode) + str;
|
|
1171
|
+
}
|
|
1172
|
+
return str;
|
|
1173
|
+
}
|
|
1174
|
+
generateUUID() {
|
|
1175
|
+
const hexDigits = "0123456789ABCDEF";
|
|
1176
|
+
let uuid = "{";
|
|
1177
|
+
for (let i = 0; i < 36; i++) {
|
|
1178
|
+
if (i === 8 || i === 13 || i === 18 || i === 23) {
|
|
1179
|
+
uuid += "-";
|
|
1180
|
+
} else {
|
|
1181
|
+
uuid += hexDigits[Math.floor(Math.random() * 16)];
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
uuid += "}";
|
|
1185
|
+
return uuid;
|
|
1186
|
+
}
|
|
1187
|
+
isRange(ref) {
|
|
1188
|
+
return ref.indexOf(":") !== -1;
|
|
1189
|
+
}
|
|
1190
|
+
isWithin(ref, startRef, endRef) {
|
|
1191
|
+
const start = this.splitRef(startRef);
|
|
1192
|
+
const end = this.splitRef(endRef);
|
|
1193
|
+
const target = this.splitRef(ref);
|
|
1194
|
+
start.col = `${this.charToNum(start.col)}`;
|
|
1195
|
+
end.col = `${this.charToNum(end.col)}`;
|
|
1196
|
+
target.col = `${this.charToNum(target.col)}`;
|
|
1197
|
+
return start.row <= target.row && target.row <= end.row && start.col <= target.col && target.col <= end.col;
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* 将任意类型的值转换为字符串
|
|
1201
|
+
* 支持扩展:使用自定义格式化器
|
|
1202
|
+
*/
|
|
1203
|
+
stringify(value, placeholder, key) {
|
|
1204
|
+
if (placeholder) {
|
|
1205
|
+
return this.executeFormatters(value, placeholder, key);
|
|
1206
|
+
}
|
|
1207
|
+
if (value instanceof Date) {
|
|
1208
|
+
return Number(value.getTime() / (1e3 * 60 * 60 * 24) + 25569).toString();
|
|
1209
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
1210
|
+
return Number(value).toString();
|
|
1211
|
+
} else if (typeof value === "string") {
|
|
1212
|
+
return String(value).toString();
|
|
1213
|
+
}
|
|
1214
|
+
return "";
|
|
1215
|
+
}
|
|
1216
|
+
insertCellValue(cell, substitution) {
|
|
1217
|
+
const cellValue = cell.find("v");
|
|
1218
|
+
const stringify = this.stringify(substitution);
|
|
1219
|
+
if (typeof substitution === "string" && substitution[0] === "=") {
|
|
1220
|
+
const formula = etree.Element("f");
|
|
1221
|
+
formula.text = substitution.substring(1);
|
|
1222
|
+
cell.insert(1, formula);
|
|
1223
|
+
delete cell.attrib.t;
|
|
1224
|
+
return formula.text.toString();
|
|
1225
|
+
}
|
|
1226
|
+
if (typeof substitution === "number" || substitution instanceof Date) {
|
|
1227
|
+
delete cell.attrib.t;
|
|
1228
|
+
cellValue.text = stringify;
|
|
1229
|
+
} else if (typeof substitution === "boolean") {
|
|
1230
|
+
cell.attrib.t = "b";
|
|
1231
|
+
cellValue.text = stringify;
|
|
1232
|
+
} else {
|
|
1233
|
+
cell.attrib.t = "s";
|
|
1234
|
+
cellValue.text = Number(this.stringIndex(stringify)).toString();
|
|
1235
|
+
}
|
|
1236
|
+
return stringify;
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* 执行单个值的替换
|
|
1240
|
+
* 支持扩展:调用自定义替换器
|
|
1241
|
+
*/
|
|
1242
|
+
substituteScalar(cell, string, placeholder, substitution) {
|
|
1243
|
+
const customResult = this.executeReplacers(cell, string, placeholder, substitution);
|
|
1244
|
+
if (customResult !== void 0) {
|
|
1245
|
+
if (placeholder.full) {
|
|
1246
|
+
return this.insertCellValue(cell, customResult);
|
|
1247
|
+
} else {
|
|
1248
|
+
cell.attrib.t = "s";
|
|
1249
|
+
return this.insertCellValue(cell, customResult);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
if (placeholder.full) {
|
|
1253
|
+
return this.insertCellValue(cell, substitution);
|
|
1254
|
+
} else {
|
|
1255
|
+
const newString = string.replace(placeholder.placeholder, this.stringify(substitution, placeholder));
|
|
1256
|
+
cell.attrib.t = "s";
|
|
1257
|
+
return this.insertCellValue(cell, newString);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
substituteArray(cells, cell, substitution) {
|
|
1261
|
+
let newCellsInserted = -1;
|
|
1262
|
+
let currentCell = cell.attrib.r;
|
|
1263
|
+
substitution.forEach((element) => {
|
|
1264
|
+
++newCellsInserted;
|
|
1265
|
+
if (newCellsInserted > 0) {
|
|
1266
|
+
currentCell = this.nextCol(currentCell);
|
|
1267
|
+
}
|
|
1268
|
+
const newCell = this.cloneElement(cell);
|
|
1269
|
+
this.insertCellValue(newCell, element);
|
|
1270
|
+
newCell.attrib.r = currentCell;
|
|
1271
|
+
cells.push(newCell);
|
|
1272
|
+
});
|
|
1273
|
+
return newCellsInserted;
|
|
1274
|
+
}
|
|
1275
|
+
async substituteTable(row, newTableRows, cells, cell, namedTables, substitution, placeholder, drawing) {
|
|
1276
|
+
let newCellsInserted = 0;
|
|
1277
|
+
if (substitution.length === 0) {
|
|
1278
|
+
delete cell.attrib.t;
|
|
1279
|
+
this.replaceChildren(cell, []);
|
|
1280
|
+
} else {
|
|
1281
|
+
const parentTables = namedTables.filter((namedTable) => {
|
|
1282
|
+
const range = this.splitRange(namedTable.root.attrib.ref);
|
|
1283
|
+
return this.isWithin(cell.attrib.r, range.start, range.end);
|
|
1284
|
+
});
|
|
1285
|
+
for (const [idx, element] of substitution.entries()) {
|
|
1286
|
+
let newRow;
|
|
1287
|
+
let newCell;
|
|
1288
|
+
let newCellsInsertedOnNewRow = 0;
|
|
1289
|
+
const newCells = [];
|
|
1290
|
+
const value = this.valueGet(element, placeholder);
|
|
1291
|
+
if (idx === 0) {
|
|
1292
|
+
if (value instanceof Array) {
|
|
1293
|
+
newCellsInserted = this.substituteArray(cells, cell, value);
|
|
1294
|
+
} else if (placeholder.subType == "image" && value != "") {
|
|
1295
|
+
this.substituteImage(cell, placeholder.placeholder, placeholder, value, drawing);
|
|
1296
|
+
} else if (placeholder.subType === "imageincell" && value != "") {
|
|
1297
|
+
await this.substituteImageInCell(cell, value);
|
|
1298
|
+
} else {
|
|
1299
|
+
const customResult = this.executeReplacers(cell, "", placeholder, value);
|
|
1300
|
+
if (customResult !== void 0) {
|
|
1301
|
+
this.insertCellValue(cell, customResult);
|
|
1302
|
+
} else {
|
|
1303
|
+
this.insertCellValue(cell, value);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
} else {
|
|
1307
|
+
if (idx - 1 < newTableRows.length) {
|
|
1308
|
+
newRow = newTableRows[idx - 1];
|
|
1309
|
+
} else {
|
|
1310
|
+
newRow = this.cloneElement(row, false);
|
|
1311
|
+
newRow.attrib.r = this.getCurrentRow(row, newTableRows.length + 1);
|
|
1312
|
+
newTableRows.push(newRow);
|
|
1313
|
+
}
|
|
1314
|
+
newCell = this.cloneElement(cell);
|
|
1315
|
+
newCell.attrib.r = this.joinRef({
|
|
1316
|
+
row: newRow.attrib.r,
|
|
1317
|
+
col: this.splitRef(newCell.attrib.r).col
|
|
1318
|
+
});
|
|
1319
|
+
if (value instanceof Array) {
|
|
1320
|
+
newCellsInsertedOnNewRow = this.substituteArray(newCells, newCell, value);
|
|
1321
|
+
newCells.forEach((nc) => {
|
|
1322
|
+
newRow.append(nc);
|
|
1323
|
+
});
|
|
1324
|
+
this.updateRowSpan(newRow, newCellsInsertedOnNewRow);
|
|
1325
|
+
} else if (placeholder.subType == "image" && value != "") {
|
|
1326
|
+
this.substituteImage(newCell, placeholder.placeholder, placeholder, value, drawing);
|
|
1327
|
+
} else if (placeholder.subType === "imageincell" && value != "") {
|
|
1328
|
+
await this.substituteImageInCell(newCell, value);
|
|
1329
|
+
newRow.append(newCell);
|
|
1330
|
+
} else {
|
|
1331
|
+
const customResult = this.executeReplacers(newCell, "", placeholder, value);
|
|
1332
|
+
if (customResult !== void 0) {
|
|
1333
|
+
this.insertCellValue(newCell, customResult);
|
|
1334
|
+
} else {
|
|
1335
|
+
this.insertCellValue(newCell, value);
|
|
1336
|
+
}
|
|
1337
|
+
newRow.append(newCell);
|
|
1338
|
+
}
|
|
1339
|
+
const mergeCell = this.sheet.root.findall("mergeCells/mergeCell").find((c) => this.splitRange(c.attrib.ref).start === cell.attrib.r);
|
|
1340
|
+
const isMergeCell = mergeCell != null;
|
|
1341
|
+
if (isMergeCell) {
|
|
1342
|
+
const originalMergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1343
|
+
const originalMergeStart = this.splitRef(originalMergeRange.start);
|
|
1344
|
+
const originalMergeEnd = this.splitRef(originalMergeRange.end);
|
|
1345
|
+
for (let column = this.charToNum(originalMergeStart.col) + 1; column <= this.charToNum(originalMergeEnd.col); column++) {
|
|
1346
|
+
const data = this.sheet.root.find("sheetData");
|
|
1347
|
+
const children = data.getchildren();
|
|
1348
|
+
const originalRow = children.find((f) => f.attrib.r == originalMergeStart.row);
|
|
1349
|
+
const col = this.numToChar(column);
|
|
1350
|
+
const originalCell = originalRow.getchildren().find((f) => f.attrib.r.startsWith(col));
|
|
1351
|
+
const additionalCell = this.cloneElement(originalCell);
|
|
1352
|
+
additionalCell.attrib.r = this.joinRef({
|
|
1353
|
+
row: newRow.attrib.r,
|
|
1354
|
+
col: this.numToChar(column)
|
|
1355
|
+
});
|
|
1356
|
+
newRow.append(additionalCell);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
parentTables.forEach((namedTable) => {
|
|
1360
|
+
const tableRoot = namedTable.root;
|
|
1361
|
+
const autoFilter = tableRoot.find("autoFilter");
|
|
1362
|
+
const range = this.splitRange(tableRoot.attrib.ref);
|
|
1363
|
+
if (!this.isWithin(newCell.attrib.r, range.start, range.end)) {
|
|
1364
|
+
range.end = this.nextRow(range.end);
|
|
1365
|
+
tableRoot.attrib.ref = this.joinRange(range);
|
|
1366
|
+
if (autoFilter !== null) {
|
|
1367
|
+
autoFilter.attrib.ref = tableRoot.attrib.ref;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
});
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return newCellsInserted;
|
|
1375
|
+
}
|
|
1376
|
+
async initRichData() {
|
|
1377
|
+
if (!this.richDataIsInit) {
|
|
1378
|
+
const _relsrichValueRel = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1379
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
1380
|
+
</Relationships>`;
|
|
1381
|
+
const rdrichvalue = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1382
|
+
<rvData xmlns="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" count="0">
|
|
1383
|
+
</rvData>`;
|
|
1384
|
+
const rdrichvaluestructure = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1385
|
+
<rvStructures xmlns="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" count="1">
|
|
1386
|
+
<s t="_localImage">
|
|
1387
|
+
<k n="_rvRel:LocalImageIdentifier" t="i"/>
|
|
1388
|
+
<k n="CalcOrigin" t="i"/>
|
|
1389
|
+
</s>
|
|
1390
|
+
</rvStructures>`;
|
|
1391
|
+
const rdRichValueTypes = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1392
|
+
<rvTypesInfo xmlns="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata2"
|
|
1393
|
+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x"
|
|
1394
|
+
xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
|
1395
|
+
<global>
|
|
1396
|
+
<keyFlags>
|
|
1397
|
+
<key name="_Self">
|
|
1398
|
+
<flag name="ExcludeFromFile" value="1"/>
|
|
1399
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1400
|
+
</key>
|
|
1401
|
+
<key name="_DisplayString">
|
|
1402
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1403
|
+
</key>
|
|
1404
|
+
<key name="_Flags">
|
|
1405
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1406
|
+
</key>
|
|
1407
|
+
<key name="_Format">
|
|
1408
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1409
|
+
</key>
|
|
1410
|
+
<key name="_SubLabel">
|
|
1411
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1412
|
+
</key>
|
|
1413
|
+
<key name="_Attribution">
|
|
1414
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1415
|
+
</key>
|
|
1416
|
+
<key name="_Icon">
|
|
1417
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1418
|
+
</key>
|
|
1419
|
+
<key name="_Display">
|
|
1420
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1421
|
+
</key>
|
|
1422
|
+
<key name="_CanonicalPropertyNames">
|
|
1423
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1424
|
+
</key>
|
|
1425
|
+
<key name="_ClassificationId">
|
|
1426
|
+
<flag name="ExcludeFromCalcComparison" value="1"/>
|
|
1427
|
+
</key>
|
|
1428
|
+
</keyFlags>
|
|
1429
|
+
</global>
|
|
1430
|
+
</rvTypesInfo>`;
|
|
1431
|
+
const richValueRel = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1432
|
+
<richValueRels xmlns="http://schemas.microsoft.com/office/spreadsheetml/2022/richvaluerel"
|
|
1433
|
+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
1434
|
+
</richValueRels>`;
|
|
1435
|
+
const metadata = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
1436
|
+
<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
1437
|
+
xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata">
|
|
1438
|
+
<metadataTypes count="1">
|
|
1439
|
+
<metadataType name="XLRICHVALUE" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1"/>
|
|
1440
|
+
</metadataTypes>
|
|
1441
|
+
<futureMetadata name="XLRICHVALUE" count="0">
|
|
1442
|
+
</futureMetadata>
|
|
1443
|
+
<valueMetadata count="0">
|
|
1444
|
+
</valueMetadata>
|
|
1445
|
+
</metadata>`;
|
|
1446
|
+
const _relsrichValueRelFileName = "xl/richData/_rels/richValueRel.xml.rels";
|
|
1447
|
+
const rdrichvalueFileName = "xl/richData/rdrichvalue.xml";
|
|
1448
|
+
const rdrichvaluestructureFileName = "xl/richData/rdrichvaluestructure.xml";
|
|
1449
|
+
const rdRichValueTypesFileName = "xl/richData/rdRichValueTypes.xml";
|
|
1450
|
+
const richValueRelFileName = "xl/richData/richValueRel.xml";
|
|
1451
|
+
const metadataFileName = "xl/metadata.xml";
|
|
1452
|
+
this._relsrichValueRel = etree.parse(_relsrichValueRel).getroot();
|
|
1453
|
+
this.rdrichvalue = etree.parse(rdrichvalue).getroot();
|
|
1454
|
+
this.rdrichvaluestructure = etree.parse(rdrichvaluestructure).getroot();
|
|
1455
|
+
this.rdRichValueTypes = etree.parse(rdRichValueTypes).getroot();
|
|
1456
|
+
this.richValueRel = etree.parse(richValueRel).getroot();
|
|
1457
|
+
this.metadata = etree.parse(metadata).getroot();
|
|
1458
|
+
if (this.archive.file(_relsrichValueRelFileName)) {
|
|
1459
|
+
const content = await this.archive.file(_relsrichValueRelFileName).async("string");
|
|
1460
|
+
this._relsrichValueRel = etree.parse(content).getroot();
|
|
1461
|
+
}
|
|
1462
|
+
if (this.archive.file(rdrichvalueFileName)) {
|
|
1463
|
+
const content = await this.archive.file(rdrichvalueFileName).async("string");
|
|
1464
|
+
this.rdrichvalue = etree.parse(content).getroot();
|
|
1465
|
+
}
|
|
1466
|
+
if (this.archive.file(rdrichvaluestructureFileName)) {
|
|
1467
|
+
const content = await this.archive.file(rdrichvaluestructureFileName).async("string");
|
|
1468
|
+
this.rdrichvaluestructure = etree.parse(content).getroot();
|
|
1469
|
+
}
|
|
1470
|
+
if (this.archive.file(rdRichValueTypesFileName)) {
|
|
1471
|
+
const content = await this.archive.file(rdRichValueTypesFileName).async("string");
|
|
1472
|
+
this.rdRichValueTypes = etree.parse(content).getroot();
|
|
1473
|
+
}
|
|
1474
|
+
if (this.archive.file(richValueRelFileName)) {
|
|
1475
|
+
const content = await this.archive.file(richValueRelFileName).async("string");
|
|
1476
|
+
this.richValueRel = etree.parse(content).getroot();
|
|
1477
|
+
}
|
|
1478
|
+
if (this.archive.file(metadataFileName)) {
|
|
1479
|
+
const content = await this.archive.file(metadataFileName).async("string");
|
|
1480
|
+
this.metadata = etree.parse(content).getroot();
|
|
1481
|
+
}
|
|
1482
|
+
this.richDataIsInit = true;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
writeRichDataAlreadyExist(element, elementSearchName, attributeName, attributeValue) {
|
|
1486
|
+
for (const e of element.findall(elementSearchName)) {
|
|
1487
|
+
if (e.attrib[attributeName] == attributeValue) {
|
|
1488
|
+
return true;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
return false;
|
|
1492
|
+
}
|
|
1493
|
+
writeRichData() {
|
|
1494
|
+
if (this.richDataIsInit) {
|
|
1495
|
+
const _relsrichValueRelFileName = "xl/richData/_rels/richValueRel.xml.rels";
|
|
1496
|
+
const rdrichvalueFileName = "xl/richData/rdrichvalue.xml";
|
|
1497
|
+
const rdrichvaluestructureFileName = "xl/richData/rdrichvaluestructure.xml";
|
|
1498
|
+
const rdRichValueTypesFileName = "xl/richData/rdRichValueTypes.xml";
|
|
1499
|
+
const richValueRelFileName = "xl/richData/richValueRel.xml";
|
|
1500
|
+
const metadataFileName = "xl/metadata.xml";
|
|
1501
|
+
const options = { encoding: "utf-8" };
|
|
1502
|
+
this.archive.file(_relsrichValueRelFileName, etree.tostring(this._relsrichValueRel, options));
|
|
1503
|
+
this.archive.file(rdrichvalueFileName, etree.tostring(this.rdrichvalue, options));
|
|
1504
|
+
this.archive.file(rdrichvaluestructureFileName, etree.tostring(this.rdrichvaluestructure, options));
|
|
1505
|
+
this.archive.file(rdRichValueTypesFileName, etree.tostring(this.rdRichValueTypes, options));
|
|
1506
|
+
this.archive.file(richValueRelFileName, etree.tostring(this.richValueRel, options));
|
|
1507
|
+
this.archive.file(metadataFileName, etree.tostring(this.metadata, options));
|
|
1508
|
+
const broadsideMax = this.findMaxId(this.workbookRels, "Relationship", "Id", /rId(\d*)/);
|
|
1509
|
+
let _rel;
|
|
1510
|
+
if (!this.writeRichDataAlreadyExist(this.workbookRels, "Relationship", "Target", "richData/rdrichvaluestructure.xml")) {
|
|
1511
|
+
_rel = etree.SubElement(this.workbookRels, "Relationship");
|
|
1512
|
+
_rel.set("Id", "rId" + broadsideMax);
|
|
1513
|
+
_rel.set("Type", "http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure");
|
|
1514
|
+
_rel.set("Target", "richData/rdrichvaluestructure.xml");
|
|
1515
|
+
}
|
|
1516
|
+
if (!this.writeRichDataAlreadyExist(this.workbookRels, "Relationship", "Target", "richData/rdrichvalue.xml")) {
|
|
1517
|
+
_rel = etree.SubElement(this.workbookRels, "Relationship");
|
|
1518
|
+
_rel.set("Id", "rId" + (broadsideMax + 1));
|
|
1519
|
+
_rel.set("Type", "http://schemas.microsoft.com/office/2017/06/relationships/rdRichValue");
|
|
1520
|
+
_rel.set("Target", "richData/rdrichvalue.xml");
|
|
1521
|
+
}
|
|
1522
|
+
if (!this.writeRichDataAlreadyExist(this.workbookRels, "Relationship", "Target", "richData/richValueRel.xml")) {
|
|
1523
|
+
_rel = etree.SubElement(this.workbookRels, "Relationship");
|
|
1524
|
+
_rel.set("Id", "rId" + (broadsideMax + 2));
|
|
1525
|
+
_rel.set("Type", "http://schemas.microsoft.com/office/2022/10/relationships/richValueRel");
|
|
1526
|
+
_rel.set("Target", "richData/richValueRel.xml");
|
|
1527
|
+
}
|
|
1528
|
+
if (!this.writeRichDataAlreadyExist(this.workbookRels, "Relationship", "Target", "metadata.xml")) {
|
|
1529
|
+
_rel = etree.SubElement(this.workbookRels, "Relationship");
|
|
1530
|
+
_rel.set("Id", "rId" + (broadsideMax + 3));
|
|
1531
|
+
_rel.set("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata");
|
|
1532
|
+
_rel.set("Target", "metadata.xml");
|
|
1533
|
+
}
|
|
1534
|
+
if (!this.writeRichDataAlreadyExist(this.workbookRels, "Relationship", "Target", "richData/rdRichValueTypes.xml")) {
|
|
1535
|
+
_rel = etree.SubElement(this.workbookRels, "Relationship");
|
|
1536
|
+
_rel.set("Id", "rId" + (broadsideMax + 4));
|
|
1537
|
+
_rel.set("Type", "http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueTypes");
|
|
1538
|
+
_rel.set("Target", "richData/rdRichValueTypes.xml");
|
|
1539
|
+
}
|
|
1540
|
+
if (!this.writeRichDataAlreadyExist(this.contentTypes, "Override", "PartName", "/xl/metadata.xml")) {
|
|
1541
|
+
let ctOverride = etree.SubElement(this.contentTypes, "Override");
|
|
1542
|
+
ctOverride.set("PartName", "/xl/metadata.xml");
|
|
1543
|
+
ctOverride.set("ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml");
|
|
1544
|
+
}
|
|
1545
|
+
if (!this.writeRichDataAlreadyExist(this.contentTypes, "Override", "PartName", "/xl/richData/richValueRel.xml")) {
|
|
1546
|
+
let ctOverride = etree.SubElement(this.contentTypes, "Override");
|
|
1547
|
+
ctOverride.set("PartName", "/xl/richData/richValueRel.xml");
|
|
1548
|
+
ctOverride.set("ContentType", "application/vnd.ms-excel.richvaluerel+xml");
|
|
1549
|
+
}
|
|
1550
|
+
if (!this.writeRichDataAlreadyExist(this.contentTypes, "Override", "PartName", "/xl/richData/rdrichvalue.xml")) {
|
|
1551
|
+
let ctOverride = etree.SubElement(this.contentTypes, "Override");
|
|
1552
|
+
ctOverride.set("PartName", "/xl/richData/rdrichvalue.xml");
|
|
1553
|
+
ctOverride.set("ContentType", "application/vnd.ms-excel.rdrichvalue+xml");
|
|
1554
|
+
}
|
|
1555
|
+
if (!this.writeRichDataAlreadyExist(this.contentTypes, "Override", "PartName", "/xl/richData/rdrichvaluestructure.xml")) {
|
|
1556
|
+
let ctOverride = etree.SubElement(this.contentTypes, "Override");
|
|
1557
|
+
ctOverride.set("PartName", "/xl/richData/rdrichvaluestructure.xml");
|
|
1558
|
+
ctOverride.set("ContentType", "application/vnd.ms-excel.rdrichvaluestructure+xml");
|
|
1559
|
+
}
|
|
1560
|
+
if (!this.writeRichDataAlreadyExist(this.contentTypes, "Override", "PartName", "/xl/richData/rdRichValueTypes.xml")) {
|
|
1561
|
+
let ctOverride = etree.SubElement(this.contentTypes, "Override");
|
|
1562
|
+
ctOverride.set("PartName", "/xl/richData/rdRichValueTypes.xml");
|
|
1563
|
+
ctOverride.set("ContentType", "application/vnd.ms-excel.rdrichvaluetypes+xml");
|
|
1564
|
+
}
|
|
1565
|
+
this._rebuild();
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
async substituteImageInCell(cell, substitution) {
|
|
1569
|
+
if (substitution == null || substitution == "") {
|
|
1570
|
+
this.insertCellValue(cell, "");
|
|
1571
|
+
return true;
|
|
1572
|
+
}
|
|
1573
|
+
await this.initRichData();
|
|
1574
|
+
const maxFildId = this.findMaxFileId(/xl\/media\/image\d*\..*/, /image(\d*)\./);
|
|
1575
|
+
const fileExtension = "jpg";
|
|
1576
|
+
try {
|
|
1577
|
+
substitution = this.imageToBuffer(substitution);
|
|
1578
|
+
} catch (error) {
|
|
1579
|
+
if (this.option && this.option.handleImageError && typeof this.option.handleImageError === "function") {
|
|
1580
|
+
this.option.handleImageError(substitution, error);
|
|
1581
|
+
} else {
|
|
1582
|
+
throw error;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
this.archive.file("xl/media/image" + maxFildId + "." + fileExtension, toArrayBuffer(substitution), {
|
|
1586
|
+
binary: true,
|
|
1587
|
+
base64: false
|
|
1588
|
+
});
|
|
1589
|
+
const maxIdRichData = this.findMaxId(this._relsrichValueRel, "Relationship", "Id", /rId(\d*)/);
|
|
1590
|
+
const _rel = etree.SubElement(this._relsrichValueRel, "Relationship");
|
|
1591
|
+
_rel.set("Id", "rId" + maxIdRichData);
|
|
1592
|
+
_rel.set("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
|
|
1593
|
+
_rel.set("Target", "../media/image" + maxFildId + "." + fileExtension);
|
|
1594
|
+
const currentCountedRichValue = this.rdrichvalue.get("count");
|
|
1595
|
+
this.rdrichvalue.set("count", parseInt(currentCountedRichValue) + 1);
|
|
1596
|
+
const rv = etree.SubElement(this.rdrichvalue, "rv");
|
|
1597
|
+
rv.set("s", "0");
|
|
1598
|
+
const firstV = etree.SubElement(rv, "v");
|
|
1599
|
+
const secondV = etree.SubElement(rv, "v");
|
|
1600
|
+
firstV.text = currentCountedRichValue;
|
|
1601
|
+
secondV.text = "5";
|
|
1602
|
+
const rel = etree.SubElement(this.richValueRel, "rel");
|
|
1603
|
+
rel.set("r:id", "rId" + maxIdRichData);
|
|
1604
|
+
const futureMetadata = this.metadata.findall("futureMetadata").find((fm) => {
|
|
1605
|
+
return fm.attrib.name === "XLRICHVALUE";
|
|
1606
|
+
});
|
|
1607
|
+
const futureMetadataCount = futureMetadata.get("count");
|
|
1608
|
+
futureMetadata.set("count", parseInt(futureMetadataCount) + 1);
|
|
1609
|
+
const bk = etree.SubElement(futureMetadata, "bk");
|
|
1610
|
+
const extLst = etree.SubElement(bk, "extLst");
|
|
1611
|
+
const ext = etree.SubElement(extLst, "ext");
|
|
1612
|
+
ext.set("uri", "{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}");
|
|
1613
|
+
const xlrd_rvb = etree.SubElement(ext, "xlrd:rvb");
|
|
1614
|
+
xlrd_rvb.set("i", futureMetadataCount);
|
|
1615
|
+
const valueMetadataCount = this.metadata.find("valueMetadata").get("count");
|
|
1616
|
+
this.metadata.find("valueMetadata").set("count", parseInt(valueMetadataCount) + 1);
|
|
1617
|
+
const bk_VM = etree.SubElement(this.metadata.find("valueMetadata"), "bk");
|
|
1618
|
+
const rc = etree.SubElement(bk_VM, "rc");
|
|
1619
|
+
const XLRICHVALUEMetaDataTypeIndex = this.metadata.find("metadataTypes").findall("metadataType").findIndex((el) => {
|
|
1620
|
+
return el.attrib.name === "XLRICHVALUE";
|
|
1621
|
+
});
|
|
1622
|
+
rc.set("t", "" + (XLRICHVALUEMetaDataTypeIndex + 1));
|
|
1623
|
+
rc.set("v", valueMetadataCount);
|
|
1624
|
+
cell.set("t", "e");
|
|
1625
|
+
cell.set("vm", parseInt(currentCountedRichValue) + 1);
|
|
1626
|
+
this.insertCellValue(cell, "#VALUE!");
|
|
1627
|
+
return true;
|
|
1628
|
+
}
|
|
1629
|
+
substituteImage(cell, string, placeholder, substitution, drawing) {
|
|
1630
|
+
this.substituteScalar(cell, string, placeholder, "");
|
|
1631
|
+
if (substitution == null || substitution == "") {
|
|
1632
|
+
return true;
|
|
1633
|
+
}
|
|
1634
|
+
const maxId = this.findMaxId(drawing.relRoot, "Relationship", "Id", /rId(\d*)/);
|
|
1635
|
+
const maxFildId = this.findMaxFileId(/xl\/media\/image\d*.jpg/, /image(\d*)\.jpg/);
|
|
1636
|
+
const rel = etree.SubElement(drawing.relRoot, "Relationship");
|
|
1637
|
+
rel.set("Id", "rId" + maxId);
|
|
1638
|
+
rel.set("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
|
|
1639
|
+
rel.set("Target", "../media/image" + maxFildId + ".jpg");
|
|
1640
|
+
try {
|
|
1641
|
+
substitution = this.imageToBuffer(substitution);
|
|
1642
|
+
} catch (error) {
|
|
1643
|
+
if (this.option && this.option.handleImageError && typeof this.option.handleImageError === "function") {
|
|
1644
|
+
this.option.handleImageError(substitution, error);
|
|
1645
|
+
} else {
|
|
1646
|
+
throw error;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
this.archive.file("xl/media/image" + maxFildId + ".jpg", toArrayBuffer(substitution), {
|
|
1650
|
+
binary: true,
|
|
1651
|
+
base64: false
|
|
1652
|
+
});
|
|
1653
|
+
const dimension = (0, import_image_size.imageSize)(substitution);
|
|
1654
|
+
let imageWidth = this.pixelsToEMUs(dimension.width);
|
|
1655
|
+
let imageHeight = this.pixelsToEMUs(dimension.height);
|
|
1656
|
+
let imageInMergeCell = false;
|
|
1657
|
+
for (let mergeCell of this.sheet.root.findall("mergeCells/mergeCell")) {
|
|
1658
|
+
if (this.cellInMergeCells(cell, mergeCell)) {
|
|
1659
|
+
const mergeCellWidth = this.getWidthMergeCell(mergeCell, this.sheet);
|
|
1660
|
+
const mergeCellHeight = this.getHeightMergeCell(mergeCell, this.sheet);
|
|
1661
|
+
const mergeWidthEmus = this.columnWidthToEMUs(mergeCellWidth);
|
|
1662
|
+
const mergeHeightEmus = this.rowHeightToEMUs(mergeCellHeight);
|
|
1663
|
+
const widthRate = imageWidth / mergeWidthEmus;
|
|
1664
|
+
const heightRate = imageHeight / mergeHeightEmus;
|
|
1665
|
+
if (widthRate > heightRate) {
|
|
1666
|
+
imageWidth = Math.floor(imageWidth / widthRate);
|
|
1667
|
+
imageHeight = Math.floor(imageHeight / widthRate);
|
|
1668
|
+
} else {
|
|
1669
|
+
imageWidth = Math.floor(imageWidth / heightRate);
|
|
1670
|
+
imageHeight = Math.floor(imageHeight / heightRate);
|
|
1671
|
+
}
|
|
1672
|
+
imageInMergeCell = true;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
if (!imageInMergeCell) {
|
|
1676
|
+
let ratio = 100;
|
|
1677
|
+
if (this.option && this.option.imageRatio) {
|
|
1678
|
+
ratio = this.option.imageRatio;
|
|
1679
|
+
}
|
|
1680
|
+
if (ratio <= 0) {
|
|
1681
|
+
ratio = 100;
|
|
1682
|
+
}
|
|
1683
|
+
imageWidth = Math.floor(imageWidth * ratio / 100);
|
|
1684
|
+
imageHeight = Math.floor(imageHeight * ratio / 100);
|
|
1685
|
+
}
|
|
1686
|
+
const imagePart = etree.SubElement(drawing.root, "xdr:oneCellAnchor");
|
|
1687
|
+
const fromPart = etree.SubElement(imagePart, "xdr:from");
|
|
1688
|
+
const fromCol = etree.SubElement(fromPart, "xdr:col");
|
|
1689
|
+
fromCol.text = (this.charToNum(this.splitRef(cell.attrib.r).col) - 1).toString();
|
|
1690
|
+
const fromColOff = etree.SubElement(fromPart, "xdr:colOff");
|
|
1691
|
+
fromColOff.text = "0";
|
|
1692
|
+
const fromRow = etree.SubElement(fromPart, "xdr:row");
|
|
1693
|
+
fromRow.text = (this.splitRef(cell.attrib.r).row - 1).toString();
|
|
1694
|
+
const fromRowOff = etree.SubElement(fromPart, "xdr:rowOff");
|
|
1695
|
+
fromRowOff.text = "0";
|
|
1696
|
+
const extImagePart = etree.SubElement(imagePart, "xdr:ext", { cx: `${imageWidth}`, cy: `${imageHeight}` });
|
|
1697
|
+
const picNode = etree.SubElement(imagePart, "xdr:pic");
|
|
1698
|
+
const nvPicPr = etree.SubElement(picNode, "xdr:nvPicPr");
|
|
1699
|
+
const cNvPr = etree.SubElement(nvPicPr, "xdr:cNvPr", { id: `${maxId}`, name: "image_" + maxId, descr: "" });
|
|
1700
|
+
const cNvPicPr = etree.SubElement(nvPicPr, "xdr:cNvPicPr");
|
|
1701
|
+
const picLocks = etree.SubElement(cNvPicPr, "a:picLocks", { noChangeAspect: "1" });
|
|
1702
|
+
const blipFill = etree.SubElement(picNode, "xdr:blipFill");
|
|
1703
|
+
const blip = etree.SubElement(blipFill, "a:blip", {
|
|
1704
|
+
"xmlns:r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
|
|
1705
|
+
"r:embed": "rId" + maxId
|
|
1706
|
+
});
|
|
1707
|
+
const stretch = etree.SubElement(blipFill, "a:stretch");
|
|
1708
|
+
const fillRect = etree.SubElement(stretch, "a:fillRect");
|
|
1709
|
+
const spPr = etree.SubElement(picNode, "xdr:spPr");
|
|
1710
|
+
const xfrm = etree.SubElement(spPr, "a:xfrm");
|
|
1711
|
+
const off = etree.SubElement(xfrm, "a:off", { x: "0", y: "0" });
|
|
1712
|
+
const ext = etree.SubElement(xfrm, "a:ext", { cx: `${imageWidth}`, cy: `${imageHeight}` });
|
|
1713
|
+
const prstGeom = etree.SubElement(spPr, "a:prstGeom", { "prst": "rect" });
|
|
1714
|
+
const avLst = etree.SubElement(prstGeom, "a:avLst");
|
|
1715
|
+
const clientData = etree.SubElement(imagePart, "xdr:clientData");
|
|
1716
|
+
return true;
|
|
1717
|
+
}
|
|
1718
|
+
cloneElement(element, deep) {
|
|
1719
|
+
const newElement = etree.Element(element.tag, element.attrib);
|
|
1720
|
+
newElement.text = element.text;
|
|
1721
|
+
newElement.tail = element.tail;
|
|
1722
|
+
if (deep !== false) {
|
|
1723
|
+
element.getchildren().forEach((child) => {
|
|
1724
|
+
newElement.append(this.cloneElement(child, deep));
|
|
1725
|
+
});
|
|
1726
|
+
}
|
|
1727
|
+
return newElement;
|
|
1728
|
+
}
|
|
1729
|
+
replaceChildren(parent, children) {
|
|
1730
|
+
parent.delSlice(0, parent.len());
|
|
1731
|
+
children.forEach((child) => {
|
|
1732
|
+
parent.append(child);
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
getCurrentRow(row, rowsInserted) {
|
|
1736
|
+
return parseInt(row.attrib.r, 10) + rowsInserted;
|
|
1737
|
+
}
|
|
1738
|
+
getCurrentCell(cell, currentRow, cellsInserted) {
|
|
1739
|
+
const colRef = this.splitRef(cell.attrib.r).col;
|
|
1740
|
+
const colNum = this.charToNum(colRef);
|
|
1741
|
+
return this.joinRef({
|
|
1742
|
+
row: currentRow,
|
|
1743
|
+
col: this.numToChar(colNum + cellsInserted)
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
updateRowSpan(row, cellsInserted) {
|
|
1747
|
+
if (cellsInserted !== 0 && row.attrib.spans) {
|
|
1748
|
+
const rowSpan = row.attrib.spans.split(":").map((f) => parseInt(f, 10));
|
|
1749
|
+
rowSpan[1] += cellsInserted;
|
|
1750
|
+
row.attrib.spans = rowSpan.join(":");
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
splitRange(range) {
|
|
1754
|
+
const split = range.split(":");
|
|
1755
|
+
return {
|
|
1756
|
+
start: split[0],
|
|
1757
|
+
end: split[1]
|
|
1758
|
+
};
|
|
1759
|
+
}
|
|
1760
|
+
joinRange(range) {
|
|
1761
|
+
return range.start + ":" + range.end;
|
|
1762
|
+
}
|
|
1763
|
+
pushRight(workbook, sheet, currentCell, numCols) {
|
|
1764
|
+
const cellRef = this.splitRef(currentCell);
|
|
1765
|
+
const currentRow = cellRef.row;
|
|
1766
|
+
const currentCol = this.charToNum(cellRef.col);
|
|
1767
|
+
sheet.findall("mergeCells/mergeCell").forEach((mergeCell) => {
|
|
1768
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1769
|
+
const mergeStart = this.splitRef(mergeRange.start);
|
|
1770
|
+
const mergeStartCol = this.charToNum(mergeStart.col);
|
|
1771
|
+
const mergeEnd = this.splitRef(mergeRange.end);
|
|
1772
|
+
const mergeEndCol = this.charToNum(mergeEnd.col);
|
|
1773
|
+
if (mergeStart.row === currentRow && currentCol < mergeStartCol) {
|
|
1774
|
+
mergeStart.col = this.numToChar(mergeStartCol + numCols);
|
|
1775
|
+
mergeEnd.col = this.numToChar(mergeEndCol + numCols);
|
|
1776
|
+
mergeCell.attrib.ref = this.joinRange({
|
|
1777
|
+
start: this.joinRef(mergeStart),
|
|
1778
|
+
end: this.joinRef(mergeEnd)
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
});
|
|
1782
|
+
workbook.findall("definedNames/definedName").forEach((name) => {
|
|
1783
|
+
const ref = name.text;
|
|
1784
|
+
if (this.isRange(ref)) {
|
|
1785
|
+
const namedRange = this.splitRange(ref);
|
|
1786
|
+
const namedStart = this.splitRef(namedRange.start);
|
|
1787
|
+
const namedStartCol = this.charToNum(namedStart.col);
|
|
1788
|
+
const namedEnd = this.splitRef(namedRange.end);
|
|
1789
|
+
const namedEndCol = this.charToNum(namedEnd.col);
|
|
1790
|
+
if (namedStart.row === currentRow && currentCol < namedStartCol) {
|
|
1791
|
+
namedStart.col = this.numToChar(namedStartCol + numCols);
|
|
1792
|
+
namedEnd.col = this.numToChar(namedEndCol + numCols);
|
|
1793
|
+
name.text = this.joinRange({
|
|
1794
|
+
start: this.joinRef(namedStart),
|
|
1795
|
+
end: this.joinRef(namedEnd)
|
|
1796
|
+
});
|
|
1797
|
+
}
|
|
1798
|
+
} else {
|
|
1799
|
+
const namedRef = this.splitRef(ref);
|
|
1800
|
+
const namedCol = this.charToNum(namedRef.col);
|
|
1801
|
+
if (namedRef.row === currentRow && currentCol < namedCol) {
|
|
1802
|
+
namedRef.col = this.numToChar(namedCol + numCols);
|
|
1803
|
+
name.text = this.joinRef(namedRef);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
});
|
|
1807
|
+
sheet.findall("hyperlinks/hyperlink").forEach((hyperlink) => {
|
|
1808
|
+
const ref = this.splitRef(hyperlink.attrib.ref);
|
|
1809
|
+
const colNumber = this.charToNum(ref.col);
|
|
1810
|
+
if (colNumber > currentCol) {
|
|
1811
|
+
ref.col = this.numToChar(colNumber + numCols);
|
|
1812
|
+
hyperlink.attrib.ref = this.joinRef(ref);
|
|
1813
|
+
}
|
|
1814
|
+
});
|
|
1815
|
+
}
|
|
1816
|
+
pushDown(workbook, sheet, tables, currentRow, numRows) {
|
|
1817
|
+
const mergeCells = sheet.find("mergeCells");
|
|
1818
|
+
sheet.findall("mergeCells/mergeCell").forEach((mergeCell) => {
|
|
1819
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1820
|
+
const mergeStart = this.splitRef(mergeRange.start);
|
|
1821
|
+
const mergeEnd = this.splitRef(mergeRange.end);
|
|
1822
|
+
if (mergeStart.row > currentRow) {
|
|
1823
|
+
mergeStart.row += numRows;
|
|
1824
|
+
mergeEnd.row += numRows;
|
|
1825
|
+
mergeCell.attrib.ref = this.joinRange({
|
|
1826
|
+
start: this.joinRef(mergeStart),
|
|
1827
|
+
end: this.joinRef(mergeEnd)
|
|
1828
|
+
});
|
|
1829
|
+
}
|
|
1830
|
+
if (mergeStart.row == currentRow) {
|
|
1831
|
+
for (let i = 1; i <= numRows; i++) {
|
|
1832
|
+
const newMergeCell = this.cloneElement(mergeCell);
|
|
1833
|
+
mergeStart.row += 1;
|
|
1834
|
+
mergeEnd.row += 1;
|
|
1835
|
+
newMergeCell.attrib.ref = this.joinRange({
|
|
1836
|
+
start: this.joinRef(mergeStart),
|
|
1837
|
+
end: this.joinRef(mergeEnd)
|
|
1838
|
+
});
|
|
1839
|
+
mergeCells.attrib.count += 1;
|
|
1840
|
+
mergeCells._children.push(newMergeCell);
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
});
|
|
1844
|
+
tables.forEach((table) => {
|
|
1845
|
+
const tableRoot = table.root;
|
|
1846
|
+
const tableRange = this.splitRange(tableRoot.attrib.ref);
|
|
1847
|
+
const tableStart = this.splitRef(tableRange.start);
|
|
1848
|
+
const tableEnd = this.splitRef(tableRange.end);
|
|
1849
|
+
if (tableStart.row > currentRow) {
|
|
1850
|
+
tableStart.row += numRows;
|
|
1851
|
+
tableEnd.row += numRows;
|
|
1852
|
+
tableRoot.attrib.ref = this.joinRange({
|
|
1853
|
+
start: this.joinRef(tableStart),
|
|
1854
|
+
end: this.joinRef(tableEnd)
|
|
1855
|
+
});
|
|
1856
|
+
const autoFilter = tableRoot.find("autoFilter");
|
|
1857
|
+
if (autoFilter !== null) {
|
|
1858
|
+
autoFilter.attrib.ref = tableRoot.attrib.ref;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
});
|
|
1862
|
+
workbook.findall("definedNames/definedName").forEach((name) => {
|
|
1863
|
+
const ref = name.text;
|
|
1864
|
+
if (this.isRange(ref)) {
|
|
1865
|
+
const namedRange = this.splitRange(ref);
|
|
1866
|
+
const namedStart = this.splitRef(namedRange.start);
|
|
1867
|
+
const namedEnd = this.splitRef(namedRange.end);
|
|
1868
|
+
if (namedStart) {
|
|
1869
|
+
if (namedStart.row > currentRow) {
|
|
1870
|
+
namedStart.row += numRows;
|
|
1871
|
+
namedEnd.row += numRows;
|
|
1872
|
+
name.text = this.joinRange({
|
|
1873
|
+
start: this.joinRef(namedStart),
|
|
1874
|
+
end: this.joinRef(namedEnd)
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
if (this.option && this.option.pushDownPageBreakOnTableSubstitution) {
|
|
1879
|
+
if (this.sheet.name == name.text.split("!")[0].replace(/'/gi, "") && namedEnd) {
|
|
1880
|
+
if (namedEnd.row > currentRow) {
|
|
1881
|
+
namedEnd.row += numRows;
|
|
1882
|
+
name.text = this.joinRange({
|
|
1883
|
+
start: this.joinRef(namedStart),
|
|
1884
|
+
end: this.joinRef(namedEnd)
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
} else {
|
|
1890
|
+
const namedRef = this.splitRef(ref);
|
|
1891
|
+
if (namedRef.row > currentRow) {
|
|
1892
|
+
namedRef.row += numRows;
|
|
1893
|
+
name.text = this.joinRef(namedRef);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
});
|
|
1897
|
+
sheet.findall("hyperlinks/hyperlink").forEach((hyperlink) => {
|
|
1898
|
+
const ref = this.splitRef(hyperlink.attrib.ref);
|
|
1899
|
+
if (ref.row > currentRow) {
|
|
1900
|
+
ref.row += numRows;
|
|
1901
|
+
hyperlink.attrib.ref = this.joinRef(ref);
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
async hideCols(sheetName, hideItemIndexes) {
|
|
1906
|
+
const sheet = await this.loadSheet(sheetName);
|
|
1907
|
+
this.sheet = sheet;
|
|
1908
|
+
if (Array.isArray(hideItemIndexes) && hideItemIndexes.length) {
|
|
1909
|
+
const cols = sheet.root.find("cols");
|
|
1910
|
+
if (cols) {
|
|
1911
|
+
hideItemIndexes.forEach((hideIndex) => {
|
|
1912
|
+
const colIndex = hideIndex + 1;
|
|
1913
|
+
const col = cols.findall("col").find((c) => {
|
|
1914
|
+
const min = parseInt(c.attrib.min, 10);
|
|
1915
|
+
const max = parseInt(c.attrib.max, 10);
|
|
1916
|
+
return colIndex >= min && colIndex <= max;
|
|
1917
|
+
});
|
|
1918
|
+
if (col) {
|
|
1919
|
+
col.attrib.hidden = "1";
|
|
1920
|
+
}
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
this.archive.file(sheet.filename, etree.tostring(sheet.root, { encoding: "utf-8" }));
|
|
1925
|
+
this._rebuild();
|
|
1926
|
+
return this;
|
|
1927
|
+
}
|
|
1928
|
+
getWidthCell(numCol, sheet) {
|
|
1929
|
+
let defaultWidth = sheet.root.find("sheetFormatPr").attrib["defaultColWidth"];
|
|
1930
|
+
if (!defaultWidth) {
|
|
1931
|
+
defaultWidth = "11.42578125";
|
|
1932
|
+
}
|
|
1933
|
+
let finalWidth = defaultWidth;
|
|
1934
|
+
sheet.root.findall("cols/col").forEach((col) => {
|
|
1935
|
+
if (numCol >= col.attrib["min"] && numCol <= col.attrib["max"]) {
|
|
1936
|
+
if (col.attrib["width"] != void 0) {
|
|
1937
|
+
finalWidth = col.attrib["width"];
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
});
|
|
1941
|
+
return Number.parseFloat(finalWidth);
|
|
1942
|
+
}
|
|
1943
|
+
getWidthMergeCell(mergeCell, sheet) {
|
|
1944
|
+
let mergeWidth = 0;
|
|
1945
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1946
|
+
const mergeStartCol = this.charToNum(this.splitRef(mergeRange.start).col);
|
|
1947
|
+
const mergeEndCol = this.charToNum(this.splitRef(mergeRange.end).col);
|
|
1948
|
+
for (let i = mergeStartCol; i < mergeEndCol + 1; i++) {
|
|
1949
|
+
mergeWidth += this.getWidthCell(i, sheet);
|
|
1950
|
+
}
|
|
1951
|
+
return mergeWidth;
|
|
1952
|
+
}
|
|
1953
|
+
getHeightCell(numRow, sheet) {
|
|
1954
|
+
let finalHeight = sheet.root.find("sheetFormatPr").attrib["defaultRowHeight"];
|
|
1955
|
+
sheet.root.findall("sheetData/row").forEach((row) => {
|
|
1956
|
+
if (numRow == row.attrib["r"]) {
|
|
1957
|
+
if (row.attrib["ht"] != void 0) {
|
|
1958
|
+
finalHeight = row.attrib["ht"];
|
|
1959
|
+
}
|
|
1960
|
+
}
|
|
1961
|
+
});
|
|
1962
|
+
return Number.parseFloat(finalHeight);
|
|
1963
|
+
}
|
|
1964
|
+
getHeightMergeCell(mergeCell, sheet) {
|
|
1965
|
+
let mergeHeight = 0;
|
|
1966
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1967
|
+
const mergeStartRow = this.splitRef(mergeRange.start).row;
|
|
1968
|
+
const mergeEndRow = this.splitRef(mergeRange.end).row;
|
|
1969
|
+
for (let i = mergeStartRow; i < mergeEndRow + 1; i++) {
|
|
1970
|
+
mergeHeight += this.getHeightCell(i, sheet);
|
|
1971
|
+
}
|
|
1972
|
+
return mergeHeight;
|
|
1973
|
+
}
|
|
1974
|
+
getNbRowOfMergeCell(mergeCell) {
|
|
1975
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
1976
|
+
const mergeStartRow = this.splitRef(mergeRange.start).row;
|
|
1977
|
+
const mergeEndRow = this.splitRef(mergeRange.end).row;
|
|
1978
|
+
return mergeEndRow - mergeStartRow + 1;
|
|
1979
|
+
}
|
|
1980
|
+
pixelsToEMUs(pixels) {
|
|
1981
|
+
return Math.round(pixels * 914400 / 96);
|
|
1982
|
+
}
|
|
1983
|
+
columnWidthToEMUs(width) {
|
|
1984
|
+
return this.pixelsToEMUs(width * 7.625579987895905);
|
|
1985
|
+
}
|
|
1986
|
+
rowHeightToEMUs(height) {
|
|
1987
|
+
return Math.round(height / 72 * 914400);
|
|
1988
|
+
}
|
|
1989
|
+
findMaxFileId(fileNameRegex, idRegex) {
|
|
1990
|
+
const files = this.archive.file(fileNameRegex);
|
|
1991
|
+
const maxId = files.reduce((p, c) => {
|
|
1992
|
+
const num = parseInt(idRegex.exec(c.name)[1]);
|
|
1993
|
+
if (p == null) {
|
|
1994
|
+
return num;
|
|
1995
|
+
}
|
|
1996
|
+
return p > num ? p : num;
|
|
1997
|
+
}, 0);
|
|
1998
|
+
return maxId + 1;
|
|
1999
|
+
}
|
|
2000
|
+
cellInMergeCells(cell, mergeCell) {
|
|
2001
|
+
const cellCol = this.charToNum(this.splitRef(cell.attrib.r).col);
|
|
2002
|
+
const cellRow = this.splitRef(cell.attrib.r).row;
|
|
2003
|
+
const mergeRange = this.splitRange(mergeCell.attrib.ref);
|
|
2004
|
+
const mergeStartCol = this.charToNum(this.splitRef(mergeRange.start).col);
|
|
2005
|
+
const mergeEndCol = this.charToNum(this.splitRef(mergeRange.end).col);
|
|
2006
|
+
const mergeStartRow = this.splitRef(mergeRange.start).row;
|
|
2007
|
+
const mergeEndRow = this.splitRef(mergeRange.end).row;
|
|
2008
|
+
if (cellCol >= mergeStartCol && cellCol <= mergeEndCol) {
|
|
2009
|
+
if (cellRow >= mergeStartRow && cellRow <= mergeEndRow) {
|
|
2010
|
+
return true;
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
return false;
|
|
2014
|
+
}
|
|
2015
|
+
imageToBuffer(imageObj) {
|
|
2016
|
+
function checkImage(buffer) {
|
|
2017
|
+
try {
|
|
2018
|
+
(0, import_image_size.imageSize)(buffer);
|
|
2019
|
+
return buffer;
|
|
2020
|
+
} catch (error) {
|
|
2021
|
+
throw new TypeError("imageObj cannot be parse as a buffer image");
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
if (!imageObj) {
|
|
2025
|
+
throw new TypeError("imageObj cannot be null");
|
|
2026
|
+
}
|
|
2027
|
+
if (imageObj instanceof Buffer) {
|
|
2028
|
+
return checkImage(imageObj);
|
|
2029
|
+
}
|
|
2030
|
+
if (typeof imageObj === "string" || imageObj instanceof String) {
|
|
2031
|
+
imageObj = imageObj.toString();
|
|
2032
|
+
const imagePath = this.option && this.option.imageRootPath ? this.option.imageRootPath + "/" + imageObj : imageObj;
|
|
2033
|
+
if (fs.existsSync(imagePath)) {
|
|
2034
|
+
return checkImage(Buffer.from(fs.readFileSync(imagePath, { encoding: "base64" }), "base64"));
|
|
2035
|
+
}
|
|
2036
|
+
try {
|
|
2037
|
+
return checkImage(Buffer.from(imageObj, "base64"));
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
throw new TypeError("imageObj cannot be parse as a buffer");
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
throw new TypeError("imageObj type is not supported : " + typeof imageObj);
|
|
2043
|
+
}
|
|
2044
|
+
findMaxId(element, tag, attr, idRegex) {
|
|
2045
|
+
let maxId = 0;
|
|
2046
|
+
element.findall(tag).forEach((el) => {
|
|
2047
|
+
const match = idRegex.exec(el.attrib[attr]);
|
|
2048
|
+
if (match == null) {
|
|
2049
|
+
throw new Error("Can not find the id!");
|
|
2050
|
+
}
|
|
2051
|
+
const cid = parseInt(match[1]);
|
|
2052
|
+
if (cid > maxId) {
|
|
2053
|
+
maxId = cid;
|
|
2054
|
+
}
|
|
2055
|
+
});
|
|
2056
|
+
return ++maxId;
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
var generateXlsxTemplate = async function(data, values, options) {
|
|
2060
|
+
const w = await Workbook.parse(data, options);
|
|
2061
|
+
await w.substituteAll(values);
|
|
2062
|
+
return w.generate(options);
|
|
2063
|
+
};
|
|
2064
|
+
|
|
2065
|
+
// src/helper.ts
|
|
2066
|
+
var import_exceljs = __toESM(require("exceljs"));
|
|
2067
|
+
var import_stream = require("stream");
|
|
2068
|
+
var isPureNumber = /^[0-9]+$/;
|
|
2069
|
+
var isPureUppercase = /^[A-Z]+$/;
|
|
2070
|
+
var exprSingle = `expr`;
|
|
2071
|
+
var exprArr = `exprArr`;
|
|
2072
|
+
var exprIndex = `index`;
|
|
2073
|
+
var defaultKey = `!!`;
|
|
2074
|
+
var numberKey = `!!number`;
|
|
2075
|
+
var codeKey = `!!codeKey`;
|
|
2076
|
+
var funcCommand = "fn:";
|
|
2077
|
+
var RuleToken = /* @__PURE__ */ ((RuleToken2) => {
|
|
2078
|
+
RuleToken2["AliasToken"] = "alias";
|
|
2079
|
+
RuleToken2["CellToken"] = "cell";
|
|
2080
|
+
RuleToken2["MergeCellToken"] = "mergeCell";
|
|
2081
|
+
RuleToken2["RowCellToken"] = "rowCell";
|
|
2082
|
+
RuleToken2["UseAliasToken"] = "@";
|
|
2083
|
+
RuleToken2["RangeToken"] = "-";
|
|
2084
|
+
RuleToken2["PosToken"] = ":";
|
|
2085
|
+
RuleToken2["FunctionPatternToken"] = "<?>";
|
|
2086
|
+
RuleToken2["AnyToken"] = "?";
|
|
2087
|
+
RuleToken2["VarPatternToken"] = "${?}";
|
|
2088
|
+
RuleToken2["UndefinedToken"] = "";
|
|
2089
|
+
RuleToken2["EqualToken"] = "=";
|
|
2090
|
+
RuleToken2["ArgPosToken"] = ",";
|
|
2091
|
+
RuleToken2["LparenToken"] = "(";
|
|
2092
|
+
RuleToken2["RparenToken"] = ")";
|
|
2093
|
+
RuleToken2["DotGetToken"] = ".";
|
|
2094
|
+
RuleToken2["CompileGenToken"] = "compile:GenCell";
|
|
2095
|
+
RuleToken2["CompileMacroToken"] = "compile:Macro";
|
|
2096
|
+
return RuleToken2;
|
|
2097
|
+
})(RuleToken || {});
|
|
2098
|
+
var RuleMapOptions = class _RuleMapOptions {
|
|
2099
|
+
constructor(m) {
|
|
2100
|
+
// rule configure area
|
|
2101
|
+
this.startLine = 1;
|
|
2102
|
+
this.startColumn = 1;
|
|
2103
|
+
if (m === void 0) {
|
|
2104
|
+
this.ruleKeyMap = defaultRuleTokenMap;
|
|
2105
|
+
} else {
|
|
2106
|
+
this.ruleKeyMap = m;
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
static withAllSheets(w, excludes) {
|
|
2110
|
+
const compileSheets = [];
|
|
2111
|
+
const options = new _RuleMapOptions();
|
|
2112
|
+
if (excludes === void 0) {
|
|
2113
|
+
excludes = [];
|
|
2114
|
+
}
|
|
2115
|
+
if (w.worksheets.length > 0 && excludes.length > 0) {
|
|
2116
|
+
for (const [index, sheet] of w.worksheets.entries()) {
|
|
2117
|
+
if (excludes.includes(index.toString()) || excludes.includes(sheet.name)) {
|
|
2118
|
+
continue;
|
|
2119
|
+
}
|
|
2120
|
+
if (sheet.name.endsWith(".json")) {
|
|
2121
|
+
continue;
|
|
2122
|
+
}
|
|
2123
|
+
compileSheets.push(sheet.name);
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
options.compileSheets = compileSheets;
|
|
2127
|
+
return options;
|
|
2128
|
+
}
|
|
2129
|
+
parseDefault(worksheet) {
|
|
2130
|
+
this.ruleKeyMap = mergeOption(this.ruleKeyMap, defaultRuleTokenMap);
|
|
2131
|
+
if (this.startLine === void 0) {
|
|
2132
|
+
this.startLine = 1;
|
|
2133
|
+
}
|
|
2134
|
+
if (this.endLine === void 0) {
|
|
2135
|
+
this.endLine = worksheet.rowCount;
|
|
2136
|
+
}
|
|
2137
|
+
if (this.startColumn === void 0) {
|
|
2138
|
+
this.startColumn = 1;
|
|
2139
|
+
}
|
|
2140
|
+
if (this.endColumn === void 0) {
|
|
2141
|
+
this.endColumn = worksheet.columnCount;
|
|
2142
|
+
}
|
|
2143
|
+
return this;
|
|
2144
|
+
}
|
|
2145
|
+
addRuleMap(key, value) {
|
|
2146
|
+
this.ruleKeyMap.set(key, value);
|
|
2147
|
+
return this;
|
|
2148
|
+
}
|
|
2149
|
+
setStartRow(start) {
|
|
2150
|
+
this.startLine = start;
|
|
2151
|
+
return this;
|
|
2152
|
+
}
|
|
2153
|
+
setStartColumn(start) {
|
|
2154
|
+
this.startColumn = start;
|
|
2155
|
+
return this;
|
|
2156
|
+
}
|
|
2157
|
+
setEndRow(end) {
|
|
2158
|
+
this.endLine = end;
|
|
2159
|
+
return this;
|
|
2160
|
+
}
|
|
2161
|
+
setEndColumn(end) {
|
|
2162
|
+
this.endColumn = end;
|
|
2163
|
+
return this;
|
|
2164
|
+
}
|
|
2165
|
+
parseToken(value) {
|
|
2166
|
+
if (value === "") {
|
|
2167
|
+
return "" /* UndefinedToken */;
|
|
2168
|
+
}
|
|
2169
|
+
for (const [token, alias] of this.ruleKeyMap.entries()) {
|
|
2170
|
+
if (alias === value) {
|
|
2171
|
+
return token;
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
return "" /* UndefinedToken */;
|
|
2175
|
+
}
|
|
2176
|
+
getContextMap() {
|
|
2177
|
+
const ctx = /* @__PURE__ */ new Map();
|
|
2178
|
+
for (const [token, expr] of this.ruleKeyMap.entries()) {
|
|
2179
|
+
if (!isRuleToken(token)) {
|
|
2180
|
+
const value = [{
|
|
2181
|
+
express: expr,
|
|
2182
|
+
key: expr,
|
|
2183
|
+
tokens: [token],
|
|
2184
|
+
value: token.toString()
|
|
2185
|
+
}];
|
|
2186
|
+
ctx.set(token, value);
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
return ctx;
|
|
2190
|
+
}
|
|
2191
|
+
getCompileCheckHandlers() {
|
|
2192
|
+
if (this.compileCheckers !== void 0 && this.compileCheckers.length > 0) {
|
|
2193
|
+
return this.compileCheckers;
|
|
2194
|
+
}
|
|
2195
|
+
return void 0;
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
2198
|
+
var CompileContext = class _CompileContext extends RuleMapOptions {
|
|
2199
|
+
constructor(m) {
|
|
2200
|
+
super(m);
|
|
2201
|
+
this.aliasMap = /* @__PURE__ */ new Map();
|
|
2202
|
+
}
|
|
2203
|
+
static create(r) {
|
|
2204
|
+
const ctx = new _CompileContext(r.ruleKeyMap);
|
|
2205
|
+
Object.assign(ctx, { ...r });
|
|
2206
|
+
return ctx.init();
|
|
2207
|
+
}
|
|
2208
|
+
init() {
|
|
2209
|
+
if (this.ruleKeyMap === void 0) {
|
|
2210
|
+
this.ruleKeyMap = defaultRuleTokenMap;
|
|
2211
|
+
}
|
|
2212
|
+
return this;
|
|
2213
|
+
}
|
|
2214
|
+
loadAlias(m) {
|
|
2215
|
+
if (m.size <= 0 || !m.has("alias" /* AliasToken */)) {
|
|
2216
|
+
return this;
|
|
2217
|
+
}
|
|
2218
|
+
const values = m.get("alias" /* AliasToken */);
|
|
2219
|
+
for (const vs of values) {
|
|
2220
|
+
if (typeof vs.value === "string") {
|
|
2221
|
+
this.aliasMap.set(vs.key, vs.value);
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
return this;
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* 设置别名缓存
|
|
2228
|
+
*/
|
|
2229
|
+
setAlias(key, value) {
|
|
2230
|
+
this.aliasMap.set(key, value);
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* 获取别名缓存值
|
|
2234
|
+
*/
|
|
2235
|
+
getAlias(key) {
|
|
2236
|
+
return this.aliasMap.get(key);
|
|
2237
|
+
}
|
|
2238
|
+
/**
|
|
2239
|
+
* 检查别名是否存在
|
|
2240
|
+
*/
|
|
2241
|
+
hasAlias(key) {
|
|
2242
|
+
return this.aliasMap.has(key);
|
|
2243
|
+
}
|
|
2244
|
+
filterSheet(sheetName) {
|
|
2245
|
+
if (sheetName !== "" && this.compileSheets !== void 0 && this.compileSheets.length > 0) {
|
|
2246
|
+
return this.compileSheets.includes(sheetName);
|
|
2247
|
+
}
|
|
2248
|
+
return false;
|
|
2249
|
+
}
|
|
2250
|
+
};
|
|
2251
|
+
var defaultRuleTokenMap = /* @__PURE__ */ new Map([
|
|
2252
|
+
["alias" /* AliasToken */, "alias" /* AliasToken */.toString()],
|
|
2253
|
+
["?" /* AnyToken */, "?" /* AnyToken */.toString()],
|
|
2254
|
+
["cell" /* CellToken */, "cell" /* CellToken */.toString()],
|
|
2255
|
+
["rowCell" /* RowCellToken */, "rowCell" /* RowCellToken */.toString()],
|
|
2256
|
+
["mergeCell" /* MergeCellToken */, "mergeCell" /* MergeCellToken */.toString()],
|
|
2257
|
+
["@" /* UseAliasToken */, "@" /* UseAliasToken */.toString()],
|
|
2258
|
+
[":" /* PosToken */, ":" /* PosToken */.toString()],
|
|
2259
|
+
["-" /* RangeToken */, "-" /* RangeToken */.toString()],
|
|
2260
|
+
["<?>" /* FunctionPatternToken */, "<?>" /* FunctionPatternToken */.toString()],
|
|
2261
|
+
["${?}" /* VarPatternToken */, "${?}" /* VarPatternToken */.toString()],
|
|
2262
|
+
["=" /* EqualToken */, "=" /* EqualToken */.toString()],
|
|
2263
|
+
["," /* ArgPosToken */, "," /* ArgPosToken */.toString()],
|
|
2264
|
+
["(" /* LparenToken */, "(" /* LparenToken */.toString()],
|
|
2265
|
+
[")" /* RparenToken */, ")" /* RparenToken */.toString()],
|
|
2266
|
+
["." /* DotGetToken */, "." /* DotGetToken */.toString()],
|
|
2267
|
+
["compile:Macro" /* CompileMacroToken */, "compile:Macro" /* CompileMacroToken */.toString()],
|
|
2268
|
+
["compile:GenCell" /* CompileGenToken */, "compile:GenCell" /* CompileGenToken */.toString()]
|
|
2269
|
+
]);
|
|
2270
|
+
var DefaultPlaceholderCellValue = class {
|
|
2271
|
+
constructor(p, merge) {
|
|
2272
|
+
this.placeholder = p;
|
|
2273
|
+
this.mergeCellPlaceholder = merge === void 0 ? "" : merge;
|
|
2274
|
+
}
|
|
2275
|
+
mergeCell(values) {
|
|
2276
|
+
if (this.mergeCellPlaceholder !== void 0) {
|
|
2277
|
+
return this.mergeCellPlaceholder.replace("?", values.join(","));
|
|
2278
|
+
}
|
|
2279
|
+
return "";
|
|
2280
|
+
}
|
|
2281
|
+
toString() {
|
|
2282
|
+
return this.placeholder;
|
|
2283
|
+
}
|
|
2284
|
+
};
|
|
2285
|
+
var _getCells = (thisArg) => {
|
|
2286
|
+
let cells = [];
|
|
2287
|
+
for (let j = thisArg.minColumn; j <= thisArg.maxColumn; j += thisArg.stepColumn) {
|
|
2288
|
+
for (let i = thisArg.minRow; i <= thisArg.maxRow; i += thisArg.stepRow) {
|
|
2289
|
+
cells.push({
|
|
2290
|
+
Row: i,
|
|
2291
|
+
Column: j
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
return cells;
|
|
2296
|
+
};
|
|
2297
|
+
var TokenParserManger = class _TokenParserManger {
|
|
2298
|
+
// T=xxx
|
|
2299
|
+
static aliasParse(ctx, token, value) {
|
|
2300
|
+
if (token !== "alias" /* AliasToken */) {
|
|
2301
|
+
return {
|
|
2302
|
+
ok: false
|
|
2303
|
+
};
|
|
2304
|
+
}
|
|
2305
|
+
const parser = getTokenParser("=" /* EqualToken */);
|
|
2306
|
+
const { values, expr, ok } = parser.handler(ctx, "=" /* EqualToken */, value);
|
|
2307
|
+
if (!ok) {
|
|
2308
|
+
return {
|
|
2309
|
+
ok: false
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
if (typeof expr.value !== "string" || expr.value === "") {
|
|
2313
|
+
return {
|
|
2314
|
+
ok: false,
|
|
2315
|
+
error: new Error(`alias express right value cannot be a empty value.`)
|
|
2316
|
+
};
|
|
2317
|
+
}
|
|
2318
|
+
return {
|
|
2319
|
+
ok: true,
|
|
2320
|
+
expr: {
|
|
2321
|
+
express: value,
|
|
2322
|
+
key: expr.key,
|
|
2323
|
+
// alias key
|
|
2324
|
+
value: expr.value,
|
|
2325
|
+
// alias value
|
|
2326
|
+
tokens: [token, "=" /* EqualToken */]
|
|
2327
|
+
// express tokens
|
|
2328
|
+
},
|
|
2329
|
+
values
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
// x=xx
|
|
2333
|
+
static equalParse(ctx, token, value) {
|
|
2334
|
+
if (token !== "=" /* EqualToken */) {
|
|
2335
|
+
return {
|
|
2336
|
+
ok: false
|
|
2337
|
+
};
|
|
2338
|
+
}
|
|
2339
|
+
const equalToken = _TokenParserManger.getTokenByCtx(ctx, "=" /* EqualToken */);
|
|
2340
|
+
const offset = equalToken.length;
|
|
2341
|
+
const index = value.indexOf(equalToken);
|
|
2342
|
+
if (index < 0) {
|
|
2343
|
+
return {
|
|
2344
|
+
ok: false
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
2347
|
+
const len = value.length;
|
|
2348
|
+
const key = value.substring(0, index);
|
|
2349
|
+
const rightValue = value.substring(index + offset, len);
|
|
2350
|
+
if (rightValue === "") {
|
|
2351
|
+
return {
|
|
2352
|
+
ok: false,
|
|
2353
|
+
error: new Error(`equal express right value cannot be a empty value.`)
|
|
2354
|
+
};
|
|
2355
|
+
}
|
|
2356
|
+
const expr = {
|
|
2357
|
+
key,
|
|
2358
|
+
value: rightValue,
|
|
2359
|
+
express: value,
|
|
2360
|
+
tokens: [token]
|
|
2361
|
+
};
|
|
2362
|
+
return {
|
|
2363
|
+
ok: true,
|
|
2364
|
+
values: [key, rightValue],
|
|
2365
|
+
expr
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
//cell| X:Y=${?}
|
|
2369
|
+
static cellParse(ctx, token, value) {
|
|
2370
|
+
if (token !== "cell" /* CellToken */) {
|
|
2371
|
+
return {
|
|
2372
|
+
ok: false
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
const equalToken = _TokenParserManger.getTokenByCtx(ctx, "=" /* EqualToken */);
|
|
2376
|
+
const eqOffset = equalToken.length;
|
|
2377
|
+
const posToken = _TokenParserManger.getTokenByCtx(ctx, ":" /* PosToken */);
|
|
2378
|
+
const eqIndex = value.indexOf(equalToken);
|
|
2379
|
+
const posIndex = value.indexOf(posToken);
|
|
2380
|
+
if (eqIndex < 0 || posIndex < 0) {
|
|
2381
|
+
return {
|
|
2382
|
+
ok: false
|
|
2383
|
+
};
|
|
2384
|
+
}
|
|
2385
|
+
const parser = getTokenParser(":" /* PosToken */);
|
|
2386
|
+
const varParser = getTokenParser("${?}" /* VarPatternToken */);
|
|
2387
|
+
const posValue = value.substring(0, eqIndex);
|
|
2388
|
+
const varValue = value.substring(eqIndex + eqOffset);
|
|
2389
|
+
const posReply = parser.handler(ctx, ":" /* PosToken */, posValue);
|
|
2390
|
+
if (!posReply.ok) {
|
|
2391
|
+
return {
|
|
2392
|
+
ok: false,
|
|
2393
|
+
...posReply
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
const varReply = varParser.handler(ctx, "${?}" /* VarPatternToken */, varValue);
|
|
2397
|
+
if (!varReply.ok) {
|
|
2398
|
+
return {
|
|
2399
|
+
ok: false,
|
|
2400
|
+
...varReply
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
const expr = {
|
|
2404
|
+
...varReply.expr
|
|
2405
|
+
};
|
|
2406
|
+
expr.express = value;
|
|
2407
|
+
expr.cells = posReply.expr.cells;
|
|
2408
|
+
expr.value = varReply.expr.value;
|
|
2409
|
+
expr.ref = varReply.expr.ref;
|
|
2410
|
+
expr.tokens = [token, "=" /* EqualToken */, ...posReply.expr.tokens, ...varReply.expr.tokens];
|
|
2411
|
+
return {
|
|
2412
|
+
ok: true,
|
|
2413
|
+
expr,
|
|
2414
|
+
values: [posReply.values, varReply.values]
|
|
2415
|
+
};
|
|
2416
|
+
}
|
|
2417
|
+
static useAliasParse(ctx, token, value) {
|
|
2418
|
+
if (token !== "@" /* UseAliasToken */) {
|
|
2419
|
+
return {
|
|
2420
|
+
ok: false
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
const useAliasToken = _TokenParserManger.getTokenByCtx(ctx, "@" /* UseAliasToken */);
|
|
2424
|
+
const offset = useAliasToken.length;
|
|
2425
|
+
const has = offset !== 0 && value.indexOf(useAliasToken) >= 0;
|
|
2426
|
+
if (!has) {
|
|
2427
|
+
return {
|
|
2428
|
+
ok: false
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
const endTokens = ["@" /* UseAliasToken */, "(" /* LparenToken */, "," /* ArgPosToken */, "." /* DotGetToken */];
|
|
2432
|
+
const values = _TokenParserManger.scanToken(value, useAliasToken, _TokenParserManger.toList(ctx, endTokens));
|
|
2433
|
+
if (values === void 0 || values.length <= 0) {
|
|
2434
|
+
return {
|
|
2435
|
+
ok: false
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
const keys = [];
|
|
2439
|
+
const tokens = [];
|
|
2440
|
+
const expr = {
|
|
2441
|
+
express: value,
|
|
2442
|
+
tokens,
|
|
2443
|
+
value: keys,
|
|
2444
|
+
ref: []
|
|
2445
|
+
};
|
|
2446
|
+
for (const v of values) {
|
|
2447
|
+
tokens.push(token);
|
|
2448
|
+
keys.push(v.token);
|
|
2449
|
+
expr.ref.push(v.value);
|
|
2450
|
+
}
|
|
2451
|
+
expr.value = keys;
|
|
2452
|
+
expr.tokens = tokens;
|
|
2453
|
+
return {
|
|
2454
|
+
expr,
|
|
2455
|
+
ok: true,
|
|
2456
|
+
values
|
|
2457
|
+
};
|
|
2458
|
+
}
|
|
2459
|
+
static rangeParse(ctx, token, value) {
|
|
2460
|
+
if (token !== "-" /* RangeToken */) {
|
|
2461
|
+
return {
|
|
2462
|
+
ok: false
|
|
2463
|
+
};
|
|
2464
|
+
}
|
|
2465
|
+
const rangeToken = _TokenParserManger.getTokenByCtx(ctx, "-" /* RangeToken */);
|
|
2466
|
+
const offset = rangeToken.length;
|
|
2467
|
+
const index = value.indexOf(rangeToken);
|
|
2468
|
+
if (index < 0 || offset <= 0) {
|
|
2469
|
+
return {
|
|
2470
|
+
ok: false
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
let setup = 1;
|
|
2474
|
+
let startNumber = NaN;
|
|
2475
|
+
let endNumber = NaN;
|
|
2476
|
+
let startPos = value.substring(0, index).trim();
|
|
2477
|
+
let endPos = value.substring(index + offset).trim();
|
|
2478
|
+
const argPosToken = _TokenParserManger.getTokenByCtx(ctx, "," /* ArgPosToken */);
|
|
2479
|
+
const endSetupIndex = endPos.indexOf(argPosToken);
|
|
2480
|
+
if (endSetupIndex > 0) {
|
|
2481
|
+
setup = Number.parseInt(endPos.substring(endSetupIndex).trim(), 10);
|
|
2482
|
+
endPos = endPos.substring(0, endSetupIndex).trim();
|
|
2483
|
+
}
|
|
2484
|
+
if (isNaN(setup)) {
|
|
2485
|
+
return {
|
|
2486
|
+
ok: false,
|
|
2487
|
+
error: new Error(`rangeToken parse setup NaN, ${value}`)
|
|
2488
|
+
};
|
|
2489
|
+
}
|
|
2490
|
+
endNumber = _TokenParserManger.parsePosNumber(endPos);
|
|
2491
|
+
startNumber = _TokenParserManger.parsePosNumber(startPos);
|
|
2492
|
+
if (isNaN(startNumber) || isNaN(endNumber)) {
|
|
2493
|
+
return {
|
|
2494
|
+
ok: false,
|
|
2495
|
+
error: new Error(`rangeToken parse start,end has NaN, ${value}`)
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
const expr = {
|
|
2499
|
+
express: value,
|
|
2500
|
+
tokens: [token],
|
|
2501
|
+
value: [startNumber, endNumber, setup]
|
|
2502
|
+
};
|
|
2503
|
+
return {
|
|
2504
|
+
expr,
|
|
2505
|
+
ok: true,
|
|
2506
|
+
values: [startNumber, endNumber, setup]
|
|
2507
|
+
};
|
|
2508
|
+
}
|
|
2509
|
+
static posParse(ctx, token, value) {
|
|
2510
|
+
if (token !== ":" /* PosToken */) {
|
|
2511
|
+
return {
|
|
2512
|
+
ok: false
|
|
2513
|
+
};
|
|
2514
|
+
}
|
|
2515
|
+
const posToken = _TokenParserManger.getTokenByCtx(ctx, ":" /* PosToken */);
|
|
2516
|
+
const offset = posToken.length;
|
|
2517
|
+
const index = value.indexOf(posToken);
|
|
2518
|
+
const len = value.length;
|
|
2519
|
+
const column = value.substring(0, index).trim();
|
|
2520
|
+
const row = value.substring(index + offset, len).trim();
|
|
2521
|
+
const rangeToken = _TokenParserManger.getTokenByCtx(ctx, "-" /* RangeToken */);
|
|
2522
|
+
const columnRange = column.indexOf(rangeToken);
|
|
2523
|
+
const rowRange = row.indexOf(rangeToken);
|
|
2524
|
+
if (rowRange > 0 || columnRange > 0) {
|
|
2525
|
+
return _TokenParserManger.parseRangeValue(ctx, { rowRange, columnRange, row, column, token, express: value });
|
|
2526
|
+
}
|
|
2527
|
+
const cell = {
|
|
2528
|
+
Row: Number.parseInt(row, 10),
|
|
2529
|
+
Column: columnLetterToNumber(column)
|
|
2530
|
+
};
|
|
2531
|
+
const expr = {
|
|
2532
|
+
value: cell,
|
|
2533
|
+
cells: [cell],
|
|
2534
|
+
express: value,
|
|
2535
|
+
tokens: [token]
|
|
2536
|
+
};
|
|
2537
|
+
return {
|
|
2538
|
+
ok: true,
|
|
2539
|
+
values: [row, column],
|
|
2540
|
+
expr
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
2543
|
+
// value input: A-AQ:13-15=<sum(#,[compile:Macro(exprArr,[F],[13,15],!codeKey)],compile:Marco(index),0)>
|
|
2544
|
+
// output: {
|
|
2545
|
+
// A:13 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],1,0),
|
|
2546
|
+
// B:13 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],2,0),
|
|
2547
|
+
// C:13 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],3,0),
|
|
2548
|
+
// ....,
|
|
2549
|
+
// A:14 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],1,0),
|
|
2550
|
+
// B:14 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],2,0),
|
|
2551
|
+
// C:14 => sum(#,[ codeKey(F:13.value),codeKey(F:14.value),codeKey(F:15.value)],3,0),
|
|
2552
|
+
// }
|
|
2553
|
+
static mergeCellParse(ctx, token, value) {
|
|
2554
|
+
if (token !== "mergeCell" /* MergeCellToken */ && token !== "rowCell" /* RowCellToken */) {
|
|
2555
|
+
return { ok: false };
|
|
2556
|
+
}
|
|
2557
|
+
const equalToken = _TokenParserManger.getTokenByCtx(ctx, "=" /* EqualToken */);
|
|
2558
|
+
const index = value.indexOf(equalToken);
|
|
2559
|
+
const offset = equalToken.length;
|
|
2560
|
+
if (index <= 0) return { ok: false, error: new Error(`merge cell config syntax error: ${value}`) };
|
|
2561
|
+
const rangeStr = value.substring(0, index).trim();
|
|
2562
|
+
const exprStr = value.substring(index + offset);
|
|
2563
|
+
const posParser = getTokenParser(":" /* PosToken */);
|
|
2564
|
+
const posReply = posParser.handler(ctx, ":" /* PosToken */, rangeStr);
|
|
2565
|
+
const functionToken = getTokenParser("<?>" /* FunctionPatternToken */);
|
|
2566
|
+
if (!posReply.ok) return { ok: false, ...posReply };
|
|
2567
|
+
const macroGenToken = _TokenParserManger.getTokenByCtx(ctx, "compile:GenCell" /* CompileGenToken */);
|
|
2568
|
+
const expr = {
|
|
2569
|
+
express: value,
|
|
2570
|
+
value: exprStr,
|
|
2571
|
+
// The template expression
|
|
2572
|
+
posExpr: posReply.expr,
|
|
2573
|
+
tokens: [token, ...posReply.expr.tokens]
|
|
2574
|
+
};
|
|
2575
|
+
if (exprStr.startsWith(macroGenToken)) {
|
|
2576
|
+
const argsSplitToken = _TokenParserManger.getTokenByCtx(ctx, "," /* ArgPosToken */);
|
|
2577
|
+
const args = _TokenParserManger.split(exprStr, argsSplitToken, [`(`, `)`]);
|
|
2578
|
+
const macro = _TokenParserManger.filterMacro(args);
|
|
2579
|
+
const aliasTokens = _TokenParserManger.extractUseAliasTokens(ctx, args);
|
|
2580
|
+
if (aliasTokens !== void 0 && aliasTokens.length > 0) {
|
|
2581
|
+
expr.tokens.push(...aliasTokens);
|
|
2582
|
+
}
|
|
2583
|
+
if (macro !== void 0 && macro.tokens.length > 0) {
|
|
2584
|
+
expr.macro = macro;
|
|
2585
|
+
expr.tokens.push(...macro.tokens);
|
|
2586
|
+
}
|
|
2587
|
+
} else {
|
|
2588
|
+
const exprReply = functionToken.handler(ctx, "<?>" /* FunctionPatternToken */, exprStr);
|
|
2589
|
+
if (exprReply.error !== void 0 && exprReply.error instanceof Error) {
|
|
2590
|
+
return {
|
|
2591
|
+
ok: false,
|
|
2592
|
+
...exprReply
|
|
2593
|
+
};
|
|
2594
|
+
}
|
|
2595
|
+
if (exprReply.ok && exprReply.expr !== void 0) {
|
|
2596
|
+
expr.funcExpr = exprReply.expr;
|
|
2597
|
+
expr.tokens.push(...exprReply.expr.tokens);
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
return {
|
|
2601
|
+
ok: true,
|
|
2602
|
+
expr,
|
|
2603
|
+
values: [rangeStr, exprStr]
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
// G-AQ:12=compile:GenCell(compile:Macro(expr,F,12),'.',compile:Marco(index))
|
|
2607
|
+
static rowCellParse(ctx, token, value) {
|
|
2608
|
+
if (token !== "rowCell" /* RowCellToken */) {
|
|
2609
|
+
return { ok: false };
|
|
2610
|
+
}
|
|
2611
|
+
return _TokenParserManger.mergeCellParse(ctx, token, value);
|
|
2612
|
+
}
|
|
2613
|
+
// $functionName($arg0:string,$arg1:string[],$arg2:string|number,$arg3:string|number)
|
|
2614
|
+
// eg: func(A,[xx1,xx2],xxx3), sum(#,[F,12,13],1,0)
|
|
2615
|
+
// $functionName not in compile:Macro,compile:GenCell
|
|
2616
|
+
// extract => {func:$functionName, arguments:[$arg0,$arg1,$arg2,$argN...]}
|
|
2617
|
+
// output: {func:"sum",arguments:["A",["F","12","13"],"1","0"]}
|
|
2618
|
+
static functionPatternParse(ctx, token, value) {
|
|
2619
|
+
if (token !== "<?>" /* FunctionPatternToken */) {
|
|
2620
|
+
return { ok: false };
|
|
2621
|
+
}
|
|
2622
|
+
const wordToken = _TokenParserManger.getTokenByCtx(ctx, "?" /* AnyToken */);
|
|
2623
|
+
const funcToken = _TokenParserManger.getTokenByCtx(ctx, "<?>" /* FunctionPatternToken */);
|
|
2624
|
+
const splitIndex = funcToken.indexOf(wordToken);
|
|
2625
|
+
const splitOffset = wordToken.length;
|
|
2626
|
+
const funcStartToken = funcToken.substring(0, splitIndex);
|
|
2627
|
+
const funcEndToken = funcToken.substring(splitIndex + splitOffset);
|
|
2628
|
+
const rparenToken = _TokenParserManger.getTokenByCtx(ctx, ")" /* RparenToken */);
|
|
2629
|
+
const lparenToken = _TokenParserManger.getTokenByCtx(ctx, "(" /* LparenToken */);
|
|
2630
|
+
const argsSplitToken = _TokenParserManger.getTokenByCtx(ctx, "," /* ArgPosToken */);
|
|
2631
|
+
if (value.startsWith(funcStartToken) && value.endsWith(funcEndToken)) {
|
|
2632
|
+
const content = value.substring(1, value.length - 1);
|
|
2633
|
+
const lparen = content.indexOf(lparenToken);
|
|
2634
|
+
const rparen = content.lastIndexOf(rparenToken);
|
|
2635
|
+
if (lparen > 0 && rparen > lparen) {
|
|
2636
|
+
const funcName = content.substring(0, lparen);
|
|
2637
|
+
const argsStr = content.substring(lparen + lparenToken.length, rparen);
|
|
2638
|
+
const args = _TokenParserManger.split(argsStr, argsSplitToken, [`[`, `]`]);
|
|
2639
|
+
const macro = _TokenParserManger.filterMacro(args);
|
|
2640
|
+
const tokens = [token];
|
|
2641
|
+
const expr = {
|
|
2642
|
+
express: value,
|
|
2643
|
+
func: funcName,
|
|
2644
|
+
value: args,
|
|
2645
|
+
// arguments array
|
|
2646
|
+
tokens
|
|
2647
|
+
};
|
|
2648
|
+
const alias = _TokenParserManger.extractUseAliasTokens(ctx, args);
|
|
2649
|
+
if (alias !== void 0 && alias.length > 0) {
|
|
2650
|
+
expr.tokens.push(...alias);
|
|
2651
|
+
}
|
|
2652
|
+
if (macro !== void 0 && macro.tokens.length > 0) {
|
|
2653
|
+
expr.macro = macro;
|
|
2654
|
+
expr.tokens.push(...macro.tokens);
|
|
2655
|
+
}
|
|
2656
|
+
return {
|
|
2657
|
+
ok: true,
|
|
2658
|
+
expr,
|
|
2659
|
+
values: [funcName, args]
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
return {
|
|
2664
|
+
ok: false,
|
|
2665
|
+
error: new Error(`function express systax error`)
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
static varPatternParse(ctx, token, value) {
|
|
2669
|
+
if (token !== "${?}" /* VarPatternToken */) {
|
|
2670
|
+
return { ok: false };
|
|
2671
|
+
}
|
|
2672
|
+
const wordToken = _TokenParserManger.getTokenByCtx(ctx, "?" /* AnyToken */);
|
|
2673
|
+
const varToken = _TokenParserManger.getTokenByCtx(ctx, "${?}" /* VarPatternToken */);
|
|
2674
|
+
const index = varToken.indexOf(wordToken);
|
|
2675
|
+
const workTokenOffset = wordToken.length;
|
|
2676
|
+
const startToken = varToken.substring(0, index);
|
|
2677
|
+
const endToken = varToken.substring(workTokenOffset + index);
|
|
2678
|
+
if (!value.startsWith(startToken) || !value.endsWith(endToken)) {
|
|
2679
|
+
return {
|
|
2680
|
+
ok: false,
|
|
2681
|
+
error: new Error(`variable expression syntax error,\${ or } flag is miss`)
|
|
2682
|
+
};
|
|
2683
|
+
}
|
|
2684
|
+
const innerContent = value.substring(startToken.length, value.length - endToken.length);
|
|
2685
|
+
if (innerContent === "") {
|
|
2686
|
+
return {
|
|
2687
|
+
ok: false,
|
|
2688
|
+
error: new Error("variable expression syntax error, variable name is empty")
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
const expr = {
|
|
2692
|
+
express: value,
|
|
2693
|
+
value: innerContent,
|
|
2694
|
+
tokens: [token]
|
|
2695
|
+
};
|
|
2696
|
+
const aliasToken = _TokenParserManger.getTokenByCtx(ctx, "@" /* UseAliasToken */);
|
|
2697
|
+
if (innerContent.indexOf(aliasToken) >= 0) {
|
|
2698
|
+
const parser = getTokenParser("@" /* UseAliasToken */);
|
|
2699
|
+
const aliasReply = parser.handler(ctx, "@" /* UseAliasToken */, innerContent);
|
|
2700
|
+
if (aliasReply.ok) {
|
|
2701
|
+
expr.ref = aliasReply.expr.ref;
|
|
2702
|
+
expr.alias = aliasReply.values;
|
|
2703
|
+
expr.tokens.push(...aliasReply.expr.tokens);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
return {
|
|
2707
|
+
expr,
|
|
2708
|
+
ok: true,
|
|
2709
|
+
values: [innerContent]
|
|
2710
|
+
};
|
|
2711
|
+
}
|
|
2712
|
+
// compile:GenCell(expr1,expr2,...,) => {G:13=>`${expr1}${expr2}..`,G:14=>`${expr1}${expr2}..`,G:15=>`${expr1}${expr2}..`,...}
|
|
2713
|
+
// compile:Macro($exprType,$X,$Y,$formater)
|
|
2714
|
+
// $exprType: enums [ expr:(single value), exprArr:(array value) ]
|
|
2715
|
+
// $X: column index value, number|string or number[]|string[]
|
|
2716
|
+
// $Y: row index value, number or number[]
|
|
2717
|
+
// $formater: enums [ codeKey(a function for format string),number(a function for string to number) ]
|
|
2718
|
+
// compile:Macro(exprArr,[X1,X2],[Y1,Y2],!codeKey) =>
|
|
2719
|
+
// codeKey(X1:Y1.value),codeKey(X1:Y2.value),codeKey(X2:Y1.value),codeKey(X2:Y2.value)
|
|
2720
|
+
// compile:Macro(exprArr,[X1],[Y1,Y2],!codeKey) => codeKey(X1:Y1.value),codeKey(X1:Y2.value)
|
|
2721
|
+
// compile:Marco(index,!number) => number(i),number(i+1),number(i+2) ,i=1
|
|
2722
|
+
static compileExprExtract(value) {
|
|
2723
|
+
const results = [];
|
|
2724
|
+
const lp = "(" /* LparenToken */.toString();
|
|
2725
|
+
const args = "," /* ArgPosToken */.toString();
|
|
2726
|
+
const values = value.split(lp);
|
|
2727
|
+
for (const v of values) {
|
|
2728
|
+
let items = [];
|
|
2729
|
+
if (v.indexOf(args) >= 0) {
|
|
2730
|
+
items = v.split(args);
|
|
2731
|
+
} else {
|
|
2732
|
+
items.push(v);
|
|
2733
|
+
}
|
|
2734
|
+
for (const it of items) {
|
|
2735
|
+
if (it === "compile:Macro" /* CompileMacroToken */.toString() || it.startsWith("compile:Macro" /* CompileMacroToken */) || it.endsWith("compile:Macro" /* CompileMacroToken */)) {
|
|
2736
|
+
results.push("compile:Macro" /* CompileMacroToken */);
|
|
2737
|
+
} else if (it === "compile:GenCell" /* CompileGenToken */.toString() || it.startsWith("compile:GenCell" /* CompileGenToken */) || it.endsWith("compile:GenCell" /* CompileGenToken */)) {
|
|
2738
|
+
results.push("compile:GenCell" /* CompileGenToken */);
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
return results;
|
|
2743
|
+
}
|
|
2744
|
+
static getTokenByCtx(ctx, token) {
|
|
2745
|
+
if (ctx.size <= 0 || !ctx.has(token)) {
|
|
2746
|
+
return token.toString();
|
|
2747
|
+
}
|
|
2748
|
+
const values = ctx.get(token);
|
|
2749
|
+
if (values.length <= 0 || values[0].key === "") {
|
|
2750
|
+
return token.toString();
|
|
2751
|
+
}
|
|
2752
|
+
return values[0].key;
|
|
2753
|
+
}
|
|
2754
|
+
static scanToken(value, startToken, endTokens) {
|
|
2755
|
+
let token = "";
|
|
2756
|
+
let data = "";
|
|
2757
|
+
let end = false;
|
|
2758
|
+
let start = false;
|
|
2759
|
+
const items = [];
|
|
2760
|
+
const offset = [startToken, ...endTokens].sort((a, b) => a.length - b.length)[0].length;
|
|
2761
|
+
const size = value.length;
|
|
2762
|
+
for (let i = 0; i < size; i += offset) {
|
|
2763
|
+
let leftToken;
|
|
2764
|
+
if (value[i] === startToken) {
|
|
2765
|
+
start = true;
|
|
2766
|
+
if (token !== "") {
|
|
2767
|
+
items.push({
|
|
2768
|
+
token,
|
|
2769
|
+
value: ""
|
|
2770
|
+
});
|
|
2771
|
+
}
|
|
2772
|
+
token = startToken;
|
|
2773
|
+
} else {
|
|
2774
|
+
start = token === startToken;
|
|
2775
|
+
leftToken = `${token}${value[i]}`;
|
|
2776
|
+
}
|
|
2777
|
+
let subfix = endTokens.filter((s) => s === leftToken);
|
|
2778
|
+
end = endTokens.includes(value[i]) || subfix.length > 0;
|
|
2779
|
+
if (subfix.length > 0) {
|
|
2780
|
+
token = leftToken;
|
|
2781
|
+
data = "";
|
|
2782
|
+
}
|
|
2783
|
+
if (start && end) {
|
|
2784
|
+
continue;
|
|
2785
|
+
}
|
|
2786
|
+
if (!end) {
|
|
2787
|
+
token = `${token}${value[i]}`;
|
|
2788
|
+
data = `${data}${value[i]}`;
|
|
2789
|
+
}
|
|
2790
|
+
if (end || i + offset >= size) {
|
|
2791
|
+
if (data !== "") {
|
|
2792
|
+
items.push({
|
|
2793
|
+
token,
|
|
2794
|
+
value: data
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
token = "";
|
|
2798
|
+
data = "";
|
|
2799
|
+
end = false;
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
return items;
|
|
2803
|
+
}
|
|
2804
|
+
static split(argsStr, argsSplitToken, ignoreTokenRange) {
|
|
2805
|
+
let value = "";
|
|
2806
|
+
let depth = 0;
|
|
2807
|
+
const items = [];
|
|
2808
|
+
const splitLen = argsSplitToken.length;
|
|
2809
|
+
const startLen = ignoreTokenRange[0].length;
|
|
2810
|
+
const endLen = ignoreTokenRange[1].length;
|
|
2811
|
+
const startToken = ignoreTokenRange[0];
|
|
2812
|
+
const endToken = ignoreTokenRange[1];
|
|
2813
|
+
const isToggleMode = startToken === endToken;
|
|
2814
|
+
for (let i = 0; i < argsStr.length; ) {
|
|
2815
|
+
const substr = argsStr.substring(i);
|
|
2816
|
+
if (depth > 0 && substr.startsWith(endToken)) {
|
|
2817
|
+
value += endToken;
|
|
2818
|
+
i += endLen;
|
|
2819
|
+
depth = isToggleMode ? 0 : depth - 1;
|
|
2820
|
+
continue;
|
|
2821
|
+
}
|
|
2822
|
+
if (substr.startsWith(startToken)) {
|
|
2823
|
+
if (!isToggleMode || depth === 0) {
|
|
2824
|
+
value += startToken;
|
|
2825
|
+
i += startLen;
|
|
2826
|
+
depth++;
|
|
2827
|
+
continue;
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
if (depth === 0 && substr.startsWith(argsSplitToken)) {
|
|
2831
|
+
items.push(value);
|
|
2832
|
+
value = "";
|
|
2833
|
+
i += splitLen;
|
|
2834
|
+
continue;
|
|
2835
|
+
}
|
|
2836
|
+
value += argsStr[i];
|
|
2837
|
+
i++;
|
|
2838
|
+
}
|
|
2839
|
+
if (value !== "") {
|
|
2840
|
+
items.push(value);
|
|
2841
|
+
}
|
|
2842
|
+
return items;
|
|
2843
|
+
}
|
|
2844
|
+
static filterMacro(values) {
|
|
2845
|
+
const filter = {
|
|
2846
|
+
tokens: [],
|
|
2847
|
+
express: []
|
|
2848
|
+
};
|
|
2849
|
+
for (const expr of values) {
|
|
2850
|
+
let items = _TokenParserManger.compileExprExtract(expr);
|
|
2851
|
+
if (items === void 0 || items.length <= 0) {
|
|
2852
|
+
continue;
|
|
2853
|
+
}
|
|
2854
|
+
filter.express.push(expr);
|
|
2855
|
+
filter.tokens.push(...items);
|
|
2856
|
+
}
|
|
2857
|
+
return filter.tokens.push() <= 0 ? void 0 : filter;
|
|
2858
|
+
}
|
|
2859
|
+
static extractUseAliasTokens(ctx, args) {
|
|
2860
|
+
const tokens = [];
|
|
2861
|
+
const useAliasToken = _TokenParserManger.getTokenByCtx(ctx, "@" /* UseAliasToken */);
|
|
2862
|
+
args.forEach((v) => v.startsWith(useAliasToken) && tokens.push("@" /* UseAliasToken */));
|
|
2863
|
+
return tokens;
|
|
2864
|
+
}
|
|
2865
|
+
static toList(ctx, endTokens) {
|
|
2866
|
+
const items = [];
|
|
2867
|
+
for (const token of endTokens) {
|
|
2868
|
+
items.push(_TokenParserManger.getTokenByCtx(ctx, token));
|
|
2869
|
+
}
|
|
2870
|
+
return items;
|
|
2871
|
+
}
|
|
2872
|
+
static parseRangeValue(ctx, options) {
|
|
2873
|
+
let rowReply;
|
|
2874
|
+
let columnReply;
|
|
2875
|
+
const rangeCell = {
|
|
2876
|
+
stepRow: 1,
|
|
2877
|
+
stepColumn: 1,
|
|
2878
|
+
minColumn: 0,
|
|
2879
|
+
minRow: 0,
|
|
2880
|
+
maxRow: 0,
|
|
2881
|
+
maxColumn: 0,
|
|
2882
|
+
getCells: function() {
|
|
2883
|
+
return _getCells(this);
|
|
2884
|
+
}
|
|
2885
|
+
};
|
|
2886
|
+
const { rowRange, row, column, columnRange, express, token } = options;
|
|
2887
|
+
const rangeParse = getTokenParser("-" /* RangeToken */);
|
|
2888
|
+
if (rowRange > 0) {
|
|
2889
|
+
columnReply = rangeParse.handler(ctx, "-" /* RangeToken */, row);
|
|
2890
|
+
} else {
|
|
2891
|
+
const rowValue = Number.parseInt(row, 10);
|
|
2892
|
+
rangeCell.maxRow = rowValue;
|
|
2893
|
+
rangeCell.minRow = rowValue;
|
|
2894
|
+
}
|
|
2895
|
+
if (columnRange > 0) {
|
|
2896
|
+
rowReply = rangeParse.handler(ctx, "-" /* RangeToken */, column);
|
|
2897
|
+
} else {
|
|
2898
|
+
const columnValue = columnLetterToNumber(column);
|
|
2899
|
+
rangeCell.maxColumn = columnValue;
|
|
2900
|
+
rangeCell.minColumn = columnValue;
|
|
2901
|
+
}
|
|
2902
|
+
if (columnReply !== void 0) {
|
|
2903
|
+
if (!columnReply.ok || columnReply.values === void 0) {
|
|
2904
|
+
return columnReply;
|
|
2905
|
+
}
|
|
2906
|
+
const values = columnReply.values;
|
|
2907
|
+
let min = values[0];
|
|
2908
|
+
let max = values[1];
|
|
2909
|
+
let setup = values[2] ?? 1;
|
|
2910
|
+
rangeCell.minRow = min;
|
|
2911
|
+
rangeCell.maxRow = max;
|
|
2912
|
+
rangeCell.stepRow = setup;
|
|
2913
|
+
}
|
|
2914
|
+
if (rowReply !== void 0) {
|
|
2915
|
+
if (!rowReply.ok || rowReply.values === void 0) {
|
|
2916
|
+
return rowReply;
|
|
2917
|
+
}
|
|
2918
|
+
const values = rowReply.values;
|
|
2919
|
+
let min = values[0];
|
|
2920
|
+
let max = values[1];
|
|
2921
|
+
let setup = values[2] ?? 1;
|
|
2922
|
+
rangeCell.minColumn = min;
|
|
2923
|
+
rangeCell.maxColumn = max;
|
|
2924
|
+
rangeCell.stepColumn = setup;
|
|
2925
|
+
}
|
|
2926
|
+
const expr = {
|
|
2927
|
+
express,
|
|
2928
|
+
tokens: [token],
|
|
2929
|
+
// express tokens
|
|
2930
|
+
value: rangeCell
|
|
2931
|
+
// alias value
|
|
2932
|
+
};
|
|
2933
|
+
return {
|
|
2934
|
+
ok: true,
|
|
2935
|
+
expr,
|
|
2936
|
+
values: rangeCell
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2939
|
+
static parsePosNumber(value) {
|
|
2940
|
+
let num = NaN;
|
|
2941
|
+
if (isPureNumber.test(value)) {
|
|
2942
|
+
num = Number.parseInt(value, 10);
|
|
2943
|
+
} else if (isPureUppercase.test(value)) {
|
|
2944
|
+
num = columnLetterToNumber(value);
|
|
2945
|
+
}
|
|
2946
|
+
return !isNaN(num) && num <= 0 ? NaN : num;
|
|
2947
|
+
}
|
|
2948
|
+
};
|
|
2949
|
+
var defaultRuleTokenParserMap = /* @__PURE__ */ new Map([
|
|
2950
|
+
["alias" /* AliasToken */, TokenParserManger.aliasParse],
|
|
2951
|
+
["cell" /* CellToken */, TokenParserManger.cellParse],
|
|
2952
|
+
["=" /* EqualToken */, TokenParserManger.equalParse],
|
|
2953
|
+
["mergeCell" /* MergeCellToken */, TokenParserManger.mergeCellParse],
|
|
2954
|
+
["rowCell" /* RowCellToken */, TokenParserManger.rowCellParse],
|
|
2955
|
+
["@" /* UseAliasToken */, TokenParserManger.useAliasParse],
|
|
2956
|
+
["-" /* RangeToken */, TokenParserManger.rangeParse],
|
|
2957
|
+
[":" /* PosToken */, TokenParserManger.posParse],
|
|
2958
|
+
["${?}" /* VarPatternToken */, TokenParserManger.varPatternParse],
|
|
2959
|
+
["<?>" /* FunctionPatternToken */, TokenParserManger.functionPatternParse]
|
|
2960
|
+
]);
|
|
2961
|
+
var macroTokens = ["compile:GenCell" /* CompileGenToken */, "compile:Macro" /* CompileMacroToken */];
|
|
2962
|
+
function columnLetterToNumber(letter) {
|
|
2963
|
+
let num = 0;
|
|
2964
|
+
for (let i = 0; i < letter.length; i++) {
|
|
2965
|
+
num = num * 26 + (letter.charCodeAt(i) - 64);
|
|
2966
|
+
}
|
|
2967
|
+
return num;
|
|
2968
|
+
}
|
|
2969
|
+
function columnNumberToLetter(num) {
|
|
2970
|
+
if (num <= 0) {
|
|
2971
|
+
return "";
|
|
2972
|
+
}
|
|
2973
|
+
let letter = "";
|
|
2974
|
+
while (num > 0) {
|
|
2975
|
+
let remainder = (num - 1) % 26;
|
|
2976
|
+
letter = String.fromCharCode(65 + remainder) + letter;
|
|
2977
|
+
num = Math.floor((num - 1) / 26);
|
|
2978
|
+
}
|
|
2979
|
+
return letter;
|
|
2980
|
+
}
|
|
2981
|
+
function isBase64(str) {
|
|
2982
|
+
if (str.length < 20) return false;
|
|
2983
|
+
if (str.includes("\\") || str.includes(" ")) return false;
|
|
2984
|
+
if (str.indexOf("./") >= 0 || str.startsWith("file://") || str.startsWith("/") || str.startsWith(".")) {
|
|
2985
|
+
return false;
|
|
2986
|
+
}
|
|
2987
|
+
const data = str.replace(/^data:.*?;base64,/, "");
|
|
2988
|
+
const cleanedStr = data.replace(/[\r\n]/g, "");
|
|
2989
|
+
try {
|
|
2990
|
+
return Buffer.from(cleanedStr, "base64").toString("utf-8") !== "";
|
|
2991
|
+
} catch (e) {
|
|
2992
|
+
return false;
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
function base64ToArrayBuffer(base64) {
|
|
2996
|
+
const data = base64.replace(/^data:.*?;base64,/, "");
|
|
2997
|
+
const binaryString = atob(data);
|
|
2998
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
2999
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
3000
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
3001
|
+
}
|
|
3002
|
+
return bytes.buffer;
|
|
3003
|
+
}
|
|
3004
|
+
function getMergeRange(ws, row, col) {
|
|
3005
|
+
const merges = ws.model.merges;
|
|
3006
|
+
for (const mergeStr of merges) {
|
|
3007
|
+
const parts = mergeStr.split(":");
|
|
3008
|
+
const tl = ws.getCell(parts[0]);
|
|
3009
|
+
const br = ws.getCell(parts[1]);
|
|
3010
|
+
const tlRow = Number(tl.row);
|
|
3011
|
+
const tlCol = Number(tl.col);
|
|
3012
|
+
const brRow = Number(br.row);
|
|
3013
|
+
const brCol = Number(br.col);
|
|
3014
|
+
if (row >= tlRow && row <= brRow && col >= tlCol && col <= brCol) {
|
|
3015
|
+
return {
|
|
3016
|
+
top: tlRow,
|
|
3017
|
+
left: tlCol,
|
|
3018
|
+
bottom: brRow,
|
|
3019
|
+
right: brCol
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
return null;
|
|
3024
|
+
}
|
|
3025
|
+
var resolveCompileMacroGen = (ctx, expr, currentCellIndex) => {
|
|
3026
|
+
let parts = [];
|
|
3027
|
+
let join2 = ".";
|
|
3028
|
+
const m = ctx.getContextMap();
|
|
3029
|
+
const aliasToken = TokenParserManger.getTokenByCtx(m, "@" /* UseAliasToken */);
|
|
3030
|
+
const genToken = TokenParserManger.getTokenByCtx(m, "compile:GenCell" /* CompileGenToken */);
|
|
3031
|
+
const endTokens = ["compile:GenCell" /* CompileGenToken */, "(" /* LparenToken */, "," /* ArgPosToken */, ")" /* RparenToken */];
|
|
3032
|
+
const values = TokenParserManger.scanToken(expr, genToken, TokenParserManger.toList(m, endTokens));
|
|
3033
|
+
for (const [_, item] of values.entries()) {
|
|
3034
|
+
if (item.value === void 0 && item.value !== "") {
|
|
3035
|
+
continue;
|
|
3036
|
+
}
|
|
3037
|
+
if (!item.token.startsWith(aliasToken) && item.value !== exprIndex) {
|
|
3038
|
+
parts.push(item.value);
|
|
3039
|
+
} else {
|
|
3040
|
+
parts.push(resolveAliasExpr(ctx, item.value, currentCellIndex));
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
return parts.join(join2);
|
|
3044
|
+
};
|
|
3045
|
+
var getExprEnd = function(macroExpr, matchIndex, rparenToken) {
|
|
3046
|
+
return macroExpr.indexOf(rparenToken, matchIndex);
|
|
3047
|
+
};
|
|
3048
|
+
var macroFormatters = [numberKey, codeKey];
|
|
3049
|
+
var extractMacro = function(expr, options) {
|
|
3050
|
+
let end = NaN;
|
|
3051
|
+
const offset = options.startToken.length;
|
|
3052
|
+
const startIndex = expr.indexOf(options.startToken);
|
|
3053
|
+
const endIndex = expr.indexOf(options.endToken);
|
|
3054
|
+
const argValues = expr.substring(startIndex + offset, endIndex);
|
|
3055
|
+
const values = argValues.split(options.argToken);
|
|
3056
|
+
const extracResult = { type: values[0], rowParam: [], columnParam: void 0 };
|
|
3057
|
+
if (values.length > 1) {
|
|
3058
|
+
extracResult.columnParam = columnLetterToNumber(values[1]);
|
|
3059
|
+
}
|
|
3060
|
+
if (macroFormatters.includes(values[values.length - 1])) {
|
|
3061
|
+
end = values.length - 1;
|
|
3062
|
+
extracResult.formatter = values[end];
|
|
3063
|
+
}
|
|
3064
|
+
if (!isNaN(end) && values.length > 2) {
|
|
3065
|
+
extracResult.rowParam = values.slice(2, end).map((x) => Number.parseInt(x, 10));
|
|
3066
|
+
} else if (values.length > 2) {
|
|
3067
|
+
extracResult.rowParam = values.slice(2, values.length).map((x) => Number.parseInt(x, 10));
|
|
3068
|
+
}
|
|
3069
|
+
if (extracResult.rowParam !== void 0 && extracResult.rowParam instanceof Array && extracResult.rowParam.length === 1) {
|
|
3070
|
+
extracResult.rowParam = extracResult.rowParam[0];
|
|
3071
|
+
}
|
|
3072
|
+
return extracResult;
|
|
3073
|
+
};
|
|
3074
|
+
var __codeKey = (str) => {
|
|
3075
|
+
let vs = str.trim().replace("-", "_").replace("/", "_").trim();
|
|
3076
|
+
for (; vs.indexOf("__") >= 0; ) {
|
|
3077
|
+
vs = vs.replace("__", "_");
|
|
3078
|
+
}
|
|
3079
|
+
for (; vs.indexOf(" ") >= 0; ) {
|
|
3080
|
+
vs = vs.replace(" ", "");
|
|
3081
|
+
}
|
|
3082
|
+
return vs.trim().toUpperCase();
|
|
3083
|
+
};
|
|
3084
|
+
var __numberKey = (str) => {
|
|
3085
|
+
return Number.parseInt(str, 10).toString();
|
|
3086
|
+
};
|
|
3087
|
+
var macroFormatter = /* @__PURE__ */ new Map([
|
|
3088
|
+
[codeKey, __codeKey],
|
|
3089
|
+
[numberKey, __numberKey],
|
|
3090
|
+
[defaultKey, (v) => v]
|
|
3091
|
+
]);
|
|
3092
|
+
var execMacroFormat = function(value, formatter) {
|
|
3093
|
+
if (!macroFormatter.has(formatter)) {
|
|
3094
|
+
return value;
|
|
3095
|
+
}
|
|
3096
|
+
return macroFormatter.get(formatter)(value);
|
|
3097
|
+
};
|
|
3098
|
+
var toCellRow = (rowVals, setup) => {
|
|
3099
|
+
if (setup === void 0) {
|
|
3100
|
+
setup = 1;
|
|
3101
|
+
}
|
|
3102
|
+
if (rowVals.length == 2) {
|
|
3103
|
+
const values = [];
|
|
3104
|
+
for (let start = rowVals[0]; start <= rowVals[1]; start += setup) {
|
|
3105
|
+
values.push(start);
|
|
3106
|
+
}
|
|
3107
|
+
return values;
|
|
3108
|
+
}
|
|
3109
|
+
return rowVals;
|
|
3110
|
+
};
|
|
3111
|
+
var toCellColumn = (columnVals, setup) => {
|
|
3112
|
+
return toCellRow(columnVals, setup);
|
|
3113
|
+
};
|
|
3114
|
+
var resolveCompileMacroExpr = (ctx, macroExpr, macroTokens2, currentCellIndex, totalCells) => {
|
|
3115
|
+
if (macroTokens2 === void 0 || macroTokens2.length <= 0) {
|
|
3116
|
+
return macroExpr;
|
|
3117
|
+
}
|
|
3118
|
+
const sheet = ctx.sheet;
|
|
3119
|
+
if (sheet === void 0) {
|
|
3120
|
+
throw new Error(`miss context worksheet`);
|
|
3121
|
+
}
|
|
3122
|
+
const m = ctx.getContextMap();
|
|
3123
|
+
const argToken = TokenParserManger.getTokenByCtx(m, "," /* ArgPosToken */);
|
|
3124
|
+
const rparenToken = TokenParserManger.getTokenByCtx(m, ")" /* RparenToken */);
|
|
3125
|
+
const lparenToken = TokenParserManger.getTokenByCtx(m, "(" /* LparenToken */);
|
|
3126
|
+
const genToken = TokenParserManger.getTokenByCtx(m, "compile:GenCell" /* CompileGenToken */);
|
|
3127
|
+
const maroToken = TokenParserManger.getTokenByCtx(m, "compile:Macro" /* CompileMacroToken */);
|
|
3128
|
+
const tokenMap = /* @__PURE__ */ new Map();
|
|
3129
|
+
for (const [index, token] of macroTokens2.entries()) {
|
|
3130
|
+
let items = [];
|
|
3131
|
+
if (tokenMap.has(token)) {
|
|
3132
|
+
items = tokenMap.get(token);
|
|
3133
|
+
}
|
|
3134
|
+
items.push(index);
|
|
3135
|
+
tokenMap.set(token, items);
|
|
3136
|
+
}
|
|
3137
|
+
const resolveArray = (param) => {
|
|
3138
|
+
if (param instanceof Array) {
|
|
3139
|
+
return param;
|
|
3140
|
+
}
|
|
3141
|
+
return [param];
|
|
3142
|
+
};
|
|
3143
|
+
if (tokenMap.has("compile:Macro" /* CompileMacroToken */)) {
|
|
3144
|
+
let offset = 0;
|
|
3145
|
+
let exprValue = macroExpr;
|
|
3146
|
+
const times = tokenMap.get("compile:Macro" /* CompileMacroToken */).length;
|
|
3147
|
+
for (let i = times; i > 0; i--) {
|
|
3148
|
+
const matchIndex = exprValue.indexOf(maroToken, offset);
|
|
3149
|
+
if (matchIndex < 0) {
|
|
3150
|
+
break;
|
|
3151
|
+
}
|
|
3152
|
+
offset = getExprEnd(exprValue, matchIndex, rparenToken);
|
|
3153
|
+
const macroCurrent = exprValue.substring(matchIndex, offset + rparenToken.length);
|
|
3154
|
+
const opts = { startToken: lparenToken, endToken: rparenToken, argToken };
|
|
3155
|
+
let { type, columnParam, rowParam, formatter } = extractMacro(macroCurrent, opts);
|
|
3156
|
+
let rowVals;
|
|
3157
|
+
let columnVals;
|
|
3158
|
+
const parts = [];
|
|
3159
|
+
if (columnParam !== void 0 && rowParam !== void 0) {
|
|
3160
|
+
rowVals = resolveArray(rowParam);
|
|
3161
|
+
columnVals = resolveArray(columnParam);
|
|
3162
|
+
const rowItems = toCellRow(rowVals);
|
|
3163
|
+
const columnItems = toCellColumn(columnVals);
|
|
3164
|
+
rowItems.forEach((r) => {
|
|
3165
|
+
columnItems.forEach((c) => {
|
|
3166
|
+
const cellValue = sheet.findCell(r, c);
|
|
3167
|
+
if (cellValue === void 0 || cellValue.value === null) {
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
3170
|
+
const value = cellValue.value;
|
|
3171
|
+
parts.push(execMacroFormat(value.toString(), formatter));
|
|
3172
|
+
});
|
|
3173
|
+
});
|
|
3174
|
+
}
|
|
3175
|
+
if (type === exprArr) {
|
|
3176
|
+
macroExpr = macroExpr.replace(macroCurrent, parts.join(","));
|
|
3177
|
+
} else if (type === exprSingle) {
|
|
3178
|
+
macroExpr = macroExpr.replace(macroCurrent, parts[0]);
|
|
3179
|
+
} else if (type === exprIndex) {
|
|
3180
|
+
const indexValue = currentCellIndex + 1;
|
|
3181
|
+
macroExpr = macroExpr.replace(macroCurrent, indexValue.toString());
|
|
3182
|
+
}
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
if (tokenMap.has("compile:GenCell" /* CompileGenToken */)) {
|
|
3186
|
+
let exprValue = macroExpr;
|
|
3187
|
+
const times = tokenMap.get("compile:GenCell" /* CompileGenToken */).length;
|
|
3188
|
+
for (let i = times; i > 0; i--) {
|
|
3189
|
+
const matchIndex = exprValue.indexOf(genToken);
|
|
3190
|
+
if (matchIndex < 0) {
|
|
3191
|
+
break;
|
|
3192
|
+
}
|
|
3193
|
+
const offset = getExprEnd(exprValue, matchIndex, rparenToken);
|
|
3194
|
+
const macroCurrent = exprValue.substring(matchIndex, offset + rparenToken.length);
|
|
3195
|
+
exprValue = resolveCompileMacroGen(ctx, macroCurrent, currentCellIndex);
|
|
3196
|
+
}
|
|
3197
|
+
macroExpr = exprValue;
|
|
3198
|
+
}
|
|
3199
|
+
return macroExpr;
|
|
3200
|
+
};
|
|
3201
|
+
var loadWorkbook = async function(data) {
|
|
3202
|
+
const w = new import_exceljs.default.Workbook();
|
|
3203
|
+
if (typeof data === "string") {
|
|
3204
|
+
if (!isBase64(data)) {
|
|
3205
|
+
await w.xlsx.readFile(data);
|
|
3206
|
+
} else {
|
|
3207
|
+
await w.xlsx.load(base64ToArrayBuffer(data));
|
|
3208
|
+
}
|
|
3209
|
+
} else if (data instanceof import_stream.Stream) {
|
|
3210
|
+
await w.xlsx.read(data);
|
|
3211
|
+
} else if (data instanceof ArrayBuffer) {
|
|
3212
|
+
await w.xlsx.load(data);
|
|
3213
|
+
} else if (data instanceof Buffer) {
|
|
3214
|
+
await w.xlsx.load(data);
|
|
3215
|
+
} else {
|
|
3216
|
+
throw new Error(`unSupport buffer type ${typeof data}`);
|
|
3217
|
+
}
|
|
3218
|
+
return w;
|
|
3219
|
+
};
|
|
3220
|
+
var scanCellSetPlaceholder = async function(excelBuffer, cell, placeholder) {
|
|
3221
|
+
const workbook = await loadWorkbook(excelBuffer);
|
|
3222
|
+
const worksheet = workbook.getWorksheet(cell.Sheet);
|
|
3223
|
+
if (!worksheet) return void 0;
|
|
3224
|
+
workSheetSetPlaceholder(worksheet, cell, placeholder);
|
|
3225
|
+
return workbook.xlsx.writeBuffer();
|
|
3226
|
+
};
|
|
3227
|
+
var workSheetSetPlaceholder = function(worksheet, cell, placeholder) {
|
|
3228
|
+
const colNum = columnLetterToNumber(cell.Row);
|
|
3229
|
+
const rowNum = cell.Column;
|
|
3230
|
+
const targetCell = worksheet.getCell(rowNum, colNum);
|
|
3231
|
+
if (targetCell.isMerged) {
|
|
3232
|
+
const range = getMergeRange(worksheet, rowNum, colNum);
|
|
3233
|
+
if (range) {
|
|
3234
|
+
const leftCol = colNum - 1;
|
|
3235
|
+
const values = [];
|
|
3236
|
+
if (leftCol > 0) {
|
|
3237
|
+
for (let r = range.top; r <= range.bottom; r++) {
|
|
3238
|
+
const val = worksheet.getCell(r, leftCol).value;
|
|
3239
|
+
if (val !== null && val !== void 0 && val !== "") {
|
|
3240
|
+
values.push(String(val));
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
}
|
|
3244
|
+
if (values.length === 0) {
|
|
3245
|
+
targetCell.value = placeholder.toString();
|
|
3246
|
+
} else {
|
|
3247
|
+
targetCell.value = placeholder.mergeCell(values);
|
|
3248
|
+
}
|
|
3249
|
+
return worksheet;
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
const currentValue = targetCell.value;
|
|
3253
|
+
if (currentValue === null || currentValue === void 0 || currentValue === "") {
|
|
3254
|
+
targetCell.value = placeholder.toString();
|
|
3255
|
+
}
|
|
3256
|
+
return worksheet;
|
|
3257
|
+
};
|
|
3258
|
+
var compileCellTokens = ["cell" /* CellToken */, "mergeCell" /* MergeCellToken */, "rowCell" /* RowCellToken */];
|
|
3259
|
+
var ruleTokens = ["alias" /* AliasToken */, "cell" /* CellToken */, "mergeCell" /* MergeCellToken */, "rowCell" /* RowCellToken */];
|
|
3260
|
+
var isRuleToken = function(t) {
|
|
3261
|
+
return ruleTokens.includes(t);
|
|
3262
|
+
};
|
|
3263
|
+
var mergeOption = function(ruleKeyMap, defaultRuleTokenMap2) {
|
|
3264
|
+
for (const [key, value] of defaultRuleTokenMap2.entries()) {
|
|
3265
|
+
if (!ruleKeyMap.has(key)) {
|
|
3266
|
+
ruleKeyMap.set(key, value);
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
return ruleKeyMap;
|
|
3270
|
+
};
|
|
3271
|
+
var getTokenParser = function(token) {
|
|
3272
|
+
if (!defaultRuleTokenParserMap.has(token)) {
|
|
3273
|
+
return {
|
|
3274
|
+
exists: false
|
|
3275
|
+
};
|
|
3276
|
+
}
|
|
3277
|
+
return {
|
|
3278
|
+
exists: true,
|
|
3279
|
+
handler: defaultRuleTokenParserMap.get(token)
|
|
3280
|
+
};
|
|
3281
|
+
};
|
|
3282
|
+
var registerTokenParser = function(token, h) {
|
|
3283
|
+
if (defaultRuleTokenParserMap.has(token)) {
|
|
3284
|
+
return false;
|
|
3285
|
+
}
|
|
3286
|
+
defaultRuleTokenParserMap.set(token, h);
|
|
3287
|
+
return true;
|
|
3288
|
+
};
|
|
3289
|
+
var registerTokenParserMust = function(token, h) {
|
|
3290
|
+
defaultRuleTokenParserMap.set(token, h);
|
|
3291
|
+
};
|
|
3292
|
+
var scanWorkSheetRules = function(worksheet, options) {
|
|
3293
|
+
const result = { rules: options.getContextMap() };
|
|
3294
|
+
for (let r = options.startLine; r <= options.endLine; r++) {
|
|
3295
|
+
let emptyValue = false;
|
|
3296
|
+
let ruleToken = "" /* UndefinedToken */;
|
|
3297
|
+
for (let c = options.startColumn; c <= options.endColumn; c++) {
|
|
3298
|
+
const cell = worksheet.findCell(r, c);
|
|
3299
|
+
if (cell === void 0 || cell.value === void 0 || cell.value === null) {
|
|
3300
|
+
continue;
|
|
3301
|
+
}
|
|
3302
|
+
const cellValue = cell.value;
|
|
3303
|
+
const value = cellValue.toString();
|
|
3304
|
+
let isStartCell = c === options.startColumn;
|
|
3305
|
+
if (emptyValue && ruleToken === "" /* UndefinedToken */) {
|
|
3306
|
+
isStartCell = true;
|
|
3307
|
+
}
|
|
3308
|
+
if (value === "" && isStartCell) {
|
|
3309
|
+
emptyValue = true;
|
|
3310
|
+
continue;
|
|
3311
|
+
}
|
|
3312
|
+
if (isStartCell) {
|
|
3313
|
+
ruleToken = options.parseToken(value);
|
|
3314
|
+
continue;
|
|
3315
|
+
} else {
|
|
3316
|
+
if (!isRuleToken(ruleToken)) {
|
|
3317
|
+
break;
|
|
3318
|
+
}
|
|
3319
|
+
emptyValue = false;
|
|
3320
|
+
}
|
|
3321
|
+
const { handler, exists } = getTokenParser(ruleToken);
|
|
3322
|
+
if (!exists) {
|
|
3323
|
+
continue;
|
|
3324
|
+
}
|
|
3325
|
+
let values = [];
|
|
3326
|
+
if (result.rules.has(ruleToken)) {
|
|
3327
|
+
values = result.rules.get(ruleToken);
|
|
3328
|
+
}
|
|
3329
|
+
const { expr, ok } = handler(result.rules, ruleToken, value);
|
|
3330
|
+
if (ok && expr !== void 0) {
|
|
3331
|
+
values.push(expr);
|
|
3332
|
+
}
|
|
3333
|
+
result.rules.set(ruleToken, values);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
return result;
|
|
3337
|
+
};
|
|
3338
|
+
var parseWorkSheetRules = function(worksheet, options) {
|
|
3339
|
+
const result = { rules: /* @__PURE__ */ new Map() };
|
|
3340
|
+
if (worksheet === void 0 || worksheet === null) {
|
|
3341
|
+
return result;
|
|
3342
|
+
}
|
|
3343
|
+
if (options === void 0) {
|
|
3344
|
+
options = new RuleMapOptions();
|
|
3345
|
+
}
|
|
3346
|
+
return scanWorkSheetRules(worksheet, options.parseDefault(worksheet));
|
|
3347
|
+
};
|
|
3348
|
+
var compileCheck = function(iv, ctx) {
|
|
3349
|
+
if (iv.rules.size <= 0) {
|
|
3350
|
+
return void 0;
|
|
3351
|
+
}
|
|
3352
|
+
const errs = [];
|
|
3353
|
+
const values = iv.rules.get("alias" /* AliasToken */);
|
|
3354
|
+
if (values !== void 0 && values.length > 0) {
|
|
3355
|
+
const set = /* @__PURE__ */ new Set();
|
|
3356
|
+
for (const [idx, value] of values.entries()) {
|
|
3357
|
+
if (idx === 0) {
|
|
3358
|
+
set.add(value.key);
|
|
3359
|
+
continue;
|
|
3360
|
+
}
|
|
3361
|
+
if (set.has(value.key)) {
|
|
3362
|
+
errs.push(Error(`Duplicate alias(${value.key},${value.express}) configuration`));
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
const handlers = ctx.getCompileCheckHandlers();
|
|
3367
|
+
if (handlers !== void 0 && handlers.length > 0) {
|
|
3368
|
+
for (const h of handlers) {
|
|
3369
|
+
let err = h(iv, ctx);
|
|
3370
|
+
if (err !== void 0 && err.length > 0) {
|
|
3371
|
+
errs.push(...err);
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
if (errs.length > 0) {
|
|
3376
|
+
return errs;
|
|
3377
|
+
}
|
|
3378
|
+
return void 0;
|
|
3379
|
+
};
|
|
3380
|
+
var getMacroTokens = function(expr) {
|
|
3381
|
+
const tokens = [];
|
|
3382
|
+
for (const token of expr.tokens) {
|
|
3383
|
+
if (macroTokens.includes(token)) {
|
|
3384
|
+
tokens.push(token);
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
return tokens;
|
|
3388
|
+
};
|
|
3389
|
+
var toRowCells = function(cells) {
|
|
3390
|
+
const indexes = [];
|
|
3391
|
+
const rows = [];
|
|
3392
|
+
const rowMap = /* @__PURE__ */ new Map();
|
|
3393
|
+
for (const cell of cells) {
|
|
3394
|
+
let cells2 = [];
|
|
3395
|
+
if (rowMap.has(cell.Row)) {
|
|
3396
|
+
cells2 = rowMap.get(cell.Row);
|
|
3397
|
+
} else {
|
|
3398
|
+
indexes.push(cell.Row);
|
|
3399
|
+
}
|
|
3400
|
+
cells2.push(cell);
|
|
3401
|
+
rowMap.set(cell.Row, cells2);
|
|
3402
|
+
}
|
|
3403
|
+
indexes.sort((a, b) => a - b);
|
|
3404
|
+
for (const row of indexes) {
|
|
3405
|
+
const values = rowMap.get(row);
|
|
3406
|
+
rows.push(values);
|
|
3407
|
+
}
|
|
3408
|
+
return rows;
|
|
3409
|
+
};
|
|
3410
|
+
var resolveFunctionExpr = (ctx, templateValue, expr) => {
|
|
3411
|
+
const anyToken = defaultRuleTokenMap.get("?" /* AnyToken */);
|
|
3412
|
+
const funToken = defaultRuleTokenMap.get("<?>" /* FunctionPatternToken */);
|
|
3413
|
+
const functionTokens = expr.tokens.filter((s) => s === "<?>" /* FunctionPatternToken */);
|
|
3414
|
+
if (functionTokens === void 0 || functionTokens.length <= 0) {
|
|
3415
|
+
return templateValue;
|
|
3416
|
+
}
|
|
3417
|
+
const [start, end] = funToken.split(anyToken);
|
|
3418
|
+
for (let times = functionTokens.length; times > 0; times--) {
|
|
3419
|
+
const index = templateValue.indexOf(start);
|
|
3420
|
+
const offset = templateValue.indexOf(end);
|
|
3421
|
+
if (offset > 0 && index >= 0) {
|
|
3422
|
+
templateValue = templateValue.replace(start, funcCommand).replace(end, "");
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
return templateValue;
|
|
3426
|
+
};
|
|
3427
|
+
var searchIndexOf = (str, substr, position) => {
|
|
3428
|
+
let index = NaN;
|
|
3429
|
+
for (let sub of substr) {
|
|
3430
|
+
if (position === void 0 || position === null) {
|
|
3431
|
+
index = str.indexOf(sub);
|
|
3432
|
+
} else {
|
|
3433
|
+
index = str.indexOf(sub, position);
|
|
3434
|
+
}
|
|
3435
|
+
if (!isNaN(index) && index >= 0) {
|
|
3436
|
+
return index;
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
return -1;
|
|
3440
|
+
};
|
|
3441
|
+
var resolveAliasExpr = (ctx, templateValue, index) => {
|
|
3442
|
+
const expr = ctx.currentExpr;
|
|
3443
|
+
if (expr === void 0) {
|
|
3444
|
+
throw new Error(`miss context expr value`);
|
|
3445
|
+
}
|
|
3446
|
+
let compileValue = templateValue;
|
|
3447
|
+
const aliasToken = defaultRuleTokenMap.get("@" /* UseAliasToken */);
|
|
3448
|
+
let aliasTokens = expr.tokens.filter((s) => s === "@" /* UseAliasToken */);
|
|
3449
|
+
if (aliasTokens.length <= 0) {
|
|
3450
|
+
const num = templateValue.split(aliasToken).length - 1;
|
|
3451
|
+
if (num > 0) {
|
|
3452
|
+
aliasTokens = new Array(num).fill(aliasToken);
|
|
3453
|
+
}
|
|
3454
|
+
}
|
|
3455
|
+
if (aliasTokens !== void 0 && aliasTokens.length > 0) {
|
|
3456
|
+
for (let i = 0; i < aliasTokens.length; ++i) {
|
|
3457
|
+
const token = aliasToken;
|
|
3458
|
+
const start = compileValue.indexOf(token);
|
|
3459
|
+
if (start < 0) {
|
|
3460
|
+
break;
|
|
3461
|
+
}
|
|
3462
|
+
const offset = aliasTokens[i].length;
|
|
3463
|
+
let end = searchIndexOf(compileValue, [",", ".", ")", "]"], start);
|
|
3464
|
+
if (end < 0) {
|
|
3465
|
+
end = compileValue.length;
|
|
3466
|
+
}
|
|
3467
|
+
const sv = compileValue.substring(start + offset, end);
|
|
3468
|
+
const pl = `${token}${sv}`;
|
|
3469
|
+
const value = ctx.getAlias(sv);
|
|
3470
|
+
if (value !== void 0) {
|
|
3471
|
+
if (compileValue === pl) {
|
|
3472
|
+
compileValue = value;
|
|
3473
|
+
} else {
|
|
3474
|
+
compileValue = compileValue.replace(`${pl}`, value);
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
return compileValue;
|
|
3480
|
+
};
|
|
3481
|
+
var resolveValueExpr = (ctx, templateValue) => {
|
|
3482
|
+
const expr = ctx.currentExpr;
|
|
3483
|
+
if (expr === void 0 || expr.tokens.length <= 0) {
|
|
3484
|
+
return templateValue;
|
|
3485
|
+
}
|
|
3486
|
+
const m = ctx.getContextMap();
|
|
3487
|
+
const token = TokenParserManger.getTokenByCtx(m, "${?}" /* VarPatternToken */);
|
|
3488
|
+
const anyToken = TokenParserManger.getTokenByCtx(m, "?" /* AnyToken */);
|
|
3489
|
+
const [start, end] = token.split(anyToken);
|
|
3490
|
+
if (!templateValue.startsWith(start)) {
|
|
3491
|
+
templateValue = `${start}${templateValue}`;
|
|
3492
|
+
}
|
|
3493
|
+
if (!templateValue.endsWith(end)) {
|
|
3494
|
+
templateValue = `${templateValue}${end}`;
|
|
3495
|
+
}
|
|
3496
|
+
return templateValue;
|
|
3497
|
+
};
|
|
3498
|
+
var compileRowCells = function(ctx, expr, cellPoints, rowIndex, errs) {
|
|
3499
|
+
if (ctx.sheet === void 0) {
|
|
3500
|
+
errs.push(new Error(`ctx miss worksheet`));
|
|
3501
|
+
return;
|
|
3502
|
+
}
|
|
3503
|
+
ctx.currentExpr = expr;
|
|
3504
|
+
cellPoints.forEach((cellPoint, index) => {
|
|
3505
|
+
const r = cellPoint.Row;
|
|
3506
|
+
const sheet = ctx.sheet;
|
|
3507
|
+
const c = cellPoint.Column;
|
|
3508
|
+
const cell = sheet.findCell(r, c);
|
|
3509
|
+
if (cell === void 0 || cell.value !== void 0 && cell.value !== null && cell.value !== "") {
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3512
|
+
let templateValue = String(expr.value);
|
|
3513
|
+
const macroTokens2 = getMacroTokens(expr);
|
|
3514
|
+
templateValue = resolveFunctionExpr(ctx, templateValue, expr);
|
|
3515
|
+
templateValue = resolveCompileMacroExpr(ctx, templateValue, macroTokens2, index, cellPoints.length);
|
|
3516
|
+
templateValue = resolveAliasExpr(ctx, templateValue, index);
|
|
3517
|
+
cell.value = resolveValueExpr(ctx, templateValue);
|
|
3518
|
+
});
|
|
3519
|
+
};
|
|
3520
|
+
var generateWorkSheetCellsPlaceholder = function(ctx, expr, sheet) {
|
|
3521
|
+
const errs = [];
|
|
3522
|
+
const posExpr = expr.posExpr;
|
|
3523
|
+
let cellsItems = expr.cells;
|
|
3524
|
+
if ((cellsItems === void 0 || cellsItems.length <= 0) && posExpr !== void 0 && posExpr.value !== void 0) {
|
|
3525
|
+
const r = posExpr.value;
|
|
3526
|
+
if (r !== void 0) {
|
|
3527
|
+
cellsItems = r.getCells();
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
if (!cellsItems || cellsItems.length === 0) {
|
|
3531
|
+
return void 0;
|
|
3532
|
+
}
|
|
3533
|
+
ctx.sheet = sheet;
|
|
3534
|
+
const cells = cellsItems;
|
|
3535
|
+
toRowCells(cells).forEach((cellPoints, index) => compileRowCells(ctx, expr, cellPoints, index, errs));
|
|
3536
|
+
return errs.length > 0 ? errs : void 0;
|
|
3537
|
+
};
|
|
3538
|
+
var hasGeneratorToken = function(tokens) {
|
|
3539
|
+
for (const t of tokens) {
|
|
3540
|
+
if (compileCellTokens.includes(t)) {
|
|
3541
|
+
return true;
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
return false;
|
|
3545
|
+
};
|
|
3546
|
+
var compileWorkSheetPlaceholder = function(ctx, sheet, result) {
|
|
3547
|
+
if (ctx.compileSheets !== void 0 && ctx.compileSheets.length > 0 && !ctx.compileSheets.includes(sheet.name)) {
|
|
3548
|
+
return void 0;
|
|
3549
|
+
}
|
|
3550
|
+
const errs = [];
|
|
3551
|
+
for (const [token, express] of result.rules.entries()) {
|
|
3552
|
+
if (!isRuleToken(token)) {
|
|
3553
|
+
continue;
|
|
3554
|
+
}
|
|
3555
|
+
for (const expr of express) {
|
|
3556
|
+
if (expr.tokens.length <= 0 || !hasGeneratorToken(expr.tokens)) {
|
|
3557
|
+
continue;
|
|
3558
|
+
}
|
|
3559
|
+
let err = generateWorkSheetCellsPlaceholder(ctx, expr, sheet);
|
|
3560
|
+
if (err !== void 0 && err.length > 0) {
|
|
3561
|
+
errs.push(...err);
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
}
|
|
3565
|
+
if (errs.length > 0) {
|
|
3566
|
+
return errs;
|
|
3567
|
+
}
|
|
3568
|
+
return void 0;
|
|
3569
|
+
};
|
|
3570
|
+
var compile = async function(data, ruleSheetName, options) {
|
|
3571
|
+
const workbook = await loadWorkbook(data);
|
|
3572
|
+
const sheet = workbook.getWorksheet(ruleSheetName);
|
|
3573
|
+
if (sheet === void 0) {
|
|
3574
|
+
return {
|
|
3575
|
+
workbook,
|
|
3576
|
+
errs: [new Error(`compile error, ${ruleSheetName} not exists!`)]
|
|
3577
|
+
};
|
|
3578
|
+
}
|
|
3579
|
+
if (workbook.worksheets === void 0) {
|
|
3580
|
+
return {
|
|
3581
|
+
workbook,
|
|
3582
|
+
errs: [new Error(`worksheet, ${ruleSheetName} not exists!`)]
|
|
3583
|
+
};
|
|
3584
|
+
}
|
|
3585
|
+
if (options === void 0) {
|
|
3586
|
+
const excludes = [ruleSheetName];
|
|
3587
|
+
options = RuleMapOptions.withAllSheets(workbook, excludes);
|
|
3588
|
+
}
|
|
3589
|
+
const result = parseWorkSheetRules(sheet, options);
|
|
3590
|
+
const errs = compileCheck(result, options);
|
|
3591
|
+
if (errs !== void 0) {
|
|
3592
|
+
return {
|
|
3593
|
+
errs,
|
|
3594
|
+
workbook,
|
|
3595
|
+
configure: result
|
|
3596
|
+
};
|
|
3597
|
+
}
|
|
3598
|
+
const compileErrs = [];
|
|
3599
|
+
const ctx = CompileContext.create(options).loadAlias(result.rules);
|
|
3600
|
+
for (const [i, w] of workbook.worksheets.entries()) {
|
|
3601
|
+
if (w.name === ruleSheetName || i === ruleSheetName || !ctx.filterSheet(w.name)) {
|
|
3602
|
+
continue;
|
|
3603
|
+
}
|
|
3604
|
+
let err = compileWorkSheetPlaceholder(ctx, w, result);
|
|
3605
|
+
if (err !== void 0 && err.length > 0) {
|
|
3606
|
+
compileErrs.push(...err);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
if (compileErrs.length > 0) {
|
|
3610
|
+
return {
|
|
3611
|
+
workbook,
|
|
3612
|
+
configure: result,
|
|
3613
|
+
errs: compileErrs
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
return {
|
|
3617
|
+
workbook,
|
|
3618
|
+
configure: result
|
|
3619
|
+
};
|
|
3620
|
+
};
|
|
3621
|
+
var compileWorkSheet = async function(data, sheetName, options) {
|
|
3622
|
+
const reply = await compile(data, sheetName, options);
|
|
3623
|
+
if (reply.errs !== void 0 && reply.errs.length > 0) {
|
|
3624
|
+
return reply.errs;
|
|
3625
|
+
}
|
|
3626
|
+
return reply.workbook.xlsx;
|
|
3627
|
+
};
|
|
3628
|
+
var fetchAlias = (m) => {
|
|
3629
|
+
let sv;
|
|
3630
|
+
const alias = /* @__PURE__ */ new Map();
|
|
3631
|
+
if (!(m instanceof Map) && m.rules !== void 0) {
|
|
3632
|
+
sv = m.rules;
|
|
3633
|
+
} else if (m instanceof Map) {
|
|
3634
|
+
if (m.size <= 0 || !m.has("alias" /* AliasToken */)) {
|
|
3635
|
+
return alias;
|
|
3636
|
+
}
|
|
3637
|
+
sv = m;
|
|
3638
|
+
} else {
|
|
3639
|
+
return alias;
|
|
3640
|
+
}
|
|
3641
|
+
const values = sv.get("alias" /* AliasToken */);
|
|
3642
|
+
for (const vs of values) {
|
|
3643
|
+
if (typeof vs.value === "string") {
|
|
3644
|
+
alias.set(vs.key, vs.value);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
return alias;
|
|
3648
|
+
};
|
|
3649
|
+
var removeUnExportSheets = (w, options) => {
|
|
3650
|
+
const removes = [];
|
|
3651
|
+
if (options.compileSheets === void 0 || options.compileSheets.length <= 0) {
|
|
3652
|
+
for (const [i, v] of w.worksheets.entries()) {
|
|
3653
|
+
const sheetName = v.name;
|
|
3654
|
+
if (sheetName.endsWith(".config") || sheetName.endsWith(".json")) {
|
|
3655
|
+
removes.push(sheetName);
|
|
3656
|
+
}
|
|
3657
|
+
}
|
|
3658
|
+
} else {
|
|
3659
|
+
for (const [i, v] of w.worksheets.entries()) {
|
|
3660
|
+
if (!options.compileSheets.includes(v.name)) {
|
|
3661
|
+
removes.push(v.name);
|
|
3662
|
+
}
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
for (const [_, name] of removes.entries()) {
|
|
3666
|
+
w.removeWorksheet(name);
|
|
3667
|
+
}
|
|
3668
|
+
return w;
|
|
3669
|
+
};
|
|
3670
|
+
var toBuffer = async (w) => {
|
|
3671
|
+
const arrayBuffer = await w.xlsx.writeBuffer();
|
|
3672
|
+
return Buffer.from(arrayBuffer);
|
|
3673
|
+
};
|
|
3674
|
+
var ExprResolver = class {
|
|
3675
|
+
};
|
|
3676
|
+
ExprResolver.toBuffer = toBuffer;
|
|
3677
|
+
ExprResolver.compile = compile;
|
|
3678
|
+
ExprResolver.toRowCells = toRowCells;
|
|
3679
|
+
ExprResolver.fetchAlias = fetchAlias;
|
|
3680
|
+
ExprResolver.getExprEnd = getExprEnd;
|
|
3681
|
+
ExprResolver.compileCheck = compileCheck;
|
|
3682
|
+
ExprResolver.extractMacro = extractMacro;
|
|
3683
|
+
ExprResolver.compileRowCells = compileRowCells;
|
|
3684
|
+
ExprResolver.searchIndexOf = searchIndexOf;
|
|
3685
|
+
ExprResolver.resolveAliasExpr = resolveAliasExpr;
|
|
3686
|
+
ExprResolver.resolveValueExpr = resolveValueExpr;
|
|
3687
|
+
ExprResolver.resolveFunctionExpr = resolveFunctionExpr;
|
|
3688
|
+
ExprResolver.removeUnExportSheets = removeUnExportSheets;
|
|
3689
|
+
ExprResolver.resolveCompileMacroGen = resolveCompileMacroGen;
|
|
3690
|
+
ExprResolver.resolveCompileMacroExpr = resolveCompileMacroExpr;
|
|
3691
|
+
|
|
3692
|
+
// src/extends.ts
|
|
3693
|
+
function hasToString(obj) {
|
|
3694
|
+
return obj != null && typeof obj.toString === "function";
|
|
3695
|
+
}
|
|
3696
|
+
var tokenNextIter = [`root`, `groups`, `suffix`, `default`];
|
|
3697
|
+
var aliasKey = `__alias`;
|
|
3698
|
+
var ArgumentData = class {
|
|
3699
|
+
constructor(fn, p) {
|
|
3700
|
+
this.default = "";
|
|
3701
|
+
this.groups = [];
|
|
3702
|
+
this.tokenIterIndex = 0;
|
|
3703
|
+
this.p = p;
|
|
3704
|
+
this.func = fn;
|
|
3705
|
+
this.groups = [];
|
|
3706
|
+
}
|
|
3707
|
+
To() {
|
|
3708
|
+
return {
|
|
3709
|
+
p: this.p,
|
|
3710
|
+
root: this.root,
|
|
3711
|
+
alias: this.alias,
|
|
3712
|
+
groups: this.groups,
|
|
3713
|
+
suffix: this.suffix,
|
|
3714
|
+
default: this.default,
|
|
3715
|
+
func: this.func
|
|
3716
|
+
};
|
|
3717
|
+
}
|
|
3718
|
+
Add(startToken, value) {
|
|
3719
|
+
if (value === void 0) {
|
|
3720
|
+
this.tokenIterIndex++;
|
|
3721
|
+
return;
|
|
3722
|
+
}
|
|
3723
|
+
switch (startToken) {
|
|
3724
|
+
case `(`:
|
|
3725
|
+
if (tokenNextIter[this.tokenIterIndex] === "root") {
|
|
3726
|
+
this.root = value;
|
|
3727
|
+
this.tokenIterIndex++;
|
|
3728
|
+
}
|
|
3729
|
+
break;
|
|
3730
|
+
case `[`:
|
|
3731
|
+
if (tokenNextIter[this.tokenIterIndex] === "groups") {
|
|
3732
|
+
this.groups.push(value);
|
|
3733
|
+
}
|
|
3734
|
+
break;
|
|
3735
|
+
case `]`:
|
|
3736
|
+
if (tokenNextIter[this.tokenIterIndex] === "groups") {
|
|
3737
|
+
this.groups.push(value);
|
|
3738
|
+
}
|
|
3739
|
+
break;
|
|
3740
|
+
case `,`:
|
|
3741
|
+
const token = tokenNextIter[this.tokenIterIndex];
|
|
3742
|
+
if (token === "root") {
|
|
3743
|
+
this.root = value;
|
|
3744
|
+
this.tokenIterIndex++;
|
|
3745
|
+
} else if (token === "groups") {
|
|
3746
|
+
this.groups.push(value);
|
|
3747
|
+
} else if (token === "suffix") {
|
|
3748
|
+
this.suffix = value;
|
|
3749
|
+
this.tokenIterIndex++;
|
|
3750
|
+
} else if (token === "default") {
|
|
3751
|
+
this.default = value;
|
|
3752
|
+
this.tokenIterIndex++;
|
|
3753
|
+
}
|
|
3754
|
+
break;
|
|
3755
|
+
case `)`:
|
|
3756
|
+
this.tokenIterIndex++;
|
|
3757
|
+
break;
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
ParseAlias(alias) {
|
|
3761
|
+
if (alias === void 0 || this.root === void 0 || this.root === "") {
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
const value = valueDotGet(alias, this.root);
|
|
3765
|
+
if (value === void 0 || typeof value !== "string" || !hasToString(value)) {
|
|
3766
|
+
return;
|
|
3767
|
+
}
|
|
3768
|
+
this.alias = this.root;
|
|
3769
|
+
this.root = value;
|
|
3770
|
+
}
|
|
3771
|
+
};
|
|
3772
|
+
var ArgumentValue = class {
|
|
3773
|
+
constructor(value, defValue) {
|
|
3774
|
+
this.value = value;
|
|
3775
|
+
this.defaultValue = defValue;
|
|
3776
|
+
}
|
|
3777
|
+
isUndefined() {
|
|
3778
|
+
return this.value === void 0;
|
|
3779
|
+
}
|
|
3780
|
+
getDefault() {
|
|
3781
|
+
return this.defaultValue;
|
|
3782
|
+
}
|
|
3783
|
+
getNumber() {
|
|
3784
|
+
return Number(this.value);
|
|
3785
|
+
}
|
|
3786
|
+
toString() {
|
|
3787
|
+
if (this.isUndefined()) {
|
|
3788
|
+
return "";
|
|
3789
|
+
}
|
|
3790
|
+
if (typeof this.value === "string") {
|
|
3791
|
+
return this.value;
|
|
3792
|
+
}
|
|
3793
|
+
if (hasToString(this.value)) {
|
|
3794
|
+
return this.value.toString();
|
|
3795
|
+
}
|
|
3796
|
+
return "";
|
|
3797
|
+
}
|
|
3798
|
+
};
|
|
3799
|
+
var ArgumentValueLoader = (values, args) => {
|
|
3800
|
+
let all = [];
|
|
3801
|
+
for (let v of args.groups) {
|
|
3802
|
+
let key = `${args.root}.${v}`;
|
|
3803
|
+
if (args.suffix !== void 0 && args.suffix !== "") {
|
|
3804
|
+
key = `${key}.${args.suffix}`;
|
|
3805
|
+
}
|
|
3806
|
+
all.push(key);
|
|
3807
|
+
}
|
|
3808
|
+
if (all.length <= 0) {
|
|
3809
|
+
return args.default || "";
|
|
3810
|
+
}
|
|
3811
|
+
const items = [];
|
|
3812
|
+
for (let k of all) {
|
|
3813
|
+
let vs = valueDotGet(values, k);
|
|
3814
|
+
items.push(new ArgumentValue(vs, args.default));
|
|
3815
|
+
}
|
|
3816
|
+
return items;
|
|
3817
|
+
};
|
|
3818
|
+
var sum_all = (values, argument) => {
|
|
3819
|
+
let sum = NaN;
|
|
3820
|
+
let emptyTimes = 0;
|
|
3821
|
+
let argc = argument.groups.length;
|
|
3822
|
+
let items = ArgumentValueLoader(values, argument);
|
|
3823
|
+
for (let value of items) {
|
|
3824
|
+
let num = value.getNumber();
|
|
3825
|
+
if (value.isUndefined()) {
|
|
3826
|
+
emptyTimes++;
|
|
3827
|
+
num = Number(argument.default);
|
|
3828
|
+
}
|
|
3829
|
+
if (isNaN(sum)) {
|
|
3830
|
+
sum = num;
|
|
3831
|
+
} else {
|
|
3832
|
+
sum = sum + Number(num);
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
if (emptyTimes === argc) {
|
|
3836
|
+
return void 0;
|
|
3837
|
+
}
|
|
3838
|
+
if (isNaN(sum)) {
|
|
3839
|
+
throw new Error(`parse ${argument.p.name} NaN error`);
|
|
3840
|
+
}
|
|
3841
|
+
return sum;
|
|
3842
|
+
};
|
|
3843
|
+
var sub_value = (values, argument) => {
|
|
3844
|
+
let sub = NaN;
|
|
3845
|
+
let emptyTimes = 0;
|
|
3846
|
+
let argc = argument.groups.length;
|
|
3847
|
+
let items = ArgumentValueLoader(values, argument);
|
|
3848
|
+
for (let value of items) {
|
|
3849
|
+
let num = value.getNumber();
|
|
3850
|
+
if (value.isUndefined()) {
|
|
3851
|
+
emptyTimes++;
|
|
3852
|
+
num = Number(argument.default);
|
|
3853
|
+
}
|
|
3854
|
+
if (isNaN(num)) {
|
|
3855
|
+
continue;
|
|
3856
|
+
}
|
|
3857
|
+
if (isNaN(sub)) {
|
|
3858
|
+
sub = num;
|
|
3859
|
+
} else {
|
|
3860
|
+
sub = sub - Number(num);
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
if (emptyTimes === argc) {
|
|
3864
|
+
return void 0;
|
|
3865
|
+
}
|
|
3866
|
+
if (isNaN(sub)) {
|
|
3867
|
+
throw new Error(`parse ${argument.p.name} NaN error`);
|
|
3868
|
+
}
|
|
3869
|
+
return sub;
|
|
3870
|
+
};
|
|
3871
|
+
var defaultCommands = /* @__PURE__ */ new Map([
|
|
3872
|
+
["sum", sum_all],
|
|
3873
|
+
["sub", sub_value]
|
|
3874
|
+
]);
|
|
3875
|
+
var resolveFunc = function(value) {
|
|
3876
|
+
if (value.indexOf("(") > 0 && value.endsWith(")")) {
|
|
3877
|
+
const names = value.split("(");
|
|
3878
|
+
return names[0];
|
|
3879
|
+
}
|
|
3880
|
+
return "";
|
|
3881
|
+
};
|
|
3882
|
+
var resolveArgument = function(p, data) {
|
|
3883
|
+
const value = p.name;
|
|
3884
|
+
const fn = resolveFunc(value);
|
|
3885
|
+
const args = new ArgumentData(fn, p);
|
|
3886
|
+
if (fn !== "") {
|
|
3887
|
+
let key = "";
|
|
3888
|
+
let startT = "";
|
|
3889
|
+
const endToken = [`)`, `,`, `]`];
|
|
3890
|
+
const startToken = [`(`, `,`, `[`];
|
|
3891
|
+
const tokenRow = value.split(`${fn}`)[1];
|
|
3892
|
+
const len = tokenRow.length;
|
|
3893
|
+
for (let i = 0; i < len; i++) {
|
|
3894
|
+
let start = startToken.includes(tokenRow[i]);
|
|
3895
|
+
let end = endToken.includes(tokenRow[i]);
|
|
3896
|
+
if (start) {
|
|
3897
|
+
startT = tokenRow[i];
|
|
3898
|
+
}
|
|
3899
|
+
if (startT !== "" && tokenRow[i] !== startT && !end) {
|
|
3900
|
+
key = `${key}${tokenRow[i]}`;
|
|
3901
|
+
}
|
|
3902
|
+
if (end) {
|
|
3903
|
+
if (key === "") {
|
|
3904
|
+
args.Add(startT, void 0);
|
|
3905
|
+
} else {
|
|
3906
|
+
args.Add(startT, key);
|
|
3907
|
+
key = "";
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
const alias = valueDotGet(data, aliasKey);
|
|
3913
|
+
if (alias !== void 0) {
|
|
3914
|
+
args.ParseAlias(alias);
|
|
3915
|
+
}
|
|
3916
|
+
return args.To();
|
|
3917
|
+
};
|
|
3918
|
+
var commandExtendQuery = function(values, p) {
|
|
3919
|
+
if (p.type !== "fn") {
|
|
3920
|
+
return defaultValueDotGet(values, p);
|
|
3921
|
+
}
|
|
3922
|
+
const argument = resolveArgument(p, values);
|
|
3923
|
+
if (argument.func !== "" && defaultCommands.has(argument.func)) {
|
|
3924
|
+
return defaultCommands.get(argument.func)(values, argument);
|
|
3925
|
+
}
|
|
3926
|
+
return defaultValueDotGet(values, p);
|
|
3927
|
+
};
|
|
3928
|
+
var AddCommand = (key, h) => {
|
|
3929
|
+
if (defaultCommands.has(key)) {
|
|
3930
|
+
return false;
|
|
3931
|
+
}
|
|
3932
|
+
defaultCommands.set(key, h);
|
|
3933
|
+
return true;
|
|
3934
|
+
};
|
|
3935
|
+
var AddCommandMust = (key, h) => {
|
|
3936
|
+
defaultCommands.set(key, h);
|
|
3937
|
+
};
|
|
3938
|
+
var generateCommandsXlsxTemplate = async function(data, values, options) {
|
|
3939
|
+
const w = await Workbook.parse(data, options);
|
|
3940
|
+
w.setQueryFunctionHandler(commandExtendQuery);
|
|
3941
|
+
await w.substituteAll(values);
|
|
3942
|
+
return w.generate(options);
|
|
3943
|
+
};
|
|
3944
|
+
var getCommands = () => {
|
|
3945
|
+
return defaultCommands;
|
|
3946
|
+
};
|
|
3947
|
+
var compileRuleSheetName = "export_metadata.config";
|
|
3948
|
+
var mergeMap = function(source, dest) {
|
|
3949
|
+
for (const [key, value] of dest.entries()) {
|
|
3950
|
+
source.set(key, value);
|
|
3951
|
+
}
|
|
3952
|
+
return source;
|
|
3953
|
+
};
|
|
3954
|
+
var generateCommandsXlsxTemplateWithCompile = async function(data, values, compileOptions, options) {
|
|
3955
|
+
if (compileOptions.sheetName === void 0 || compileOptions.sheetName === "") {
|
|
3956
|
+
compileOptions.sheetName = compileRuleSheetName;
|
|
3957
|
+
}
|
|
3958
|
+
const result = await ExprResolver.compile(data, compileOptions.sheetName, compileOptions);
|
|
3959
|
+
if (result.errs !== void 0 && result.errs.length > 0) {
|
|
3960
|
+
throw result.errs[0];
|
|
3961
|
+
}
|
|
3962
|
+
let alias = ExprResolver.fetchAlias(result.configure);
|
|
3963
|
+
if (values[aliasKey] !== void 0 && values[aliasKey] instanceof Map) {
|
|
3964
|
+
alias = mergeMap(alias, values[aliasKey]);
|
|
3965
|
+
}
|
|
3966
|
+
values[aliasKey] = alias;
|
|
3967
|
+
result.workbook = ExprResolver.removeUnExportSheets(result.workbook, compileOptions);
|
|
3968
|
+
const wb = await ExprResolver.toBuffer(result.workbook);
|
|
3969
|
+
const w = await Workbook.parse(wb, options);
|
|
3970
|
+
w.setQueryFunctionHandler(commandExtendQuery);
|
|
3971
|
+
await w.substituteAll(values);
|
|
3972
|
+
return w.generate(options);
|
|
3973
|
+
};
|
|
3974
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3975
|
+
0 && (module.exports = {
|
|
3976
|
+
AddCommand,
|
|
3977
|
+
AddCommandMust,
|
|
3978
|
+
ArgumentData,
|
|
3979
|
+
ArgumentValue,
|
|
3980
|
+
ArgumentValueLoader,
|
|
3981
|
+
BufferType,
|
|
3982
|
+
CompileContext,
|
|
3983
|
+
DefaultPlaceholderCellValue,
|
|
3984
|
+
ExprResolver,
|
|
3985
|
+
RuleMapOptions,
|
|
3986
|
+
RuleToken,
|
|
3987
|
+
TokenParserManger,
|
|
3988
|
+
Workbook,
|
|
3989
|
+
columnLetterToNumber,
|
|
3990
|
+
columnNumberToLetter,
|
|
3991
|
+
commandExtendQuery,
|
|
3992
|
+
compileRuleSheetName,
|
|
3993
|
+
compileWorkSheet,
|
|
3994
|
+
compileWorkSheetPlaceholder,
|
|
3995
|
+
defaultExtractPlaceholders,
|
|
3996
|
+
defaultFormatters,
|
|
3997
|
+
defaultValueDotGet,
|
|
3998
|
+
exceljs,
|
|
3999
|
+
generateCommandsXlsxTemplate,
|
|
4000
|
+
generateCommandsXlsxTemplateWithCompile,
|
|
4001
|
+
generateXlsxTemplate,
|
|
4002
|
+
getCommands,
|
|
4003
|
+
getTokenParser,
|
|
4004
|
+
hasGeneratorToken,
|
|
4005
|
+
isRuleToken,
|
|
4006
|
+
isUrl,
|
|
4007
|
+
loadWorkbook,
|
|
4008
|
+
parseWorkSheetRules,
|
|
4009
|
+
registerTokenParser,
|
|
4010
|
+
registerTokenParserMust,
|
|
4011
|
+
resolveArgument,
|
|
4012
|
+
scanCellSetPlaceholder,
|
|
4013
|
+
toArrayBuffer,
|
|
4014
|
+
valueDotGet,
|
|
4015
|
+
workSheetSetPlaceholder
|
|
4016
|
+
});
|
|
4017
|
+
//# sourceMappingURL=index.js.map
|