@a3s-lab/office 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/4104.js CHANGED
@@ -3410,265 +3410,6 @@ function insertXlsxOrderedChild(parent, child, order) {
3410
3410
  const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
3411
3411
  parent.insertBefore(child, anchor ?? null);
3412
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.rt || 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: spreadsheetUnderlineStyle(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
- const rotation = spreadsheetTextOrientationXlsxValueFromCell(cell);
3664
- if (null !== rotation) alignment.textRotation = rotation;
3665
- return Object.keys(alignment).length ? alignment : null;
3666
- }
3667
- function work_xlsx_cell_style_writer_nonNegativeInteger(value) {
3668
- if (null === value || !/^\d+$/.test(value)) return null;
3669
- const parsed = Number(value);
3670
- return Number.isSafeInteger(parsed) ? parsed : null;
3671
- }
3672
3413
  const defaultThemeColors = [
3673
3414
  'ffffff',
3674
3415
  '000000',
@@ -3870,19 +3611,633 @@ function hslToRgb(hue, saturation, lightness) {
3870
3611
  }
3871
3612
  return channels;
3872
3613
  }
3873
- function normalizedHexColor(value) {
3874
- if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
3875
- return value.slice(-6).toLowerCase();
3614
+ function normalizedHexColor(value) {
3615
+ if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
3616
+ return value.slice(-6).toLowerCase();
3617
+ }
3618
+ function boundedInteger(value, maximum) {
3619
+ if (null === value || !/^\d+$/.test(value)) return null;
3620
+ const parsed = Number(value);
3621
+ return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
3622
+ }
3623
+ function work_xlsx_colors_booleanAttribute(element, name) {
3624
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3625
+ return '1' === value || 'true' === value || 'on' === value;
3626
+ }
3627
+ const THEME_COLOR_NAMES = [
3628
+ 'lt1',
3629
+ 'dk1',
3630
+ 'lt2',
3631
+ 'dk2',
3632
+ 'accent1',
3633
+ 'accent2',
3634
+ 'accent3',
3635
+ 'accent4',
3636
+ 'accent5',
3637
+ 'accent6',
3638
+ 'hlink',
3639
+ 'folHlink'
3640
+ ];
3641
+ const MAX_INDEXED_COLOR = 255;
3642
+ function readXlsxSemanticColorOrigin(element, colors) {
3643
+ if (!element || work_ooxml_package_attribute(element, 'rgb')) return;
3644
+ const renderedColor = resolveXlsxColor(element, colors);
3645
+ if (!renderedColor) return;
3646
+ const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
3647
+ const theme = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'theme'), THEME_COLOR_NAMES.length - 1);
3648
+ if (null !== theme && colors.theme[theme]) return {
3649
+ kind: 'theme',
3650
+ baseColor: `#${colors.theme[theme]}`,
3651
+ index: theme,
3652
+ renderedColor,
3653
+ ...null === tint ? {} : {
3654
+ tint
3655
+ }
3656
+ };
3657
+ const indexed = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'indexed'), MAX_INDEXED_COLOR);
3658
+ if (null !== indexed && colors.indexed[indexed]) return {
3659
+ kind: 'indexed',
3660
+ baseColor: `#${colors.indexed[indexed]}`,
3661
+ index: indexed,
3662
+ renderedColor,
3663
+ ...null === tint ? {} : {
3664
+ tint
3665
+ }
3666
+ };
3667
+ if (xlsxBooleanAttribute(element, 'auto')) return {
3668
+ kind: 'automatic',
3669
+ baseColor: '#000000',
3670
+ renderedColor,
3671
+ ...null === tint ? {} : {
3672
+ tint
3673
+ }
3674
+ };
3675
+ }
3676
+ function withXlsxCellStyleOrigin(cell, origin) {
3677
+ return origin && xlsxCellStyleOriginHasValues(origin) ? {
3678
+ ...cell,
3679
+ a3sXlsxStyleOrigin: origin
3680
+ } : cell;
3681
+ }
3682
+ function xlsxCellStyleOrigin(cell) {
3683
+ const candidate = cell?.a3sXlsxStyleOrigin;
3684
+ if (!work_xlsx_cell_style_origin_isRecord(candidate)) return;
3685
+ const fontColor = normalizedXlsxSemanticColor(candidate.fontColor);
3686
+ const fillColor = normalizedXlsxSemanticColor(candidate.fillColor);
3687
+ const borderColors = normalizedBorderColors(candidate.borderColors);
3688
+ const origin = {
3689
+ ...fontColor ? {
3690
+ fontColor
3691
+ } : {},
3692
+ ...fillColor ? {
3693
+ fillColor
3694
+ } : {},
3695
+ ...borderColors ? {
3696
+ borderColors
3697
+ } : {}
3698
+ };
3699
+ return xlsxCellStyleOriginHasValues(origin) ? origin : void 0;
3700
+ }
3701
+ function xlsxSemanticColorMatchesValue(origin, value) {
3702
+ return normalizedColor(value) === origin.renderedColor.toLowerCase();
3703
+ }
3704
+ function xlsxColorElementMatchesOrigin(element, origin) {
3705
+ if (!element || work_ooxml_package_attribute(element, 'rgb')) return false;
3706
+ if ('theme' === origin.kind) {
3707
+ if (work_ooxml_package_attribute(element, 'theme') !== String(origin.index)) return false;
3708
+ } else if ('indexed' === origin.kind) {
3709
+ if (work_ooxml_package_attribute(element, 'indexed') !== String(origin.index)) return false;
3710
+ } else if (!xlsxBooleanAttribute(element, 'auto')) return false;
3711
+ const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
3712
+ return tint === (origin.tint ?? null);
3713
+ }
3714
+ function applyXlsxSemanticColorOrigin(element, origin) {
3715
+ for (const name of [
3716
+ 'rgb',
3717
+ 'theme',
3718
+ 'indexed',
3719
+ 'auto',
3720
+ 'tint'
3721
+ ])element.removeAttribute(name);
3722
+ if ('theme' === origin.kind) element.setAttribute('theme', String(origin.index));
3723
+ else if ('indexed' === origin.kind) element.setAttribute('indexed', String(origin.index));
3724
+ else element.setAttribute('auto', '1');
3725
+ if (void 0 !== origin.tint) element.setAttribute('tint', String(origin.tint));
3726
+ }
3727
+ function xlsxSemanticColorOriginKey(origin) {
3728
+ return origin ? `${origin.kind}:${'index' in origin ? origin.index : ''}:${origin.baseColor}:${origin.renderedColor}:${origin.tint ?? ''}` : '';
3729
+ }
3730
+ function xlsxSemanticColorOriginSupported(origin, palette) {
3731
+ if ('automatic' === origin.kind) return true;
3732
+ return palette?.[origin.kind].get(origin.index)?.toLowerCase() === origin.baseColor.toLowerCase();
3733
+ }
3734
+ function prepareXlsxSemanticPalette(styles, theme, origins) {
3735
+ const candidates = semanticPaletteCandidates(origins);
3736
+ const supportedTheme = new Map();
3737
+ let themeChanged = false;
3738
+ const scheme = theme ? firstDescendant(theme, 'clrScheme') : void 0;
3739
+ for (const [index, color] of candidates.theme){
3740
+ const name = THEME_COLOR_NAMES[index];
3741
+ const entry = name && scheme ? directChild(scheme, name) : void 0;
3742
+ if (entry) {
3743
+ themeChanged = writeThemeColor(entry, color) || themeChanged;
3744
+ supportedTheme.set(index, color);
3745
+ }
3746
+ }
3747
+ const supportedIndexed = new Map();
3748
+ let stylesChanged = false;
3749
+ if (candidates.indexed.size) {
3750
+ const colors = ensureXlsxStyleCollection(styles, 'colors', [
3751
+ 'extLst'
3752
+ ]);
3753
+ let indexedColors = directChild(colors, 'indexedColors');
3754
+ if (!indexedColors) {
3755
+ indexedColors = styles.createElementNS(styles.documentElement.namespaceURI, 'indexedColors');
3756
+ colors.prepend(indexedColors);
3757
+ stylesChanged = true;
3758
+ }
3759
+ const resolver = createXlsxColorResolver(styles, theme);
3760
+ const highestIndex = Math.max(...candidates.indexed.keys());
3761
+ while(directChildren(indexedColors, 'rgbColor').length <= highestIndex){
3762
+ const index = directChildren(indexedColors, 'rgbColor').length;
3763
+ const element = styles.createElementNS(styles.documentElement.namespaceURI, 'rgbColor');
3764
+ element.setAttribute('rgb', `FF${(resolver.indexed[index] ?? '000000').toUpperCase()}`);
3765
+ indexedColors.append(element);
3766
+ stylesChanged = true;
3767
+ }
3768
+ const entries = directChildren(indexedColors, 'rgbColor');
3769
+ for (const [index, color] of candidates.indexed){
3770
+ const expected = `FF${color.slice(1).toUpperCase()}`;
3771
+ const entry = entries[index];
3772
+ if (entry) {
3773
+ if (work_ooxml_package_attribute(entry, 'rgb')?.toUpperCase() !== expected) {
3774
+ entry.setAttribute('rgb', expected);
3775
+ stylesChanged = true;
3776
+ }
3777
+ supportedIndexed.set(index, color);
3778
+ }
3779
+ }
3780
+ }
3781
+ return {
3782
+ palette: {
3783
+ indexed: supportedIndexed,
3784
+ theme: supportedTheme
3785
+ },
3786
+ stylesChanged,
3787
+ themeChanged
3788
+ };
3789
+ }
3790
+ function semanticPaletteCandidates(origins) {
3791
+ const theme = new Map();
3792
+ const indexed = new Map();
3793
+ const themeConflicts = new Set();
3794
+ const indexedConflicts = new Set();
3795
+ for (const origin of origins)for (const color of xlsxCellStyleOriginColors(origin)){
3796
+ if ('automatic' === color.kind) continue;
3797
+ const target = 'theme' === color.kind ? theme : indexed;
3798
+ const conflicts = 'theme' === color.kind ? themeConflicts : indexedConflicts;
3799
+ const current = target.get(color.index);
3800
+ if (current && current.toLowerCase() !== color.baseColor.toLowerCase()) conflicts.add(color.index);
3801
+ else if (!current) target.set(color.index, color.baseColor);
3802
+ }
3803
+ for (const index of themeConflicts)theme.delete(index);
3804
+ for (const index of indexedConflicts)indexed.delete(index);
3805
+ return {
3806
+ indexed,
3807
+ theme
3808
+ };
3809
+ }
3810
+ function xlsxCellStyleOriginColors(origin) {
3811
+ return [
3812
+ origin.fontColor,
3813
+ origin.fillColor,
3814
+ ...Object.values(origin.borderColors ?? {})
3815
+ ].filter((value)=>Boolean(value));
3816
+ }
3817
+ function writeThemeColor(entry, color) {
3818
+ const current = directChildren(entry)[0];
3819
+ if (current?.localName === 'srgbClr' && work_ooxml_package_attribute(current, 'val')?.toLowerCase() === color.slice(1).toLowerCase()) return false;
3820
+ for (const child of directChildren(entry))child.remove();
3821
+ const qualifiedName = entry.prefix ? `${entry.prefix}:srgbClr` : 'srgbClr';
3822
+ const replacement = entry.ownerDocument.createElementNS(entry.namespaceURI, qualifiedName);
3823
+ replacement.setAttribute('val', color.slice(1).toUpperCase());
3824
+ entry.append(replacement);
3825
+ return true;
3826
+ }
3827
+ function normalizedBorderColors(value) {
3828
+ if (!work_xlsx_cell_style_origin_isRecord(value)) return;
3829
+ const result = {};
3830
+ for (const side of [
3831
+ 'bottom',
3832
+ 'diagonal',
3833
+ 'left',
3834
+ 'right',
3835
+ 'top'
3836
+ ]){
3837
+ const color = normalizedXlsxSemanticColor(value[side]);
3838
+ if (color) result[side] = color;
3839
+ }
3840
+ return Object.keys(result).length ? result : void 0;
3841
+ }
3842
+ function normalizedXlsxSemanticColor(value) {
3843
+ if (!work_xlsx_cell_style_origin_isRecord(value)) return;
3844
+ const baseColor = normalizedColor(value.baseColor);
3845
+ const renderedColor = normalizedColor(value.renderedColor);
3846
+ const tint = normalizedTint(value.tint);
3847
+ if (!baseColor || !renderedColor || void 0 === tint) return;
3848
+ if ('automatic' === value.kind) return {
3849
+ kind: 'automatic',
3850
+ baseColor,
3851
+ renderedColor,
3852
+ ...null === tint ? {} : {
3853
+ tint
3854
+ }
3855
+ };
3856
+ const maximum = 'theme' === value.kind ? THEME_COLOR_NAMES.length - 1 : MAX_INDEXED_COLOR;
3857
+ const index = boundedNumber(value.index, maximum);
3858
+ if ('theme' !== value.kind && 'indexed' !== value.kind || null === index) return;
3859
+ return {
3860
+ kind: value.kind,
3861
+ baseColor,
3862
+ index,
3863
+ renderedColor,
3864
+ ...null === tint ? {} : {
3865
+ tint
3866
+ }
3867
+ };
3868
+ }
3869
+ function xlsxCellStyleOriginHasValues(origin) {
3870
+ return Boolean(origin.fontColor || origin.fillColor || Object.keys(origin.borderColors ?? {}).length);
3871
+ }
3872
+ function normalizedColor(value) {
3873
+ const rgb = xlsxRgbColor(value);
3874
+ return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
3875
+ }
3876
+ function normalizedTint(value) {
3877
+ if (void 0 === value) return null;
3878
+ return 'number' == typeof value && Number.isFinite(value) && value >= -1 && value <= 1 ? value : void 0;
3879
+ }
3880
+ function boundedTint(value) {
3881
+ if (null === value) return null;
3882
+ const tint = Number(value);
3883
+ return Number.isFinite(tint) && tint >= -1 && tint <= 1 ? tint : null;
3884
+ }
3885
+ function work_xlsx_cell_style_origin_boundedInteger(value, maximum) {
3886
+ if (null === value || !/^\d+$/.test(value)) return null;
3887
+ return boundedNumber(Number(value), maximum);
3888
+ }
3889
+ function boundedNumber(value, maximum) {
3890
+ return 'number' == typeof value && Number.isSafeInteger(value) && value >= 0 && value <= maximum ? value : null;
3891
+ }
3892
+ function xlsxBooleanAttribute(element, name) {
3893
+ const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3894
+ return '1' === value || 'true' === value || 'on' === value;
3895
+ }
3896
+ function work_xlsx_cell_style_origin_isRecord(value) {
3897
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
3898
+ }
3899
+ function hasXlsxDirectFontStyle(cell) {
3900
+ 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);
3901
+ }
3902
+ function directXlsxFontStyle(cell) {
3903
+ const color = void 0 !== cell.fc ? xlsxRgbColor(cell.fc) : null;
3904
+ return {
3905
+ ...void 0 !== cell.bl ? {
3906
+ bold: 1 === Number(cell.bl)
3907
+ } : {},
3908
+ ...color ? {
3909
+ color
3910
+ } : {},
3911
+ ...void 0 !== cell.it ? {
3912
+ italic: 1 === Number(cell.it)
3913
+ } : {},
3914
+ ...'string' == typeof cell.ff && cell.ff.trim() ? {
3915
+ name: cell.ff.trim()
3916
+ } : {},
3917
+ ...'number' == typeof cell.fs && Number.isFinite(cell.fs) && cell.fs > 0 ? {
3918
+ size: cell.fs
3919
+ } : {},
3920
+ ...void 0 !== cell.cl ? {
3921
+ strike: 1 === Number(cell.cl)
3922
+ } : {},
3923
+ ...void 0 !== cell.un ? {
3924
+ underline: spreadsheetUnderlineStyle(cell.un)
3925
+ } : {}
3926
+ };
3927
+ }
3928
+ function directXlsxAlignment(cell) {
3929
+ const alignment = {};
3930
+ if (void 0 !== cell.ht) alignment.horizontal = 0 === Number(cell.ht) ? 'center' : 2 === Number(cell.ht) ? 'right' : 'left';
3931
+ if (void 0 !== cell.vt) alignment.vertical = 0 === Number(cell.vt) ? 'center' : 1 === Number(cell.vt) ? 'top' : 'bottom';
3932
+ if (void 0 !== cell.tb) alignment.wrapText = '2' === cell.tb;
3933
+ const rotation = spreadsheetTextOrientationXlsxValueFromCell(cell);
3934
+ if (null !== rotation) alignment.textRotation = rotation;
3935
+ return Object.keys(alignment).length ? alignment : null;
3876
3936
  }
