@a3s-lab/office 0.13.0 → 0.13.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.
Files changed (25) hide show
  1. package/README.md +13 -1
  2. package/dist/0~6090.js +63 -4
  3. package/dist/0~spreadsheet-editor.js +2940 -2164
  4. package/dist/4104.js +1094 -18
  5. package/dist/internal/features/work/editors/office-menu-keyboard.d.ts +1 -0
  6. package/dist/internal/features/work/editors/spreadsheet-cell-border-per-cell.d.ts +5 -0
  7. package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +15 -1
  8. package/dist/internal/features/work/editors/spreadsheet-cell-style-command.d.ts +3 -0
  9. package/dist/internal/features/work/editors/spreadsheet-cell-style-ribbon.d.ts +9 -0
  10. package/dist/internal/features/work/editors/spreadsheet-cell-style.d.ts +41 -0
  11. package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +134 -0
  12. package/dist/internal/features/work/editors/spreadsheet-command-controller.d.ts +2 -0
  13. package/dist/internal/features/work/editors/spreadsheet-editor-ribbon.d.ts +3 -1
  14. package/dist/internal/features/work/editors/spreadsheet-number-format.d.ts +15 -3
  15. package/dist/internal/features/work/work-xlsx-cell-borders.d.ts +25 -0
  16. package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +21 -0
  17. package/dist/internal/features/work/work-xlsx-cell-style-xml.d.ts +17 -0
  18. package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +13 -0
  19. package/dist/internal/features/work/work-xlsx-colors.d.ts +6 -0
  20. package/dist/internal/features/work/work-xlsx-interop.d.ts +3 -1
  21. package/dist/internal/features/work/work-xlsx-worksheet-scan.d.ts +1 -0
  22. package/dist/office-kernel.wasm +0 -0
  23. package/dist/styles.css +117 -0
  24. package/dist/work-spreadsheet-package-scan.worker.js +7 -3
  25. package/package.json +5 -3