3877
- function boundedInteger(value, maximum) {
3878
- if (null === value || !/^\d+$/.test(value)) return null;
3879
- const parsed = Number(value);
3880
- return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
3937
+ function xlsxStyleCollectionIndex(collection, childName, value) {
3938
+ const index = work_xlsx_cell_style_values_nonNegativeInteger(value) ?? 0;
3939
+ return directChildren(collection, childName)[index] ? index : 0;
3881
3940
  }
3882
- function work_xlsx_colors_booleanAttribute(element, name) {
3941
+ function xlsxColorMatches(element, value, colors, fallback) {
3942
+ const rgb = xlsxRgbColor(value);
3943
+ const resolved = resolveXlsxColor(element, colors) ?? fallback;
3944
+ return Boolean(rgb && resolved && `#${rgb.slice(-6).toLowerCase()}` === resolved.toLowerCase());
3945
+ }
3946
+ function xlsxToggleEnabled(element) {
3947
+ if (!element) return false;
3948
+ const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
3949
+ return '0' !== value && 'false' !== value && 'off' !== value;
3950
+ }
3951
+ function xlsxUnderlineStyle(element) {
3952
+ return element ? spreadsheetUnderlineStyle(spreadsheetUnderlineCellValueFromXlsx(work_ooxml_package_attribute(element, 'val'))) : 'none';
3953
+ }
3954
+ function xlsxBorderLineMatches(element, line, colors, semanticColor) {
3955
+ const style = element ? work_ooxml_package_attribute(element, 'style') : null;
3956
+ if (!line) return !style;
3957
+ return style === line.style && (semanticColor ? xlsxColorElementMatchesOrigin(element ? directChild(element, 'color') : void 0, semanticColor) : xlsxColorMatches(element ? directChild(element, 'color') : void 0, line.color, colors, '#000000'));
3958
+ }
3959
+ function activeXlsxSemanticColorOrigin(origin, value, palette) {
3960
+ return origin && xlsxSemanticColorMatchesValue(origin, value) && xlsxSemanticColorOriginSupported(origin, palette) ? origin : void 0;
3961
+ }
3962
+ function work_xlsx_cell_style_values_xlsxBooleanAttribute(element, name) {
3963
+ if (!element) return false;
3883
3964
  const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
3884
3965
  return '1' === value || 'true' === value || 'on' === value;
3885
3966
  }
3967
+ function xlsxAlignmentMatches(xf, style) {
3968
+ const alignment = directChild(xf, 'alignment');
3969
+ if (void 0 !== style.horizontal && work_ooxml_package_attribute(alignment ?? xf, 'horizontal') !== style.horizontal) return false;
3970
+ if (void 0 !== style.vertical && work_ooxml_package_attribute(alignment ?? xf, 'vertical') !== style.vertical) return false;
3971
+ if (void 0 !== style.wrapText && (!alignment || null === work_ooxml_package_attribute(alignment, 'wrapText') || work_xlsx_cell_style_values_xlsxBooleanAttribute(alignment, 'wrapText') !== style.wrapText)) return false;
3972
+ if (void 0 !== style.textRotation) {
3973
+ const rotation = work_xlsx_cell_style_values_nonNegativeInteger(alignment ? work_ooxml_package_attribute(alignment, 'textRotation') : null);
3974
+ if (rotation !== style.textRotation) return false;
3975
+ }
3976
+ return true;
3977
+ }
3978
+ function work_xlsx_cell_style_values_nonNegativeInteger(value) {
3979
+ if (null === value || !/^\d+$/.test(value)) return null;
3980
+ const parsed = Number(value);
3981
+ return Number.isSafeInteger(parsed) ? parsed : null;
3982
+ }
3983
+ const fontChildOrder = [
3984
+ 'name',
3985
+ 'charset',
3986
+ 'family',
3987
+ 'b',
3988
+ 'i',
3989
+ 'strike',
3990
+ 'outline',
3991
+ 'shadow',
3992
+ 'condense',
3993
+ 'extend',
3994
+ 'color',
3995
+ 'sz',
3996
+ 'u',
3997
+ 'vertAlign',
3998
+ 'scheme'
3999
+ ];
4000
+ class XlsxDirectCellStyleWriter {
4001
+ styles;
4002
+ semanticPalette;
4003
+ fonts;
4004
+ fills;
4005
+ borders;
4006
+ cellXfs;
4007
+ generatedFonts = new Map();
4008
+ generatedFills = new Map();
4009
+ generatedBorders = new Map();
4010
+ generatedStyles = new Map();
4011
+ colors;
4012
+ changed = false;
4013
+ constructor(styles, theme = null, semanticPalette){
4014
+ this.styles = styles;
4015
+ this.semanticPalette = semanticPalette;
4016
+ this.colors = createXlsxColorResolver(styles, theme);
4017
+ const root = styles.documentElement;
4018
+ this.fonts = ensureXlsxStyleCollection(styles, 'fonts', [
4019
+ 'fills',
4020
+ 'borders',
4021
+ 'cellStyleXfs',
4022
+ 'cellXfs',
4023
+ 'cellStyles',
4024
+ 'dxfs',
4025
+ 'tableStyles',
4026
+ 'colors',
4027
+ 'extLst'
4028
+ ]);
4029
+ if (!directChildren(this.fonts, 'font').length) {
4030
+ this.fonts.append(styles.createElementNS(root.namespaceURI, 'font'));
4031
+ this.changed = true;
4032
+ }
4033
+ this.fills = ensureXlsxStyleCollection(styles, 'fills', [
4034
+ 'borders',
4035
+ 'cellStyleXfs',
4036
+ 'cellXfs',
4037
+ 'cellStyles',
4038
+ 'dxfs',
4039
+ 'tableStyles',
4040
+ 'colors',
4041
+ 'extLst'
4042
+ ]);
4043
+ if (!directChildren(this.fills, 'fill').length) {
4044
+ this.fills.append(defaultXlsxFill(styles, 'none'));
4045
+ this.fills.append(defaultXlsxFill(styles, 'gray125'));
4046
+ this.changed = true;
4047
+ }
4048
+ this.borders = ensureXlsxStyleCollection(styles, 'borders', [
4049
+ 'cellStyleXfs',
4050
+ 'cellXfs',
4051
+ 'cellStyles',
4052
+ 'dxfs',
4053
+ 'tableStyles',
4054
+ 'colors',
4055
+ 'extLst'
4056
+ ]);
4057
+ if (!directChildren(this.borders, 'border').length) {
4058
+ this.borders.append(defaultXlsxBorder(styles));
4059
+ this.changed = true;
4060
+ }
4061
+ this.cellXfs = ensureXlsxStyleCollection(styles, 'cellXfs', [
4062
+ 'cellStyles',
4063
+ 'dxfs',
4064
+ 'tableStyles',
4065
+ 'colors',
4066
+ 'extLst'
4067
+ ]);
4068
+ if (!directChildren(this.cellXfs, 'xf').length) {
4069
+ const base = styles.createElementNS(root.namespaceURI, 'xf');
4070
+ base.setAttribute('numFmtId', '0');
4071
+ base.setAttribute('fontId', '0');
4072
+ base.setAttribute('fillId', '0');
4073
+ base.setAttribute('borderId', '0');
4074
+ base.setAttribute('xfId', '0');
4075
+ this.cellXfs.append(base);
4076
+ this.changed = true;
4077
+ }
4078
+ this.updateCounts();
4079
+ }
4080
+ styleId(baseStyleId, cell, border) {
4081
+ const styles = directChildren(this.cellXfs, 'xf');
4082
+ const baseIndex = Number.isInteger(baseStyleId) && styles[baseStyleId] ? baseStyleId : 0;
4083
+ const base = styles[baseIndex];
4084
+ const baseFontId = xlsxStyleCollectionIndex(this.fonts, 'font', work_ooxml_package_attribute(base, 'fontId'));
4085
+ const baseFillId = xlsxStyleCollectionIndex(this.fills, 'fill', work_ooxml_package_attribute(base, 'fillId'));
4086
+ const baseBorderId = xlsxStyleCollectionIndex(this.borders, 'border', work_ooxml_package_attribute(base, 'borderId'));
4087
+ const origin = xlsxCellStyleOrigin(cell);
4088
+ const fontId = this.fontId(baseFontId, cell, origin?.fontColor);
4089
+ const fillId = this.fillId(baseFillId, cell, origin?.fillColor);
4090
+ const borderId = this.borderId(baseBorderId, border, origin?.borderColors);
4091
+ const alignment = directXlsxAlignment(cell);
4092
+ const alignmentChanged = Boolean(alignment && !xlsxAlignmentMatches(base, alignment));
4093
+ if (fontId === baseFontId && fillId === baseFillId && borderId === baseBorderId && !alignmentChanged) return baseIndex;
4094
+ const key = `${baseIndex}:${fontId}:${fillId}:${borderId}:${alignmentChanged ? JSON.stringify(alignment) : ''}`;
4095
+ const cached = this.generatedStyles.get(key);
4096
+ if (void 0 !== cached) return cached;
4097
+ const clone = base.cloneNode(true);
4098
+ clone.setAttribute('fontId', String(fontId));
4099
+ clone.setAttribute('fillId', String(fillId));
4100
+ clone.setAttribute('borderId', String(borderId));
4101
+ if (fontId !== baseFontId) clone.setAttribute('applyFont', '1');
4102
+ if (fillId !== baseFillId) clone.setAttribute('applyFill', '1');
4103
+ if (borderId !== baseBorderId) clone.setAttribute('applyBorder', '1');
4104
+ if (alignment && alignmentChanged) {
4105
+ writeXlsxAlignment(this.styles, clone, alignment);
4106
+ clone.setAttribute('applyAlignment', '1');
4107
+ }
4108
+ const index = styles.length;
4109
+ this.cellXfs.append(clone);
4110
+ this.generatedStyles.set(key, index);
4111
+ this.changed = true;
4112
+ this.updateCounts();
4113
+ return index;
4114
+ }
4115
+ fontId(baseFontId, cell, colorOrigin) {
4116
+ if (!hasXlsxDirectFontStyle(cell)) return baseFontId;
4117
+ const fonts = directChildren(this.fonts, 'font');
4118
+ const baseIndex = fonts[baseFontId] ? baseFontId : 0;
4119
+ const style = directXlsxFontStyle(cell);
4120
+ const base = fonts[baseIndex];
4121
+ const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, style.color, this.semanticPalette);
4122
+ const nameChanged = void 0 !== style.name && work_ooxml_package_attribute(directChild(base, 'name') ?? base, 'val')?.trim() !== style.name;
4123
+ const sizeChanged = void 0 !== style.size && Number(work_ooxml_package_attribute(directChild(base, 'sz') ?? base, 'val')) !== style.size;
4124
+ const colorChanged = void 0 !== style.color && (semanticColor ? !xlsxColorElementMatchesOrigin(directChild(base, 'color'), semanticColor) : !xlsxColorMatches(directChild(base, 'color'), style.color, this.colors, '#000000'));
4125
+ const boldChanged = void 0 !== style.bold && xlsxToggleEnabled(directChild(base, 'b')) !== style.bold;
4126
+ const italicChanged = void 0 !== style.italic && xlsxToggleEnabled(directChild(base, 'i')) !== style.italic;
4127
+ const strikeChanged = void 0 !== style.strike && xlsxToggleEnabled(directChild(base, 'strike')) !== style.strike;
4128
+ const underlineChanged = void 0 !== style.underline && xlsxUnderlineStyle(directChild(base, 'u')) !== style.underline;
4129
+ if (!nameChanged && !sizeChanged && !colorChanged && !boldChanged && !italicChanged && !strikeChanged && !underlineChanged) return baseIndex;
4130
+ const key = `${baseIndex}:${JSON.stringify(style)}:${xlsxSemanticColorOriginKey(semanticColor)}`;
4131
+ const cached = this.generatedFonts.get(key);
4132
+ if (void 0 !== cached) return cached;
4133
+ const font = base.cloneNode(true);
4134
+ if (nameChanged && void 0 !== style.name) setXlsxValueChild(this.styles, font, 'name', style.name, fontChildOrder);
4135
+ if (sizeChanged && void 0 !== style.size) setXlsxValueChild(this.styles, font, 'sz', String(style.size), fontChildOrder);
4136
+ if (colorChanged && void 0 !== style.color) {
4137
+ setXlsxColorChild(this.styles, font, style.color, fontChildOrder);
4138
+ const color = directChild(font, 'color');
4139
+ if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
4140
+ }
4141
+ if (boldChanged && void 0 !== style.bold) setXlsxToggleChild(this.styles, font, 'b', style.bold, fontChildOrder);
4142
+ if (italicChanged && void 0 !== style.italic) setXlsxToggleChild(this.styles, font, 'i', style.italic, fontChildOrder);
4143
+ if (strikeChanged && void 0 !== style.strike) setXlsxToggleChild(this.styles, font, 'strike', style.strike, fontChildOrder);
4144
+ if (underlineChanged && void 0 !== style.underline) setXlsxUnderlineChild(this.styles, font, style.underline, fontChildOrder);
4145
+ const index = fonts.length;
4146
+ this.fonts.append(font);
4147
+ this.generatedFonts.set(key, index);
4148
+ this.changed = true;
4149
+ this.updateCounts();
4150
+ return index;
4151
+ }
4152
+ fillId(baseFillId, cell, colorOrigin) {
4153
+ if (void 0 === cell.bg) return baseFillId;
4154
+ const color = xlsxRgbColor(cell.bg);
4155
+ if (!color) return baseFillId;
4156
+ const fills = directChildren(this.fills, 'fill');
4157
+ const baseIndex = fills[baseFillId] ? baseFillId : 0;
4158
+ const basePattern = directChild(fills[baseIndex], 'patternFill');
4159
+ const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, color, this.semanticPalette);
4160
+ if ('solid' === work_ooxml_package_attribute(basePattern ?? fills[baseIndex], 'patternType') && (semanticColor ? xlsxColorElementMatchesOrigin(directChild(basePattern ?? fills[baseIndex], 'fgColor'), semanticColor) : xlsxColorMatches(directChild(basePattern ?? fills[baseIndex], 'fgColor'), color, this.colors))) return baseIndex;
4161
+ const key = `${color}:${xlsxSemanticColorOriginKey(semanticColor)}`;
4162
+ const cached = this.generatedFills.get(key);
4163
+ if (void 0 !== cached) return cached;
4164
+ const fill = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fill');
4165
+ const pattern = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'patternFill');
4166
+ pattern.setAttribute('patternType', 'solid');
4167
+ const foreground = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fgColor');
4168
+ foreground.setAttribute('rgb', color);
4169
+ if (semanticColor) applyXlsxSemanticColorOrigin(foreground, semanticColor);
4170
+ const background = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'bgColor');
4171
+ background.setAttribute('indexed', '64');
4172
+ pattern.append(foreground, background);
4173
+ fill.append(pattern);
4174
+ const index = directChildren(this.fills, 'fill').length;
4175
+ this.fills.append(fill);
4176
+ this.generatedFills.set(key, index);
4177
+ this.changed = true;
4178
+ this.updateCounts();
4179
+ return index;
4180
+ }
4181
+ borderId(baseBorderId, update, colorOrigins) {
4182
+ if (!update) return baseBorderId;
4183
+ const borders = directChildren(this.borders, 'border');
4184
+ const baseIndex = borders[baseBorderId] ? baseBorderId : 0;
4185
+ const base = borders[baseIndex];
4186
+ const lineUpdates = [
4187
+ [
4188
+ 'left',
4189
+ update.left
4190
+ ],
4191
+ [
4192
+ 'right',
4193
+ update.right
4194
+ ],
4195
+ [
4196
+ 'top',
4197
+ update.top
4198
+ ],
4199
+ [
4200
+ 'bottom',
4201
+ update.bottom
4202
+ ],
4203
+ [
4204
+ 'diagonal',
4205
+ update.diagonal
4206
+ ]
4207
+ ];
4208
+ const lineChanged = lineUpdates.some(([name, line])=>void 0 !== line && !xlsxBorderLineMatches(directChild(base, name), line, this.colors, line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0));
4209
+ const diagonalUpChanged = void 0 !== update.diagonalUp && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalUp') !== update.diagonalUp;
4210
+ const diagonalDownChanged = void 0 !== update.diagonalDown && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalDown') !== update.diagonalDown;
4211
+ if (!lineChanged && !diagonalUpChanged && !diagonalDownChanged) return baseIndex;
4212
+ const key = `${baseIndex}:${JSON.stringify(update)}:${JSON.stringify(colorOrigins ?? {})}`;
4213
+ const cached = this.generatedBorders.get(key);
4214
+ if (void 0 !== cached) return cached;
4215
+ const border = base.cloneNode(true);
4216
+ for (const [name, line] of lineUpdates)if (void 0 !== line && !xlsxBorderLineMatches(directChild(base, name), line, this.colors, line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0)) {
4217
+ setXlsxBorderLine(this.styles, border, name, line);
4218
+ const semanticColor = line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0;
4219
+ const color = directChild(directChild(border, name) ?? border, 'color');
4220
+ if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
4221
+ }
4222
+ if (diagonalUpChanged && void 0 !== update.diagonalUp) border.setAttribute('diagonalUp', update.diagonalUp ? '1' : '0');
4223
+ if (diagonalDownChanged && void 0 !== update.diagonalDown) border.setAttribute('diagonalDown', update.diagonalDown ? '1' : '0');
4224
+ const index = borders.length;
4225
+ this.borders.append(border);
4226
+ this.generatedBorders.set(key, index);
4227
+ this.changed = true;
4228
+ this.updateCounts();
4229
+ return index;
4230
+ }
4231
+ updateCounts() {
4232
+ this.fonts.setAttribute('count', String(directChildren(this.fonts, 'font').length));
4233
+ this.fills.setAttribute('count', String(directChildren(this.fills, 'fill').length));
4234
+ this.borders.setAttribute('count', String(directChildren(this.borders, 'border').length));
4235
+ this.cellXfs.setAttribute('count', String(directChildren(this.cellXfs, 'xf').length));
4236
+ }
4237
+ }
4238
+ function hasXlsxDirectCellStyle(cell) {
4239
+ return Boolean(hasXlsxDirectFontStyle(cell) || void 0 !== cell.bg || void 0 !== cell.ht || void 0 !== cell.vt || void 0 !== cell.tb || void 0 !== cell.rt || void 0 !== cell.tr);
4240
+ }
3886
4241
  const xlsxCellBorderStyles = new Set([
3887
4242
  'dashDot',
3888
4243
  'dashDotDot',
@@ -3913,10 +4268,12 @@ function readXlsxDirectCellStyles(worksheet, styles, theme = null) {
3913
4268
  if (!coordinate || !xf) return [];
3914
4269
  const style = readDirectCellStyle(xf, fonts, fills, colors);
3915
4270
  const border = readDirectCellBorder(xf, borders, colors);
4271
+ const origin = readDirectCellStyleOrigin(xf, fonts, fills, borders, colors);
3916
4272
  return Object.keys(style).length || border ? [
3917
4273
  {
3918
4274
  ...coordinate,
3919
4275
  border,
4276
+ origin,
3920
4277
  style
3921
4278
  }
3922
4279
  ] : [];
@@ -3961,6 +4318,43 @@ function readDirectCellStyle(xf, fonts, fills, colors) {
3961
4318
  if (alignment) readDirectAlignmentStyle(style, alignment);
3962
4319
  return style;
3963
4320
  }
4321
+ function readDirectCellStyleOrigin(xf, fonts, fills, borders, colors) {
4322
+ const fontId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fontId')) ?? 0;
4323
+ const font = fonts[fontId];
4324
+ const fontColor = font && (0 !== fontId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFont')) ? readXlsxSemanticColorOrigin(directChild(font, 'color'), colors) : void 0;
4325
+ const fillId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fillId')) ?? 0;
4326
+ const fill = fills[fillId];
4327
+ const pattern = fill ? directChild(fill, 'patternFill') : void 0;
4328
+ const fillColor = pattern && 'solid' === work_ooxml_package_attribute(pattern, 'patternType') && (0 !== fillId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFill')) ? readXlsxSemanticColorOrigin(directChild(pattern, 'fgColor'), colors) : void 0;
4329
+ const borderId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'borderId')) ?? 0;
4330
+ const border = borders[borderId];
4331
+ const borderColors = {};
4332
+ if (border && (0 !== borderId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyBorder'))) for (const side of [
4333
+ 'bottom',
4334
+ 'diagonal',
4335
+ 'left',
4336
+ 'right',
4337
+ 'top'
4338
+ ]){
4339
+ const line = directChild(border, side);
4340
+ const lineStyle = line ? work_ooxml_package_attribute(line, 'style') : null;
4341
+ if (!line || !lineStyle || !xlsxCellBorderStyles.has(lineStyle)) continue;
4342
+ const color = readXlsxSemanticColorOrigin(directChild(line, 'color'), colors);
4343
+ if (color) borderColors[side] = color;
4344
+ }
4345
+ if (!fontColor && !fillColor && !Object.keys(borderColors).length) return;
4346
+ return {
4347
+ ...fontColor ? {
4348
+ fontColor
4349
+ } : {},
4350
+ ...fillColor ? {
4351
+ fillColor
4352
+ } : {},
4353
+ ...Object.keys(borderColors).length ? {
4354
+ borderColors
4355
+ } : {}
4356
+ };
4357
+ }
3964
4358
  function readDirectFontStyle(style, font, colors) {
3965
4359
  const bold = directChild(font, 'b');
3966
4360
  if (bold && toggleEnabled(bold)) style.bl = 1;
@@ -6381,8 +6775,10 @@ async function patchXlsxSheetFeatures(buffer, content) {
6381
6775
  const worksheetParts = await work_xlsx_interop_readWorksheetParts(archive);
6382
6776
  const zip = await jszip.loadAsync(buffer);
6383
6777
  const styles = archive.has('xl/styles.xml') ? await archive.xml('xl/styles.xml') : null;
6778
+ const theme = archive.has('xl/theme/theme1.xml') ? await archive.xml('xl/theme/theme1.xml') : null;
6779
+ const semanticPalette = styles ? prepareXlsxSemanticPalette(styles, theme, spreadsheetXlsxStyleOrigins(content)) : void 0;
6384
6780
  const differentialFormats = styles ? new XlsxDifferentialFormatWriter(styles) : void 0;
6385
- const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles) : void 0;
6781
+ const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles, theme, semanticPalette?.palette) : void 0;
6386
6782
  const cellProtection = styles ? new XlsxCellProtectionWriter(styles) : void 0;
6387
6783
  for (const sheet of sheets){
6388
6784
  const pageBreaks = sheet.id ? pageBreaksBySheetId.get(sheet.id) : void 0;
@@ -6402,12 +6798,21 @@ async function patchXlsxSheetFeatures(buffer, content) {
6402
6798
  writeXlsxManualPageBreaks(document1, pageBreaks);
6403
6799
  zip.file(partPath, new XMLSerializer().serializeToString(document1));
6404
6800
  }
6405
- if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
6801
+ if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed || semanticPalette?.stylesChanged)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
6802
+ if (theme && semanticPalette?.themeChanged) zip.file('xl/theme/theme1.xml', new XMLSerializer().serializeToString(theme));
6406
6803
  return zip.generateAsync({
6407
6804
  type: 'arraybuffer',
6408
6805
  compression: 'DEFLATE'
6409
6806
  });
6410
6807
  }
6808
+ function spreadsheetXlsxStyleOrigins(content) {
6809
+ const origins = [];
6810
+ for (const sheet of content.sheets)for (const [, row] of sparseArrayEntries(sheet.data))for (const [, cell] of sparseArrayEntries(row)){
6811
+ const origin = xlsxCellStyleOrigin(cell);
6812
+ if (origin) origins.push(origin);
6813
+ }
6814
+ return origins;
6815
+ }
6411
6816
  async function work_xlsx_interop_readWorksheetParts(archive, workbookDocument) {
6412
6817
  if (!archive.has('xl/workbook.xml')) return new Map();
6413
6818
  const workbook = workbookDocument ?? await archive.xml('xl/workbook.xml');
@@ -8320,7 +8725,7 @@ async function importWorkSpreadsheetFile(file, extension, context) {
8320
8725
  const directCellStyle = directCellStyles.get(spreadsheetCellKey(row, column));
8321
8726
  directCellStyles.delete(spreadsheetCellKey(row, column));
8322
8727
  data[row] ??= [];
8323
- data[row][column] = freezeImportedSpreadsheetCell(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style));
8728
+ data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style), directCellStyle?.origin));
8324
8729
  if (source.f) formulaCells.push({
8325
8730
  column,
8326
8731
  row
@@ -8333,15 +8738,15 @@ async function importWorkSpreadsheetFile(file, extension, context) {
8333
8738
  }
8334
8739
  releaseImportedWorksheetCells(worksheet);
8335
8740
  }
8336
- for (const { column, row, style } of directCellStyles.values()){
8741
+ for (const { column, origin, row, style } of directCellStyles.values()){
8337
8742
  rowCount = Math.max(rowCount, row + 1);
8338
8743
  columnCount = Math.max(columnCount, column + 1);
8339
8744
  data[row] ??= [];
8340
8745
  const existing = data[row][column];
8341
- data[row][column] = freezeImportedSpreadsheetCell({
8746
+ data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin({
8342
8747
  ...existing ?? {},
8343
8748
  ...style
8344
- });
8749
+ }, origin));
8345
8750
  if (!existing) entryIndex += 1;
8346
8751
  }
8347
8752
  populatedCellCount += entryIndex;