package/dist/4104.js CHANGED
@@ -3061,6 +3061,1006 @@ function work_xlsx_images_partNumber(path) {
3061
3061
  function work_xlsx_images_escapeXml(value) {
3062
3062
  return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;');
3063
3063
  }
3064
+ const xlsxStyleByFortuneStyle = {
3065
+ 1: 'thin',
3066
+ 2: 'hair',
3067
+ 3: 'dotted',
3068
+ 4: 'dashed',
3069
+ 5: 'dashDot',
3070
+ 6: 'dashDotDot',
3071
+ 7: 'double',
3072
+ 8: 'medium',
3073
+ 9: 'mediumDashed',
3074
+ 10: 'mediumDashDot',
3075
+ 11: 'mediumDashDotDot',
3076
+ 12: 'slantDashDot',
3077
+ 13: 'thick'
3078
+ };
3079
+ const fortuneStyleByXlsxStyle = new Map(Object.entries(xlsxStyleByFortuneStyle).map(([fortune, xlsx])=>[
3080
+ xlsx,
3081
+ fortune
3082
+ ]));
3083
+ function collectXlsxCellBorders(sheet) {
3084
+ const targets = spreadsheetBorderTargets(sheet);
3085
+ const borders = new Map();
3086
+ const source = Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : [];
3087
+ for (const candidate of source){
3088
+ if (!work_xlsx_cell_borders_isRecord(candidate)) continue;
3089
+ if ('cell' === candidate.rangeType) {
3090
+ applySpreadsheetCellBorderRecord(candidate, targets, borders);
3091
+ continue;
3092
+ }
3093
+ if ('range' !== candidate.rangeType || 'string' != typeof candidate.borderType || !Array.isArray(candidate.range)) continue;
3094
+ const line = spreadsheetBorderLine(candidate);
3095
+ for (const rangeCandidate of candidate.range){
3096
+ const range = spreadsheetBorderRange(rangeCandidate);
3097
+ if (range) {
3098
+ for (const target of targets.values())if (spreadsheetBorderRangeContains(range, target)) applySpreadsheetRangeBorder(borders, target, range, candidate.borderType, line);
3099
+ }
3100
+ }
3101
+ }
3102
+ return borders;
3103
+ }
3104
+ function fortuneBorderInfoFromXlsxCells(entries) {
3105
+ return entries.flatMap(({ border, column, row })=>{
3106
+ if (!border) return [];
3107
+ const value = {
3108
+ col_index: column,
3109
+ row_index: row
3110
+ };
3111
+ setFortuneBorderLine(value, 'l', border.left);
3112
+ setFortuneBorderLine(value, 'r', border.right);
3113
+ setFortuneBorderLine(value, 't', border.top);
3114
+ setFortuneBorderLine(value, 'b', border.bottom);
3115
+ if (border.diagonal) setFortuneBorderLine(value, 's', border.diagonal);
3116
+ return Object.keys(value).length > 2 ? [
3117
+ {
3118
+ rangeType: 'cell',
3119
+ value
3120
+ }
3121
+ ] : [];
3122
+ });
3123
+ }
3124
+ function xlsxCellBorderKey(row, column) {
3125
+ return `${row}_${column}`;
3126
+ }
3127
+ function xlsxCellBorderLineFromFortune(value) {
3128
+ if (null === value) return null;
3129
+ if (!work_xlsx_cell_borders_isRecord(value)) return;
3130
+ const style = xlsxStyleByFortuneStyle[String(value.style ?? '')];
3131
+ const color = normalizeRgbColor(value.color);
3132
+ return style && color ? {
3133
+ color,
3134
+ style
3135
+ } : void 0;
3136
+ }
3137
+ function fortuneBorderStyle(style) {
3138
+ return fortuneStyleByXlsxStyle.get(style) ?? '1';
3139
+ }
3140
+ function spreadsheetBorderTargets(sheet) {
3141
+ const targets = new Map();
3142
+ for (const [row, values] of sparseArrayEntries(sheet.data))for (const [column, cell] of sparseArrayEntries(values))if (cell) targets.set(xlsxCellBorderKey(row, column), {
3143
+ column,
3144
+ row
3145
+ });
3146
+ for (const candidate of Array.isArray(sheet.config?.borderInfo) ? sheet.config.borderInfo : []){
3147
+ if (!work_xlsx_cell_borders_isRecord(candidate) || 'cell' !== candidate.rangeType) continue;
3148
+ const value = candidate.value;
3149
+ if (!work_xlsx_cell_borders_isRecord(value)) continue;
3150
+ const row = nonNegativeInteger(value.row_index);
3151
+ const column = nonNegativeInteger(value.col_index);
3152
+ if (null !== row && null !== column) targets.set(xlsxCellBorderKey(row, column), {
3153
+ column,
3154
+ row
3155
+ });
3156
+ }
3157
+ return targets;
3158
+ }
3159
+ function applySpreadsheetCellBorderRecord(record, targets, borders) {
3160
+ if (!work_xlsx_cell_borders_isRecord(record.value)) return;
3161
+ const row = nonNegativeInteger(record.value.row_index);
3162
+ const column = nonNegativeInteger(record.value.col_index);
3163
+ if (null === row || null === column) return;
3164
+ const key = xlsxCellBorderKey(row, column);
3165
+ if (!targets.has(key)) return;
3166
+ const border = {
3167
+ ...borders.get(key) ?? {}
3168
+ };
3169
+ applyCellLine(border, 'left', record.value.l);
3170
+ applyCellLine(border, 'right', record.value.r);
3171
+ applyCellLine(border, 'top', record.value.t);
3172
+ applyCellLine(border, 'bottom', record.value.b);
3173
+ const diagonal = xlsxCellBorderLineFromFortune(record.value.s);
3174
+ if (void 0 !== diagonal) {
3175
+ border.diagonal = diagonal;
3176
+ border.diagonalUp = null !== diagonal;
3177
+ border.diagonalDown = false;
3178
+ }
3179
+ borders.set(key, border);
3180
+ }
3181
+ function applyCellLine(border, side, value) {
3182
+ const line = xlsxCellBorderLineFromFortune(value);
3183
+ if (void 0 !== line) border[side] = line;
3184
+ }
3185
+ function applySpreadsheetRangeBorder(borders, target, range, borderType, line) {
3186
+ const key = xlsxCellBorderKey(target.row, target.column);
3187
+ const border = {
3188
+ ...borders.get(key) ?? {}
3189
+ };
3190
+ const onTop = target.row === range.row[0];
3191
+ const onBottom = target.row === range.row[1];
3192
+ const onLeft = target.column === range.column[0];
3193
+ const onRight = target.column === range.column[1];
3194
+ switch(borderType){
3195
+ case 'border-top':
3196
+ if (onTop) border.top = line;
3197
+ break;
3198
+ case 'border-bottom':
3199
+ if (onBottom) border.bottom = line;
3200
+ break;
3201
+ case 'border-left':
3202
+ if (onLeft) border.left = line;
3203
+ break;
3204
+ case 'border-right':
3205
+ if (onRight) border.right = line;
3206
+ break;
3207
+ case 'border-none':
3208
+ border.top = null;
3209
+ border.bottom = null;
3210
+ border.left = null;
3211
+ border.right = null;
3212
+ border.diagonal = null;
3213
+ border.diagonalUp = false;
3214
+ border.diagonalDown = false;
3215
+ break;
3216
+ case 'border-all':
3217
+ border.top = line;
3218
+ border.bottom = line;
3219
+ border.left = line;
3220
+ border.right = line;
3221
+ break;
3222
+ case 'border-outside':
3223
+ if (onTop) border.top = line;
3224
+ if (onBottom) border.bottom = line;
3225
+ if (onLeft) border.left = line;
3226
+ if (onRight) border.right = line;
3227
+ break;
3228
+ case 'border-inside':
3229
+ if (!onTop) border.top = line;
3230
+ if (!onBottom) border.bottom = line;
3231
+ if (!onLeft) border.left = line;
3232
+ if (!onRight) border.right = line;
3233
+ break;
3234
+ case 'border-horizontal':
3235
+ if (!onTop) border.top = line;
3236
+ if (!onBottom) border.bottom = line;
3237
+ break;
3238
+ case 'border-vertical':
3239
+ if (!onLeft) border.left = line;
3240
+ if (!onRight) border.right = line;
3241
+ break;
3242
+ case 'border-slash':
3243
+ border.diagonal = line;
3244
+ border.diagonalUp = null !== line;
3245
+ border.diagonalDown = false;
3246
+ break;
3247
+ default:
3248
+ return;
3249
+ }
3250
+ borders.set(key, border);
3251
+ }
3252
+ function spreadsheetBorderLine(record) {
3253
+ const style = xlsxStyleByFortuneStyle[String(record.style ?? '')];
3254
+ const color = normalizeRgbColor(record.color);
3255
+ return style && color ? {
3256
+ color,
3257
+ style
3258
+ } : null;
3259
+ }
3260
+ function spreadsheetBorderRange(value) {
3261
+ if (!work_xlsx_cell_borders_isRecord(value)) return null;
3262
+ const row = spreadsheetBorderAxis(value.row);
3263
+ const column = spreadsheetBorderAxis(value.column);
3264
+ return row && column ? {
3265
+ column,
3266
+ row
3267
+ } : null;
3268
+ }
3269
+ function spreadsheetBorderAxis(value) {
3270
+ if (!Array.isArray(value) || 2 !== value.length) return null;
3271
+ const start = nonNegativeInteger(value[0]);
3272
+ const end = nonNegativeInteger(value[1]);
3273
+ return null !== start && null !== end && start <= end ? [
3274
+ start,
3275
+ end
3276
+ ] : null;
3277
+ }
3278
+ function spreadsheetBorderRangeContains(range, target) {
3279
+ return target.row >= range.row[0] && target.row <= range.row[1] && target.column >= range.column[0] && target.column <= range.column[1];
3280
+ }
3281
+ function setFortuneBorderLine(target, name, line) {
3282
+ if (!line) return;
3283
+ target[name] = {
3284
+ color: normalizeRgbColor(line.color) ?? '#000000',
3285
+ style: fortuneBorderStyle(line.style)
3286
+ };
3287
+ }
3288
+ function normalizeRgbColor(value) {
3289
+ if ('string' != typeof value) return null;
3290
+ const color = value.trim().toLowerCase();
3291
+ if (/^#[0-9a-f]{6}$/.test(color)) return color;
3292
+ if (!/^#[0-9a-f]{3}$/.test(color)) return null;
3293
+ return `#${[
3294
+ ...color.slice(1)
3295
+ ].map((character)=>character.repeat(2)).join('')}`;
3296
+ }
3297
+ function nonNegativeInteger(value) {
3298
+ return 'number' == typeof value && Number.isSafeInteger(value) && value >= 0 ? value : null;
3299
+ }
3300
+ function work_xlsx_cell_borders_isRecord(value) {
3301
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
3302
+ }
3303
+ const borderChildOrder = [
3304
+ 'start',
3305
+ 'end',
3306
+ 'left',
3307
+ 'right',
3308
+ 'top',
3309
+ 'bottom',
3310
+ 'diagonal',
3311
+ 'vertical',
3312
+ 'horizontal',
3313
+ 'extLst'
3314
+ ];
3315
+ function ensureXlsxStyleCollection(document1, name, anchors) {
3316
+ const root = document1.documentElement;
3317
+ const existing = directChild(root, name);
3318
+ if (existing) return existing;
3319
+ const collection = document1.createElementNS(root.namespaceURI, name);
3320
+ root.insertBefore(collection, directChildren(root).find((child)=>anchors.includes(child.localName)) ?? null);
3321
+ return collection;
3322
+ }
3323
+ function defaultXlsxFill(document1, patternType) {
3324
+ const fill = document1.createElementNS(document1.documentElement.namespaceURI, 'fill');
3325
+ const pattern = document1.createElementNS(document1.documentElement.namespaceURI, 'patternFill');
3326
+ pattern.setAttribute('patternType', patternType);
3327
+ fill.append(pattern);
3328
+ return fill;
3329
+ }
3330
+ function defaultXlsxBorder(document1) {
3331
+ const border = document1.createElementNS(document1.documentElement.namespaceURI, 'border');
3332
+ for (const name of [
3333
+ 'left',
3334
+ 'right',
3335
+ 'top',
3336
+ 'bottom',
3337
+ 'diagonal'
3338
+ ])border.append(document1.createElementNS(document1.documentElement.namespaceURI, name));
3339
+ return border;
3340
+ }
3341
+ function setXlsxBorderLine(document1, border, name, line) {
3342
+ removeXlsxChildren(border, name);
3343
+ const element = document1.createElementNS(document1.documentElement.namespaceURI, name);
3344
+ if (line) {
3345
+ element.setAttribute('style', line.style);
3346
+ const color = xlsxRgbColor(line.color);
3347
+ if (color) {
3348
+ const child = document1.createElementNS(document1.documentElement.namespaceURI, 'color');
3349
+ child.setAttribute('rgb', color);
3350
+ element.append(child);
3351
+ }
3352
+ }
3353
+ insertXlsxOrderedChild(border, element, borderChildOrder);
3354
+ }
3355
+ function writeXlsxAlignment(document1, xf, style) {
3356
+ let alignment = directChild(xf, 'alignment');
3357
+ if (!alignment) {
3358
+ alignment = document1.createElementNS(document1.documentElement.namespaceURI, 'alignment');
3359
+ xf.insertBefore(alignment, directChildren(xf).find((child)=>[
3360
+ 'protection',
3361
+ 'extLst'
3362
+ ].includes(child.localName)) ?? null);
3363
+ }
3364
+ if (void 0 !== style.horizontal) alignment.setAttribute('horizontal', style.horizontal);
3365
+ if (void 0 !== style.vertical) alignment.setAttribute('vertical', style.vertical);
3366
+ if (void 0 !== style.wrapText) alignment.setAttribute('wrapText', style.wrapText ? '1' : '0');
3367
+ if (void 0 !== style.textRotation) alignment.setAttribute('textRotation', String(style.textRotation));
3368
+ }
3369
+ function setXlsxValueChild(document1, parent, name, value, order) {
3370
+ removeXlsxChildren(parent, name);
3371
+ const child = document1.createElementNS(document1.documentElement.namespaceURI, name);
3372
+ child.setAttribute('val', value);
3373
+ insertXlsxOrderedChild(parent, child, order);
3374
+ }
3375
+ function setXlsxColorChild(document1, parent, color, order) {
3376
+ removeXlsxChildren(parent, 'color');
3377
+ const child = document1.createElementNS(document1.documentElement.namespaceURI, 'color');
3378
+ child.setAttribute('rgb', color);
3379
+ insertXlsxOrderedChild(parent, child, order);
3380
+ }
3381
+ function setXlsxToggleChild(document1, parent, name, enabled, order) {
3382
+ removeXlsxChildren(parent, name);
3383
+ if (!enabled) return;
3384
+ const child = document1.createElementNS(document1.documentElement.namespaceURI, name);
3385
+ child.setAttribute('val', '1');
3386
+ insertXlsxOrderedChild(parent, child, order);
3387
+ }
3388
+ function setXlsxUnderlineChild(document1, parent, enabled, order) {
3389
+ removeXlsxChildren(parent, 'u');
3390
+ if (!enabled) return;
3391
+ const child = document1.createElementNS(document1.documentElement.namespaceURI, 'u');
3392
+ child.setAttribute('val', 'single');
3393
+ insertXlsxOrderedChild(parent, child, order);
3394
+ }
3395
+ function xlsxRgbColor(value) {
3396
+ if ('string' != typeof value) return null;
3397
+ const color = value.trim().replace('#', '').toUpperCase();
3398
+ if (/^[0-9A-F]{6}$/.test(color)) return `FF${color}`;
3399
+ if (/^[0-9A-F]{8}$/.test(color)) return color;
3400
+ if (/^[0-9A-F]{3}$/.test(color)) return `FF${[
3401
+ ...color
3402
+ ].map((character)=>character.repeat(2)).join('')}`;
3403
+ return null;
3404
+ }
3405
+ function removeXlsxChildren(parent, name) {
3406
+ for (const child of directChildren(parent, name))child.remove();
3407
+ }
3408
+ function insertXlsxOrderedChild(parent, child, order) {
3409
+ const requested = order.indexOf(child.localName);
3410
+ const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
3411
+ parent.insertBefore(child, anchor ?? null);
3412
+ }
3413
+ const fontChildOrder = [
3414
+ 'name',
3415
+ 'charset',
3416
+ 'family',
3417
+ 'b',
3418
+ 'i',
3419
+ 'strike',
3420
+ 'outline',
3421
+ 'shadow',
3422
+ 'condense',
3423
+ 'extend',
3424
+ 'color',
3425
+ 'sz',
3426
+ 'u',
3427
+ 'vertAlign',
3428
+ 'scheme'
3429
+ ];
3430
+ class XlsxDirectCellStyleWriter {
3431
+ styles;
3432
+ fonts;
3433
+ fills;
3434
+ borders;
3435
+ cellXfs;
3436
+ generatedFonts = new Map();
3437
+ generatedFills = new Map();
3438
+ generatedBorders = new Map();
3439
+ generatedStyles = new Map();
3440
+ changed = false;
3441
+ constructor(styles){
3442
+ this.styles = styles;
3443
+ const root = styles.documentElement;
3444
+ this.fonts = ensureXlsxStyleCollection(styles, 'fonts', [
3445
+ 'fills',
3446
+ 'borders',
3447
+ 'cellStyleXfs',
3448
+ 'cellXfs',
3449
+ 'cellStyles',
3450
+ 'dxfs',
3451
+ 'tableStyles',
3452
+ 'colors',
3453
+ 'extLst'
3454
+ ]);
3455
+ if (!directChildren(this.fonts, 'font').length) {
3456
+ this.fonts.append(styles.createElementNS(root.namespaceURI, 'font'));
3457
+ this.changed = true;
3458
+ }
3459
+ this.fills = ensureXlsxStyleCollection(styles, 'fills', [
3460
+ 'borders',
3461
+ 'cellStyleXfs',
3462
+ 'cellXfs',
3463
+ 'cellStyles',
3464
+ 'dxfs',
3465
+ 'tableStyles',
3466
+ 'colors',
3467
+ 'extLst'
3468
+ ]);
3469
+ if (!directChildren(this.fills, 'fill').length) {
3470
+ this.fills.append(defaultXlsxFill(styles, 'none'));
3471
+ this.fills.append(defaultXlsxFill(styles, 'gray125'));
3472
+ this.changed = true;
3473
+ }
3474
+ this.borders = ensureXlsxStyleCollection(styles, 'borders', [
3475
+ 'cellStyleXfs',
3476
+ 'cellXfs',
3477
+ 'cellStyles',
3478
+ 'dxfs',
3479
+ 'tableStyles',
3480
+ 'colors',
3481
+ 'extLst'
3482
+ ]);
3483
+ if (!directChildren(this.borders, 'border').length) {
3484
+ this.borders.append(defaultXlsxBorder(styles));
3485
+ this.changed = true;
3486
+ }
3487
+ this.cellXfs = ensureXlsxStyleCollection(styles, 'cellXfs', [
3488
+ 'cellStyles',
3489
+ 'dxfs',
3490
+ 'tableStyles',
3491
+ 'colors',
3492
+ 'extLst'
3493
+ ]);
3494
+ if (!directChildren(this.cellXfs, 'xf').length) {
3495
+ const base = styles.createElementNS(root.namespaceURI, 'xf');
3496
+ base.setAttribute('numFmtId', '0');
3497
+ base.setAttribute('fontId', '0');
3498
+ base.setAttribute('fillId', '0');
3499
+ base.setAttribute('borderId', '0');
3500
+ base.setAttribute('xfId', '0');
3501
+ this.cellXfs.append(base);
3502
+ this.changed = true;
3503
+ }
3504
+ this.updateCounts();
3505
+ }
3506
+ styleId(baseStyleId, cell, border) {
3507
+ const styles = directChildren(this.cellXfs, 'xf');
3508
+ const baseIndex = Number.isInteger(baseStyleId) && styles[baseStyleId] ? baseStyleId : 0;
3509
+ const base = styles[baseIndex];
3510
+ const fontId = this.fontId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'fontId')) ?? 0, cell);
3511
+ const fillId = this.fillId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'fillId')) ?? 0, cell);
3512
+ const borderId = this.borderId(work_xlsx_cell_style_writer_nonNegativeInteger(work_ooxml_package_attribute(base, 'borderId')) ?? 0, border);
3513
+ const alignment = directAlignment(cell);
3514
+ const key = `${baseIndex}:${fontId}:${fillId}:${borderId}:${JSON.stringify(alignment)}`;
3515
+ const cached = this.generatedStyles.get(key);
3516
+ if (void 0 !== cached) return cached;
3517
+ const clone = base.cloneNode(true);
3518
+ clone.setAttribute('fontId', String(fontId));
3519
+ clone.setAttribute('fillId', String(fillId));
3520
+ clone.setAttribute('borderId', String(borderId));
3521
+ if (hasXlsxDirectFontStyle(cell)) clone.setAttribute('applyFont', '1');
3522
+ if (void 0 !== cell.bg) clone.setAttribute('applyFill', '1');
3523
+ if (border) clone.setAttribute('applyBorder', '1');
3524
+ if (alignment) {
3525
+ writeXlsxAlignment(this.styles, clone, alignment);
3526
+ clone.setAttribute('applyAlignment', '1');
3527
+ }
3528
+ const index = styles.length;
3529
+ this.cellXfs.append(clone);
3530
+ this.generatedStyles.set(key, index);
3531
+ this.changed = true;
3532
+ this.updateCounts();
3533
+ return index;
3534
+ }
3535
+ fontId(baseFontId, cell) {
3536
+ if (!hasXlsxDirectFontStyle(cell)) return baseFontId;
3537
+ const fonts = directChildren(this.fonts, 'font');
3538
+ const baseIndex = fonts[baseFontId] ? baseFontId : 0;
3539
+ const style = directFontStyle(cell);
3540
+ const key = `${baseIndex}:${JSON.stringify(style)}`;
3541
+ const cached = this.generatedFonts.get(key);
3542
+ if (void 0 !== cached) return cached;
3543
+ const font = fonts[baseIndex].cloneNode(true);
3544
+ if (void 0 !== style.name) setXlsxValueChild(this.styles, font, 'name', style.name, fontChildOrder);
3545
+ if (void 0 !== style.size) setXlsxValueChild(this.styles, font, 'sz', String(style.size), fontChildOrder);
3546
+ if (void 0 !== style.color) setXlsxColorChild(this.styles, font, style.color, fontChildOrder);
3547
+ if (void 0 !== style.bold) setXlsxToggleChild(this.styles, font, 'b', style.bold, fontChildOrder);
3548
+ if (void 0 !== style.italic) setXlsxToggleChild(this.styles, font, 'i', style.italic, fontChildOrder);
3549
+ if (void 0 !== style.strike) setXlsxToggleChild(this.styles, font, 'strike', style.strike, fontChildOrder);
3550
+ if (void 0 !== style.underline) setXlsxUnderlineChild(this.styles, font, style.underline, fontChildOrder);
3551
+ const index = fonts.length;
3552
+ this.fonts.append(font);
3553
+ this.generatedFonts.set(key, index);
3554
+ this.changed = true;
3555
+ this.updateCounts();
3556
+ return index;
3557
+ }
3558
+ fillId(baseFillId, cell) {
3559
+ if (void 0 === cell.bg) return baseFillId;
3560
+ const color = xlsxRgbColor(cell.bg);
3561
+ if (!color) return baseFillId;
3562
+ const cached = this.generatedFills.get(color);
3563
+ if (void 0 !== cached) return cached;
3564
+ const fill = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fill');
3565
+ const pattern = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'patternFill');
3566
+ pattern.setAttribute('patternType', 'solid');
3567
+ const foreground = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fgColor');
3568
+ foreground.setAttribute('rgb', color);
3569
+ const background = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'bgColor');
3570
+ background.setAttribute('indexed', '64');
3571
+ pattern.append(foreground, background);
3572
+ fill.append(pattern);
3573
+ const index = directChildren(this.fills, 'fill').length;
3574
+ this.fills.append(fill);
3575
+ this.generatedFills.set(color, index);
3576
+ this.changed = true;
3577
+ this.updateCounts();
3578
+ return index;
3579
+ }
3580
+ borderId(baseBorderId, update) {
3581
+ if (!update) return baseBorderId;
3582
+ const borders = directChildren(this.borders, 'border');
3583
+ const baseIndex = borders[baseBorderId] ? baseBorderId : 0;
3584
+ const key = `${baseIndex}:${JSON.stringify(update)}`;
3585
+ const cached = this.generatedBorders.get(key);
3586
+ if (void 0 !== cached) return cached;
3587
+ const border = borders[baseIndex].cloneNode(true);
3588
+ for (const [name, line] of [
3589
+ [
3590
+ 'left',
3591
+ update.left
3592
+ ],
3593
+ [
3594
+ 'right',
3595
+ update.right
3596
+ ],
3597
+ [
3598
+ 'top',
3599
+ update.top
3600
+ ],
3601
+ [
3602
+ 'bottom',
3603
+ update.bottom
3604
+ ],
3605
+ [
3606
+ 'diagonal',
3607
+ update.diagonal
3608
+ ]
3609
+ ])if (void 0 !== line) setXlsxBorderLine(this.styles, border, name, line);
3610
+ if (void 0 !== update.diagonalUp) border.setAttribute('diagonalUp', update.diagonalUp ? '1' : '0');
3611
+ if (void 0 !== update.diagonalDown) border.setAttribute('diagonalDown', update.diagonalDown ? '1' : '0');
3612
+ const index = borders.length;
3613
+ this.borders.append(border);
3614
+ this.generatedBorders.set(key, index);
3615
+ this.changed = true;
3616
+ this.updateCounts();
3617
+ return index;
3618
+ }
3619
+ updateCounts() {
3620
+ this.fonts.setAttribute('count', String(directChildren(this.fonts, 'font').length));
3621
+ this.fills.setAttribute('count', String(directChildren(this.fills, 'fill').length));
3622
+ this.borders.setAttribute('count', String(directChildren(this.borders, 'border').length));
3623
+ this.cellXfs.setAttribute('count', String(directChildren(this.cellXfs, 'xf').length));
3624
+ }
3625
+ }
3626
+ function hasXlsxDirectCellStyle(cell) {
3627
+ return Boolean(hasXlsxDirectFontStyle(cell) || void 0 !== cell.bg || void 0 !== cell.ht || void 0 !== cell.vt || void 0 !== cell.tb || void 0 !== cell.tr);
3628
+ }
3629
+ function hasXlsxDirectFontStyle(cell) {
3630
+ return Boolean(void 0 !== cell.bl || void 0 !== cell.it || void 0 !== cell.un || void 0 !== cell.cl || void 0 !== cell.ff || void 0 !== cell.fs || void 0 !== cell.fc);
3631
+ }
3632
+ function directFontStyle(cell) {
3633
+ const color = void 0 !== cell.fc ? xlsxRgbColor(cell.fc) : null;
3634
+ return {
3635
+ ...void 0 !== cell.bl ? {
3636
+ bold: 1 === Number(cell.bl)
3637
+ } : {},
3638
+ ...color ? {
3639
+ color
3640
+ } : {},
3641
+ ...void 0 !== cell.it ? {
3642
+ italic: 1 === Number(cell.it)
3643
+ } : {},
3644
+ ...'string' == typeof cell.ff && cell.ff.trim() ? {
3645
+ name: cell.ff.trim()
3646
+ } : {},
3647
+ ...'number' == typeof cell.fs && Number.isFinite(cell.fs) && cell.fs > 0 ? {
3648
+ size: cell.fs
3649
+ } : {},
3650
+ ...void 0 !== cell.cl ? {
3651
+ strike: 1 === Number(cell.cl)
3652
+ } : {},
3653
+ ...void 0 !== cell.un ? {
3654
+ underline: 1 === Number(cell.un)
3655
+ } : {}
3656
+ };
3657
+ }
3658
+ function directAlignment(cell) {
3659
+ const alignment = {};
3660
+ if (void 0 !== cell.ht) alignment.horizontal = 0 === Number(cell.ht) ? 'center' : 2 === Number(cell.ht) ? 'right' : 'left';
3661
+ if (void 0 !== cell.vt) alignment.vertical = 0 === Number(cell.vt) ? 'center' : 1 === Number(cell.vt) ? 'top' : 'bottom';
3662
+ if (void 0 !== cell.tb) alignment.wrapText = '2' === cell.tb;
3663
+ if (void 0 !== cell.tr) {
3664
+ const rotation = Number(cell.tr);
3665
+ if (Number.isFinite(rotation) && rotation >= 0 && rotation <= 180) alignment.textRotation = Math.round(rotation);
3666
+ }
3667
+ return Object.keys(alignment).length ? alignment : null;
3668
+ }
3669
+ function work_xlsx_cell_style_writer_nonNegativeInteger(value) {
3670
+ if (null === value || !/^\d+$/.test(value)) return null;
3671
+ const parsed = Number(value);
3672
+ return Number.isSafeInteger(parsed) ? parsed : null;
3673
+ }
3674
+ const defaultThemeColors = [
3675
+ 'ffffff',
3676
+ '000000',
3677
+ 'e7e6e6',
3678
+ '44546a',
3679
+ '4472c4',
3680
+ 'ed7d31',
3681
+ 'a5a5a5',
3682
+ 'ffc000',
3683
+ '5b9bd5',
3684
+ '70ad47',
3685
+ '0563c1',
3686
+ '954f72'
3687
+ ];
3688
+ const themeColorNames = [
3689
+ 'lt1',
3690
+ 'dk1',
3691
+ 'lt2',
3692
+ 'dk2',
3693
+ 'accent1',
3694
+ 'accent2',
3695
+ 'accent3',
3696
+ 'accent4',
3697
+ 'accent5',
3698
+ 'accent6',
3699
+ 'hlink',
3700
+ 'folHlink'
3701
+ ];
3702
+ const defaultIndexedColors = [
3703
+ '000000',
3704
+ 'ffffff',
3705
+ 'ff0000',
3706
+ '00ff00',
3707
+ '0000ff',
3708
+ 'ffff00',
3709
+ 'ff00ff',
3710
+ '00ffff',
3711
+ '000000',
3712
+ 'ffffff',
3713
+ 'ff0000',
3714
+ '00ff00',
3715
+ '0000ff',
3716
+ 'ffff00',
3717
+ 'ff00ff',
3718
+ '00ffff',
3719
+ '800000',
3720
+ '008000',
3721
+ '000080',
3722
+ '808000',
3723
+ '800080',
3724
+ '008080',
3725
+ 'c0c0c0',
3726
+ '808080',
3727
+ '9999ff',
3728
+ '993366',
3729
+ 'ffffcc',
3730
+ 'ccffff',
3731
+ '660066',
3732
+ 'ff8080',
3733
+ '0066cc',
3734
+ 'ccccff',
3735
+ '000080',
3736
+ 'ff00ff',
3737
+ 'ffff00',
3738
+ '00ffff',
3739
+ '800080',
3740
+ '800000',
3741
+ '008080',
3742
+ '0000ff',
3743
+ '00ccff',
3744
+ 'ccffff',
3745
+ 'ccffcc',
3746
+ 'ffff99',
3747
+ '99ccff',
3748
+ 'ff99cc',
3749
+ 'cc99ff',
3750
+ 'ffcc99',
3751
+ '3366ff',
3752
+ '33cccc',
3753
+ '99cc00',
3754
+ 'ffcc00',
3755
+ 'ff9900',
3756
+ 'ff6600',
3757
+ '666699',
3758
+ '969696',
3759
+ '003366',
3760
+ '339966',
3761
+ '003300',
3762
+ '333300',
3763
+ '993300',
3764
+ '993366',
3765
+ '333399',
3766
+ '333333'
3767
+ ];
3768
+ function createXlsxColorResolver(styles, theme) {
3769
+ return {
3770
+ indexed: readIndexedColors(styles),
3771
+ theme: readThemeColors(theme)
3772
+ };
3773
+ }
3774
+ function resolveXlsxColor(element, resolver) {
3775
+ if (!element) return;
3776
+ const direct = normalizedHexColor(work_ooxml_package_attribute(element, 'rgb'));
3777
+ const themeIndex = boundedInteger(work_ooxml_package_attribute(element, 'theme'), 11);
3778
+ const indexed = boundedInteger(work_ooxml_package_attribute(element, 'indexed'), 65535);
3779
+ const automatic = work_xlsx_colors_booleanAttribute(element, 'auto');
3780
+ const source = direct ?? (null === themeIndex ? void 0 : resolver.theme[themeIndex]) ?? (null === indexed ? void 0 : resolver.indexed[indexed]) ?? (automatic ? '000000' : void 0);
3781
+ if (!source) return;
3782
+ const tint = Number(work_ooxml_package_attribute(element, 'tint'));
3783
+ return `#${Number.isFinite(tint) && tint >= -1 && tint <= 1 ? tintXlsxColor(source, tint) : source}`;
3784
+ }
3785
+ function readThemeColors(theme) {
3786
+ if (!theme) return defaultThemeColors;
3787
+ const scheme = firstDescendant(theme, 'clrScheme');
3788
+ if (!scheme) return defaultThemeColors;
3789
+ return themeColorNames.map((name, index)=>{
3790
+ const entry = directChild(scheme, name);
3791
+ const color = entry ? drawingColor(directChildren(entry)[0]) : void 0;
3792
+ return color ?? defaultThemeColors[index];
3793
+ });
3794
+ }
3795
+ function readIndexedColors(styles) {
3796
+ const indexed = firstDescendant(styles, 'indexedColors');
3797
+ if (!indexed) return defaultIndexedColors;
3798
+ const colors = directChildren(indexed, 'rgbColor').map((element)=>normalizedHexColor(work_ooxml_package_attribute(element, 'rgb')));
3799
+ return colors.every(Boolean) ? colors : defaultIndexedColors;
3800
+ }
3801
+ function drawingColor(element) {
3802
+ if (!element) return;
3803
+ return normalizedHexColor('sysClr' === element.localName ? work_ooxml_package_attribute(element, 'lastClr') : work_ooxml_package_attribute(element, 'val'));
3804
+ }
3805
+ function tintXlsxColor(color, tint) {
3806
+ const [hue, saturation, lightness] = rgbToHsl([
3807
+ 0,
3808
+ 2,
3809
+ 4
3810
+ ].map((offset)=>Number.parseInt(color.slice(offset, offset + 2), 16) / 255));
3811
+ const tintedLightness = tint < 0 ? lightness * (1 + tint) : 1 - (1 - lightness) * (1 - tint);
3812
+ return hslToRgb(hue, saturation, tintedLightness).map((channel)=>Math.round(255 * channel)).map((channel)=>channel.toString(16).padStart(2, '0')).join('');
3813
+ }
3814
+ function rgbToHsl([red, green, blue]) {
3815
+ const maximum = Math.max(red, green, blue);
3816
+ const minimum = Math.min(red, green, blue);
3817
+ const delta = maximum - minimum;
3818
+ const lightness = (maximum + minimum) / 2;
3819
+ if (0 === delta) return [
3820
+ 0,
3821
+ 0,
3822
+ lightness
3823
+ ];
3824
+ const saturation = delta / (1 - Math.abs(2 * lightness - 1));
3825
+ const hue = maximum === red ? ((green - blue) / delta + (green < blue ? 6 : 0)) / 6 : maximum === green ? ((blue - red) / delta + 2) / 6 : ((red - green) / delta + 4) / 6;
3826
+ return [
3827
+ hue,
3828
+ saturation,
3829
+ lightness
3830
+ ];
3831
+ }
3832
+ function hslToRgb(hue, saturation, lightness) {
3833
+ if (0 === saturation) return [
3834
+ lightness,
3835
+ lightness,
3836
+ lightness
3837
+ ];
3838
+ const chroma = 2 * saturation * (lightness < 0.5 ? lightness : 1 - lightness);
3839
+ const minimum = lightness - chroma / 2;
3840
+ const channels = [
3841
+ minimum,
3842
+ minimum,
3843
+ minimum
3844
+ ];
3845
+ const sector = 6 * hue;
3846
+ switch(Math.floor(sector)){
3847
+ case 0:
3848
+ case 6:
3849
+ channels[0] += chroma;
3850
+ channels[1] += chroma * sector;
3851
+ break;
3852
+ case 1:
3853
+ channels[0] += chroma * (2 - sector);
3854
+ channels[1] += chroma;
3855
+ break;
3856
+ case 2:
3857
+ channels[1] += chroma;
3858
+ channels[2] += chroma * (sector - 2);
3859
+ break;
3860
+ case 3:
3861
+ channels[1] += chroma * (4 - sector);
3862
+ channels[2] += chroma;
3863
+ break;
3864
+ case 4:
3865
+ channels[0] += chroma * (sector - 4);
3866
+ channels[2] += chroma;
3867
+ break;
3868
+ case 5:
3869
+ channels[0] += chroma;
3870
+ channels[2] += chroma * (6 - sector);
3871
+ break;
3872
+ }
3873
+ return channels;
3874
+ }
3875
+ function normalizedHexColor(value) {
3876
+ if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
3877
+ return value.slice(-6).toLowerCase();
3878
+ }
3879
+ function boundedInteger(value, maximum) {
3880
+ if (null === value || !/^\d+$/.test(value)) return null;
3881
+ const parsed = Number(value);
3882
+ return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
3883
+ }
3884
+ function work_xlsx_colors_booleanAttribute(element, name) {
3885
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3886
+ return '1' === value || 'true' === value || 'on' === value;
3887
+ }
3888
+ const xlsxCellBorderStyles = new Set([
3889
+ 'dashDot',
3890
+ 'dashDotDot',
3891
+ 'dashed',
3892
+ 'dotted',
3893
+ 'double',
3894
+ 'hair',
3895
+ 'medium',
3896
+ 'mediumDashDot',
3897
+ 'mediumDashDotDot',
3898
+ 'mediumDashed',
3899
+ 'slantDashDot',
3900
+ 'thick',
3901
+ 'thin'
3902
+ ]);
3903
+ function readXlsxDirectCellStyles(worksheet, styles, theme = null) {
3904
+ if (!styles) return [];
3905
+ const colors = createXlsxColorResolver(styles, theme);
3906
+ const fonts = directChildren(directChild(styles.documentElement, 'fonts') ?? styles, 'font');
3907
+ const fills = directChildren(directChild(styles.documentElement, 'fills') ?? styles, 'fill');
3908
+ const borders = directChildren(directChild(styles.documentElement, 'borders') ?? styles, 'border');
3909
+ const cellXfs = directChildren(directChild(styles.documentElement, 'cellXfs') ?? styles, 'xf');
3910
+ if (!cellXfs.length) return [];
3911
+ return descendants(worksheet, 'c').flatMap((cell)=>{
3912
+ const coordinate = decodeCell(work_ooxml_package_attribute(cell, 'r'));
3913
+ const styleId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(cell, 's'));
3914
+ const xf = null === styleId ? void 0 : cellXfs[styleId];
3915
+ if (!coordinate || !xf) return [];
3916
+ const style = readDirectCellStyle(xf, fonts, fills, colors);
3917
+ const border = readDirectCellBorder(xf, borders, colors);
3918
+ return Object.keys(style).length || border ? [
3919
+ {
3920
+ ...coordinate,
3921
+ border,
3922
+ style
3923
+ }
3924
+ ] : [];
3925
+ });
3926
+ }
3927
+ function sheetHasDirectCellStyles(sheet) {
3928
+ if (Array.isArray(sheet.config?.borderInfo) && sheet.config.borderInfo.length) return true;
3929
+ for (const [, row] of sparseArrayEntries(sheet.data))for (const [, cell] of sparseArrayEntries(row))if (cell && hasXlsxDirectCellStyle(cell)) return true;
3930
+ return false;
3931
+ }
3932
+ function writeXlsxDirectCellStyles(worksheet, sheet, styles) {
3933
+ const borders = collectXlsxCellBorders(sheet);
3934
+ const cells = new Map(descendants(worksheet, 'c').flatMap((element)=>{
3935
+ const reference = work_ooxml_package_attribute(element, 'r');
3936
+ return reference ? [
3937
+ [
3938
+ reference,
3939
+ element
3940
+ ]
3941
+ ] : [];
3942
+ }));
3943
+ for (const [row, values] of sparseArrayEntries(sheet.data))for (const [column, cell] of sparseArrayEntries(values)){
3944
+ const border = borders.get(xlsxCellBorderKey(row, column));
3945
+ if (!cell || !hasXlsxDirectCellStyle(cell) && !border) continue;
3946
+ const element = cells.get(encodeCell(row, column));
3947
+ if (!element) continue;
3948
+ const baseStyleId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(element, 's')) ?? 0;
3949
+ const styleId = styles.styleId(baseStyleId, cell, border);
3950
+ if (styleId) element.setAttribute('s', String(styleId));
3951
+ else element.removeAttribute('s');
3952
+ }
3953
+ }
3954
+ function readDirectCellStyle(xf, fonts, fills, colors) {
3955
+ const style = {};
3956
+ const fontId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fontId')) ?? 0;
3957
+ const font = fonts[fontId];
3958
+ if (font && (0 !== fontId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFont'))) readDirectFontStyle(style, font, colors);
3959
+ const fillId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fillId')) ?? 0;
3960
+ const fill = fills[fillId];
3961
+ if (fill && (0 !== fillId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFill'))) readDirectFillStyle(style, fill, colors);
3962
+ const alignment = directChild(xf, 'alignment');
3963
+ if (alignment) readDirectAlignmentStyle(style, alignment);
3964
+ return style;
3965
+ }
3966
+ function readDirectFontStyle(style, font, colors) {
3967
+ const bold = directChild(font, 'b');
3968
+ if (bold && toggleEnabled(bold)) style.bl = 1;
3969
+ const italic = directChild(font, 'i');
3970
+ if (italic && toggleEnabled(italic)) style.it = 1;
3971
+ const strike = directChild(font, 'strike');
3972
+ if (strike && toggleEnabled(strike)) style.cl = 1;
3973
+ const underline = directChild(font, 'u');
3974
+ if (underline && underlineEnabled(underline)) style.un = 1;
3975
+ const name = work_ooxml_package_attribute(directChild(font, 'name') ?? font, 'val')?.trim();
3976
+ if (name) style.ff = name;
3977
+ const size = Number(work_ooxml_package_attribute(directChild(font, 'sz') ?? font, 'val'));
3978
+ if (Number.isFinite(size) && size > 0) style.fs = size;
3979
+ const color = resolveXlsxColor(directChild(font, 'color'), colors);
3980
+ if (color) style.fc = color;
3981
+ }
3982
+ function readDirectFillStyle(style, fill, colors) {
3983
+ const pattern = directChild(fill, 'patternFill');
3984
+ if (!pattern || 'solid' !== work_ooxml_package_attribute(pattern, 'patternType')) return;
3985
+ const color = resolveXlsxColor(directChild(pattern, 'fgColor'), colors);
3986
+ if (color) style.bg = color;
3987
+ }
3988
+ function readDirectAlignmentStyle(style, alignment) {
3989
+ const horizontal = work_ooxml_package_attribute(alignment, 'horizontal');
3990
+ if ('center' === horizontal) style.ht = 0;
3991
+ else if ('left' === horizontal) style.ht = 1;
3992
+ else if ('right' === horizontal) style.ht = 2;
3993
+ const vertical = work_ooxml_package_attribute(alignment, 'vertical');
3994
+ if ('center' === vertical) style.vt = 0;
3995
+ else if ('top' === vertical) style.vt = 1;
3996
+ else if ('bottom' === vertical) style.vt = 2;
3997
+ if (work_xlsx_cell_styles_booleanAttribute(alignment, 'wrapText')) style.tb = '2';
3998
+ const rotation = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(alignment, 'textRotation'));
3999
+ if (null !== rotation && rotation <= 180) style.tr = String(rotation);
4000
+ }
4001
+ function readDirectCellBorder(xf, borders, colors) {
4002
+ const borderId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'borderId')) ?? 0;
4003
+ const source = borders[borderId];
4004
+ if (!source || 0 === borderId && !work_xlsx_cell_styles_booleanAttribute(xf, 'applyBorder')) return;
4005
+ const border = {};
4006
+ readBorderLine(border, 'left', directChild(source, 'left'), colors);
4007
+ readBorderLine(border, 'right', directChild(source, 'right'), colors);
4008
+ readBorderLine(border, 'top', directChild(source, 'top'), colors);
4009
+ readBorderLine(border, 'bottom', directChild(source, 'bottom'), colors);
4010
+ readBorderLine(border, 'diagonal', directChild(source, 'diagonal'), colors);
4011
+ if (border.diagonal) {
4012
+ border.diagonalUp = work_xlsx_cell_styles_booleanAttribute(source, 'diagonalUp');
4013
+ border.diagonalDown = work_xlsx_cell_styles_booleanAttribute(source, 'diagonalDown');
4014
+ }
4015
+ return Object.keys(border).length ? border : void 0;
4016
+ }
4017
+ function readBorderLine(border, name, element, colors) {
4018
+ if (!element) return;
4019
+ const style = work_ooxml_package_attribute(element, 'style');
4020
+ if (!style || !xlsxCellBorderStyles.has(style)) return;
4021
+ border[name] = {
4022
+ color: resolveXlsxColor(directChild(element, 'color'), colors) ?? '#000000',
4023
+ style: style
4024
+ };
4025
+ }
4026
+ function toggleEnabled(element) {
4027
+ const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
4028
+ return '0' !== value && 'false' !== value && 'off' !== value;
4029
+ }
4030
+ function underlineEnabled(element) {
4031
+ const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
4032
+ return '0' !== value && 'false' !== value && 'none' !== value;
4033
+ }
4034
+ function work_xlsx_cell_styles_booleanAttribute(element, name) {
4035
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
4036
+ return '1' === value || 'true' === value || 'on' === value;
4037
+ }
4038
+ function encodeCell(row, column) {
4039
+ let value = column + 1;
4040
+ let label = '';
4041
+ while(value > 0){
4042
+ value -= 1;
4043
+ label = String.fromCharCode(65 + value % 26) + label;
4044
+ value = Math.floor(value / 26);
4045
+ }
4046
+ return `${label}${row + 1}`;
4047
+ }
4048
+ function decodeCell(reference) {
4049
+ const match = /^([A-Z]{1,3})([1-9]\d{0,6})$/i.exec(reference ?? '');
4050
+ if (!match) return null;
4051
+ let column = 0;
4052
+ for (const character of match[1].toUpperCase())column = 26 * column + character.charCodeAt(0) - 64;
4053
+ const row = Number(match[2]);
4054
+ return column <= 16384 && row <= 1048576 ? {
4055
+ column: column - 1,
4056
+ row: row - 1
4057
+ } : null;
4058
+ }
4059
+ function work_xlsx_cell_styles_nonNegativeInteger(value) {
4060
+ if (null === value || !/^\d+$/.test(value)) return null;
4061
+ const parsed = Number(value);
4062
+ return Number.isSafeInteger(parsed) ? parsed : null;
4063
+ }
3064
4064
  function readXlsxDifferentialFormats(styles) {
3065
4065
  const container = styles ? firstDescendant(styles, 'dxfs') : null;
3066
4066
  if (!container) return [];
@@ -3492,7 +4492,7 @@ function writeRule(document1, rule, priority, differentialFormats) {
3492
4492
  if ('textContains' === rule.conditionName && values[0]) {
3493
4493
  element.setAttribute('type', 'containsText');
3494
4494
  element.setAttribute('text', values[0]);
3495
- const firstCell = encodeCell(rule.cellrange[0].row[0], rule.cellrange[0].column[0]);
4495
+ const firstCell = work_xlsx_conditional_format_write_encodeCell(rule.cellrange[0].row[0], rule.cellrange[0].column[0]);
3496
4496
  appendFormula(document1, element, `NOT(ISERROR(SEARCH("${values[0].replaceAll('"', '""')}",${firstCell})))`);
3497
4497
  return finish();
3498
4498
  }
@@ -3609,11 +4609,11 @@ function validIndex(value) {
3609
4609
  return 'number' == typeof value && Number.isInteger(value) && value >= 0;
3610
4610
  }
3611
4611
  function encodeRange(range) {
3612
- const start = encodeCell(range.row[0], range.column[0]);
3613
- const end = encodeCell(range.row[1], range.column[1]);
4612
+ const start = work_xlsx_conditional_format_write_encodeCell(range.row[0], range.column[0]);
4613
+ const end = work_xlsx_conditional_format_write_encodeCell(range.row[1], range.column[1]);
3614
4614
  return start === end ? start : `${start}:${end}`;
3615
4615
  }
3616
- function encodeCell(row, column) {
4616
+ function work_xlsx_conditional_format_write_encodeCell(row, column) {
3617
4617
  let value = column + 1;
3618
4618
  let label = '';
3619
4619
  while(value > 0){
@@ -4405,7 +5405,7 @@ function writeCellProtectionStyles(worksheet, sheet, styles) {
4405
5405
  const compact = compactProtectionAt(authority, row, column);
4406
5406
  if (void 0 === cell.lo && void 0 === cell.hi && void 0 === compact) continue;
4407
5407
  const element = ensureCellElement(worksheet, row, column);
4408
- const baseStyle = nonNegativeInteger(work_ooxml_package_attribute(element, 's')) ?? 0;
5408
+ const baseStyle = work_xlsx_protection_nonNegativeInteger(work_ooxml_package_attribute(element, 's')) ?? 0;
4409
5409
  const styleId = styles.styleId(baseStyle, void 0 === cell.lo ? compact?.locked ?? true : 0 !== cell.lo, void 0 === cell.hi ? compact?.hidden ?? false : 1 === cell.hi);
4410
5410
  if (styleId) element.setAttribute('s', String(styleId));
4411
5411
  else element.removeAttribute('s');
@@ -4572,7 +5572,7 @@ function work_xlsx_protection_parseSqref(value) {
4572
5572
  return value ? parseSpreadsheetCellRanges(value.trim().replace(/\s+/g, ',')) ?? [] : [];
4573
5573
  }
4574
5574
  function indexedStyle(styles, value) {
4575
- const index = nonNegativeInteger(value);
5575
+ const index = work_xlsx_protection_nonNegativeInteger(value);
4576
5576
  return null === index ? null : styles[index] ?? null;
4577
5577
  }
4578
5578
  function parseCellReference(value) {
@@ -4613,18 +5613,18 @@ function work_xlsx_protection_booleanAttribute(element, name, fallback) {
4613
5613
  if ('0' === value || 'false' === value || 'off' === value) return false;
4614
5614
  return fallback;
4615
5615
  }
4616
- function nonNegativeInteger(value) {
5616
+ function work_xlsx_protection_nonNegativeInteger(value) {
4617
5617
  if (null === value || !/^\d+$/.test(value)) return null;
4618
5618
  return Number(value);
4619
5619
  }
4620
5620
  function work_xlsx_protection_positiveInteger(value) {
4621
- const parsed = nonNegativeInteger(value);
5621
+ const parsed = work_xlsx_protection_nonNegativeInteger(value);
4622
5622
  return null !== parsed && parsed > 0 ? parsed : null;
4623
5623
  }
4624
5624
  function sameProtection(left, right) {
4625
5625
  return left.locked === right.locked && left.hidden === right.hidden;
4626
5626
  }
4627
- const XLSX_IMPORTED_WORKSHEET_ELEMENTS = [
5627
+ const IMPORTED_WORKSHEET_ELEMENTS = new Set([
4628
5628
  'pane',
4629
5629
  'dataValidation',
4630
5630
  'conditionalFormatting',
@@ -4638,10 +5638,51 @@ const XLSX_IMPORTED_WORKSHEET_ELEMENTS = [
4638
5638
  'headerFooter',
4639
5639
  'pageSetUpPr',
4640
5640
  'drawing'
4641
- ];
5641
+ ]);
5642
+ const DIAGNOSTIC_WORKSHEET_ELEMENTS = new Set([
5643
+ 'conditionalFormatting',
5644
+ 'dataValidation',
5645
+ 'sheetProtection',
5646
+ 'protectedRange',
5647
+ 'pageSetup',
5648
+ 'pageMargins',
5649
+ 'printOptions',
5650
+ 'headerFooter',
5651
+ 'pageSetUpPr',
5652
+ 'rowBreaks',
5653
+ 'colBreaks'
5654
+ ]);
5655
+ const WORKSHEET_SCAN_PATTERN = /<(?:[A-Za-z_][\w.-]*:)?(?:(cols|f|pane|dataValidation|conditionalFormatting|sheetProtection|protectedRange|rowBreaks|colBreaks|pageSetup|pageMargins|printOptions|headerFooter|pageSetUpPr|drawing)(?=[\s/>])|(row)(?=[\s/>])[^>]*\s(?:collapsed|customFormat|customHeight|hidden|ht|outlineLevel|thickBot|thickTop)\s*=|(c)(?=[\s/>])[^>]*\ss\s*=)/g;
5656
+ function scanXlsxWorksheetXml(source) {
5657
+ let hasDirectCellStyles = false;
5658
+ let hasDiagnosticFeatures = false;
5659
+ let hasFormulaFeatures = false;
5660
+ let hasImportedFeatures = false;
5661
+ let requiresSheetJsCellStyles = false;
5662
+ WORKSHEET_SCAN_PATTERN.lastIndex = 0;
5663
+ for(let match = WORKSHEET_SCAN_PATTERN.exec(source); match;){
5664
+ const element = match[1];
5665
+ if (match[3]) hasDirectCellStyles = true;
5666
+ if (match[2] || match[3] || 'cols' === element) requiresSheetJsCellStyles = true;
5667
+ if ('f' === element) hasFormulaFeatures = true;
5668
+ if (element && IMPORTED_WORKSHEET_ELEMENTS.has(element)) hasImportedFeatures = true;
5669
+ if (element && DIAGNOSTIC_WORKSHEET_ELEMENTS.has(element)) hasDiagnosticFeatures = true;
5670
+ if (hasDirectCellStyles && hasDiagnosticFeatures && hasFormulaFeatures && hasImportedFeatures && requiresSheetJsCellStyles) break;
5671
+ match = WORKSHEET_SCAN_PATTERN.exec(source);
5672
+ }
5673
+ WORKSHEET_SCAN_PATTERN.lastIndex = 0;
5674
+ return {
5675
+ hasDirectCellStyles,
5676
+ hasDiagnosticFeatures,
5677
+ hasFormulaFeatures,
5678
+ hasImportedFeatures,
5679
+ requiresSheetJsCellStyles
5680
+ };
5681
+ }
4642
5682
  async function readXlsxSheetFeaturesFromPackage(archive, worksheetScans) {
4643
5683
  const worksheetParts = await work_xlsx_interop_readWorksheetParts(archive);
4644
5684
  const styles = archive.has('xl/styles.xml') ? await archive.xml('xl/styles.xml') : null;
5685
+ const theme = archive.has('xl/theme/theme1.xml') ? await archive.xml('xl/theme/theme1.xml') : null;
4645
5686
  const differentialFormats = readXlsxDifferentialFormats(styles);
4646
5687
  const features = new Map();
4647
5688
  const imageBudget = {
@@ -4650,17 +5691,19 @@ async function readXlsxSheetFeaturesFromPackage(archive, worksheetScans) {
4650
5691
  for (const [sheetName, partPath] of worksheetParts){
4651
5692
  if (!archive.has(partPath)) continue;
4652
5693
  const scan = worksheetScans?.[partPath];
4653
- if (scan && !scan.hasImportedFeatures) {
5694
+ if (scan && !scan.hasImportedFeatures && !scan.hasDirectCellStyles) {
4654
5695
  features.set(sheetName, emptyXlsxSheetFeatures());
4655
5696
  continue;
4656
5697
  }
4657
5698
  const source = await archive.text(partPath);
4658
- if (!scan && !xmlContainsAnyElement(source, XLSX_IMPORTED_WORKSHEET_ELEMENTS)) {
5699
+ const detected = scan ?? scanXlsxWorksheetXml(source);
5700
+ if (!detected.hasImportedFeatures && !detected.hasDirectCellStyles) {
4659
5701
  features.set(sheetName, emptyXlsxSheetFeatures());
4660
5702
  continue;
4661
5703
  }
4662
5704
  const document1 = parseXml(source, partPath);
4663
5705
  features.set(sheetName, {
5706
+ directCellStyles: readXlsxDirectCellStyles(document1, styles, theme),
4664
5707
  frozen: parseFrozenPane(document1) ?? void 0,
4665
5708
  validations: parseDataValidations(document1),
4666
5709
  conditionalFormats: readXlsxConditionalFormats(document1, differentialFormats),
@@ -4675,6 +5718,7 @@ async function readXlsxSheetFeaturesFromPackage(archive, worksheetScans) {
4675
5718
  }
4676
5719
  function emptyXlsxSheetFeatures() {
4677
5720
  return {
5721
+ directCellStyles: [],
4678
5722
  validations: [],
4679
5723
  conditionalFormats: [],
4680
5724
  protection: {
@@ -4698,17 +5742,18 @@ async function patchXlsxSheetFeatures(buffer, content) {
4698
5742
  pageSetup.sheetId,
4699
5743
  pageSetup
4700
5744
  ]));
4701
- if (!sheets.some((sheet)=>sheet.frozen || Object.keys(sheet.dataVerification ?? {}).length || sheet.dataValidationRanges?.length || sheet.luckysheet_conditionformat_save?.length || sheetHasProtectionState(sheet) || Boolean(sheet.id && (pageBreaksBySheetId.get(sheet.id)?.rows?.length ?? 0) + (pageBreaksBySheetId.get(sheet.id)?.columns?.length ?? 0)) || Boolean(sheet.id && pageSetupsBySheetId.has(sheet.id)))) return buffer;
5745
+ if (!sheets.some((sheet)=>sheet.frozen || Object.keys(sheet.dataVerification ?? {}).length || sheet.dataValidationRanges?.length || sheet.luckysheet_conditionformat_save?.length || sheetHasDirectCellStyles(sheet) || sheetHasProtectionState(sheet) || Boolean(sheet.id && (pageBreaksBySheetId.get(sheet.id)?.rows?.length ?? 0) + (pageBreaksBySheetId.get(sheet.id)?.columns?.length ?? 0)) || Boolean(sheet.id && pageSetupsBySheetId.has(sheet.id)))) return buffer;
4702
5746
  const archive = await work_ooxml_package_OoxmlPackage.load(buffer);
4703
5747
  const worksheetParts = await work_xlsx_interop_readWorksheetParts(archive);
4704
5748
  const zip = await jszip.loadAsync(buffer);
4705
5749
  const styles = archive.has('xl/styles.xml') ? await archive.xml('xl/styles.xml') : null;
4706
5750
  const differentialFormats = styles ? new XlsxDifferentialFormatWriter(styles) : void 0;
5751
+ const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles) : void 0;
4707
5752
  const cellProtection = styles ? new XlsxCellProtectionWriter(styles) : void 0;
4708
5753
  for (const sheet of sheets){
4709
5754
  const pageBreaks = sheet.id ? pageBreaksBySheetId.get(sheet.id) : void 0;
4710
5755
  const pageSetup = sheet.id ? pageSetupsBySheetId.get(sheet.id) : void 0;
4711
- if (!sheet.frozen && !Object.keys(sheet.dataVerification ?? {}).length && !sheet.dataValidationRanges?.length && !sheet.luckysheet_conditionformat_save?.length && !sheetHasProtectionState(sheet) && !(pageBreaks?.rows?.length || pageBreaks?.columns?.length) && !pageSetup) continue;
5756
+ if (!sheet.frozen && !Object.keys(sheet.dataVerification ?? {}).length && !sheet.dataValidationRanges?.length && !sheet.luckysheet_conditionformat_save?.length && !sheetHasDirectCellStyles(sheet) && !sheetHasProtectionState(sheet) && !(pageBreaks?.rows?.length || pageBreaks?.columns?.length) && !pageSetup) continue;
4712
5757
  const exportedName = sheet.name.slice(0, 31) || '工作表';
4713
5758
  const partPath = worksheetParts.get(exportedName);
4714
5759
  const entry = partPath ? zip.file(partPath) : null;
@@ -4717,12 +5762,13 @@ async function patchXlsxSheetFeatures(buffer, content) {
4717
5762
  if (sheet.frozen) writeFrozenPane(document1, sheet.frozen);
4718
5763
  writeDataValidations(document1, sheet.dataVerification, sheet.dataValidationRanges);
4719
5764
  writeXlsxConditionalFormats(document1, sheet.luckysheet_conditionformat_save, differentialFormats);
5765
+ if (directCellStyles) writeXlsxDirectCellStyles(document1, sheet, directCellStyles);
4720
5766
  writeXlsxProtection(document1, sheet, cellProtection);
4721
5767
  writeXlsxPageSetup(document1, pageSetup);
4722
5768
  writeXlsxManualPageBreaks(document1, pageBreaks);
4723
5769
  zip.file(partPath, new XMLSerializer().serializeToString(document1));
4724
5770
  }
4725
- if (differentialFormats?.changed || cellProtection?.changed) zip.file('xl/styles.xml', differentialFormats?.serialize() ?? cellProtection?.serialize() ?? '');
5771
+ if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
4726
5772
  return zip.generateAsync({
4727
5773
  type: 'arraybuffer',
4728
5774
  compression: 'DEFLATE'
@@ -6004,6 +7050,7 @@ function xlsxCellStyle(cell) {
6004
7050
  font: {
6005
7051
  bold: Boolean(cell.bl),
6006
7052
  italic: Boolean(cell.it),
7053
+ strike: Boolean(cell.cl),
6007
7054
  underline: Boolean(cell.un),
6008
7055
  name: cell.ff,
6009
7056
  sz: cell.fs,
@@ -6585,6 +7632,10 @@ async function importWorkSpreadsheetFile(file, extension, context) {
6585
7632
  if (!worksheet) continue;
6586
7633
  const plainWorksheet = packageScanResult?.plainWorksheets?.[name];
6587
7634
  const features = sheetFeatures.get(name);
7635
+ const directCellStyles = new Map((features?.directCellStyles ?? []).map((entry)=>[
7636
+ spreadsheetCellKey(entry.row, entry.column),
7637
+ entry
7638
+ ]));
6588
7639
  const range = safeSpreadsheetRange(worksheet, XLSX);
6589
7640
  let rowCount = Math.max(plainWorksheet?.rowCount ?? range.e.r + 1, 40);
6590
7641
  let columnCount = Math.max(plainWorksheet?.columnCount ?? range.e.c + 1, 12);
@@ -6611,8 +7662,10 @@ async function importWorkSpreadsheetFile(file, extension, context) {
6611
7662
  const comment = importXlsxCellComment(source.c);
6612
7663
  updateSpreadsheetWorksheetCompatibilitySummary(compatibilitySummary, source);
6613
7664
  if (hyperlink) hyperlinks[`${row}_${column}`] = hyperlink;
7665
+ const directCellStyle = directCellStyles.get(spreadsheetCellKey(row, column));
7666
+ directCellStyles.delete(spreadsheetCellKey(row, column));
6614
7667
  data[row] ??= [];
6615
- data[row][column] = freezeImportedSpreadsheetCell(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX));
7668
+ data[row][column] = freezeImportedSpreadsheetCell(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style));
6616
7669
  if (source.f) formulaCells.push({
6617
7670
  column,
6618
7671
  row
@@ -6625,10 +7678,26 @@ async function importWorkSpreadsheetFile(file, extension, context) {
6625
7678
  }
6626
7679
  releaseImportedWorksheetCells(worksheet);
6627
7680
  }
7681
+ for (const { column, row, style } of directCellStyles.values()){
7682
+ rowCount = Math.max(rowCount, row + 1);
7683
+ columnCount = Math.max(columnCount, column + 1);
7684
+ data[row] ??= [];
7685
+ const existing = data[row][column];
7686
+ data[row][column] = freezeImportedSpreadsheetCell({
7687
+ ...existing ?? {},
7688
+ ...style
7689
+ });
7690
+ if (!existing) entryIndex += 1;
7691
+ }
6628
7692
  populatedCellCount += entryIndex;
6629
7693
  worksheetCompatibility.set(name, compatibilitySummary);
6630
7694
  data.length = Math.max(data.length, rowCount);
6631
7695
  const config = fortuneSheetConfig(worksheet);
7696
+ const importedBorderInfo = fortuneBorderInfoFromXlsxCells(features?.directCellStyles ?? []);
7697
+ if (importedBorderInfo.length) config.borderInfo = [
7698
+ ...Array.isArray(config.borderInfo) ? config.borderInfo : [],
7699
+ ...importedBorderInfo
7700
+ ];
6632
7701
  registerImportedSpreadsheetMatrix(data, {
6633
7702
  columnCount,
6634
7703
  formulaCells,
@@ -6807,8 +7876,11 @@ function fortuneSheetConfig(worksheet) {
6807
7876
  }
6808
7877
  return config;
6809
7878
  }
6810
- function fortuneCellFromXlsx(source, row, column, sheetId, hyperlink, comment, XLSX) {
6811
- const cell = fortuneCellStyle(source);
7879
+ function fortuneCellFromXlsx(source, row, column, sheetId, hyperlink, comment, XLSX, directStyle) {
7880
+ const cell = {
7881
+ ...fortuneCellStyle(source),
7882
+ ...directStyle
7883
+ };
6812
7884
  if (void 0 !== source.v) cell.v = source.v;
6813
7885
  const displayText = fortuneCellDisplayText(source, XLSX);
6814
7886
  if (void 0 !== displayText) cell.m = displayText;
@@ -6825,6 +7897,9 @@ function fortuneCellFromXlsx(source, row, column, sheetId, hyperlink, comment, X
6825
7897
  }
6826
7898
  return cell;
6827
7899
  }
7900
+ function spreadsheetCellKey(row, column) {
7901
+ return `${row}_${column}`;
7902
+ }
6828
7903
  function fortuneCellStyle(source) {
6829
7904
  const style = source.s;
6830
7905
  const font = style && 'object' == typeof style ? style.font : void 0;
@@ -6833,6 +7908,7 @@ function fortuneCellStyle(source) {
6833
7908
  const target = {};
6834
7909
  if (font?.bold) target.bl = 1;
6835
7910
  if (font?.italic) target.it = 1;
7911
+ if (font?.strike) target.cl = 1;
6836
7912
  if (font?.underline) target.un = 1;
6837
7913
  if (font?.name) target.ff = font.name;
6838
7914
  if (font?.sz !== void 0) target.fs = font.sz;