@a3s-lab/office 0.19.0 → 0.21.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/README.md +14 -5
- package/dist/0~3635.js +23 -2
- package/dist/0~spreadsheet-editor.js +395 -90
- package/dist/0~work-office-diagnostics.js +1 -1
- package/dist/4104.js +714 -282
- package/dist/{6164.js → 5045.js} +109 -56
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/office-color-picker.d.ts +6 -1
- package/dist/internal/features/work/editors/spreadsheet-cell-border.d.ts +8 -2
- package/dist/internal/features/work/editors/spreadsheet-command-catalog.d.ts +21 -12
- package/dist/internal/features/work/work-spreadsheet-diagonal-border-canvas.d.ts +12 -0
- package/dist/internal/features/work/work-spreadsheet-diagonal-borders.d.ts +13 -0
- package/dist/internal/features/work/work-xlsx-cell-style-origin.d.ts +44 -0
- package/dist/internal/features/work/work-xlsx-cell-style-values.d.ts +26 -0
- package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +4 -1
- package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +2 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +73 -4
- package/package.json +7 -1
package/dist/4104.js
CHANGED
|
@@ -5,7 +5,7 @@ import { OFFICE_COLLABORATION_PROTOCOL as WORK_OFFICE_COLLABORATION_PROTOCOL, Of
|
|
|
5
5
|
import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage as work_ooxml_package_OoxmlPackage, parseXml, firstDescendant, xmlNamespacePrefix, descendants, directChild, createArtifact as createWorkArtifact, xmlContainsAnyElement, createOfficeId as createWorkId, attribute as work_ooxml_package_attribute } from "./5184.js";
|
|
6
6
|
import { mountWorkLiveDocumentCapture, materializeWorkDocumentContent as work_document_model_codec_materializeWorkDocumentContent, documentPageSurfaceGeometryForElement, createWorkDocumentModel, documentContentLayoutProperties, documentModelForContent, createWorkDocumentExtensions, positionWorkLiveDocumentCapture } from "./6282.js";
|
|
7
7
|
import { normalizeWorkSpreadsheetDataLabels, workSpreadsheetChartSupportsGrouping, normalizeSpreadsheetPrintArea, normalizeWorkSpreadsheetChartLegendPosition, formatSpreadsheetCellRanges, spreadsheetCellAddress, normalizeWorkSpreadsheetChartSmoothLines, spreadsheetFormulaRangeForCell, normalizeWorkSpreadsheetChartColor, readXlsxDrawingAnchor, sparseArrayEntries, qualifySpreadsheetRange, normalizeWorkSpreadsheetBubbleScale, normalizeWorkSpreadsheetChartSeriesStyle, normalizeSpreadsheetPrintTitleRows, normalizeSpreadsheetPrintTitleColumns, spreadsheetPivotFilterValueKey, normalizeWorkSpreadsheetErrorBars, normalizeWorkSpreadsheetBubbleSizeRepresents, workSpreadsheetChartSupportsTrendlines, stripSpreadsheetSheetQualifier, normalizeWorkSpreadsheetChartLegendOverlay, normalizeWorkSpreadsheetChartGapWidth, normalizeWorkSpreadsheetChartGrouping, workSpreadsheetChartSupportsBarSpacing, workSpreadsheetChartSupportsSmoothLines, workSpreadsheetChartGroupingIsStacked, xlsxDrawingAnchorToBounds, xlsxTwoCellAnchorMarkers, workSpreadsheetChartSupportsErrorBars, sparseMatrixColumnCount, refreshSpreadsheetPivotTables, normalizeWorkSpreadsheetChartAxisGroup, isValidSpreadsheetDefinedName, normalizeWorkSpreadsheetScatterStyle, workSpreadsheetChartAxisDefaultLabelPosition, spreadsheetPivotValidation, resolveSpreadsheetChart, parseSpreadsheetCellRanges, workSpreadsheetChartAxisIsCategoryAxis, spreadsheetPivotFields, normalizeWorkSpreadsheetDoughnutHoleSize, normalizeWorkSpreadsheetChartAxes, parseSpreadsheetPrintTitles, spreadsheetFormulaRangeConflict, spreadsheetFormulaForXlsx, editableSpreadsheetFormula, workSpreadsheetChartUsesNumericXAxis, normalizeWorkSpreadsheetChartOverlap, workSpreadsheetChartSupportsAxes, workSpreadsheetChartAxisShowsMajorGridlinesByDefault, normalizeWorkSpreadsheetCombinationSeriesType, effectiveSpreadsheetCalculationSettings, normalizeWorkSpreadsheetTrendline, normalizeWorkSpreadsheetRadarStyle } from "./8715.js";
|
|
8
|
-
import {
|
|
8
|
+
import { freezeImportedSpreadsheetCell, normalizeSpreadsheetPaperSize, spreadsheetCellValueWithDiagonalBorder, normalizeSpreadsheetConditionalVisualOptions, spreadsheetTextOrientationXlsxValueFromCell, spreadsheetTextOrientationFromXlsx, isSpreadsheetConditionalComparisonOperator, registerImportedSpreadsheetMatrix, spreadsheetExplicitTextOrientationFromCell, normalizeSpreadsheetDateValidationBoundary, spreadsheetUnderlineStyle, defaultSpreadsheetConditionalIconThresholds, DEFAULT_PROTECTION_HINT, editableRangeRequiresCredentials, spreadsheetTextOrientationCellStyle, normalizeSpreadsheetConditionalIconSetFormat, defaultSpreadsheetDataBarOptions, normalizeSheetProtectionAuthority, importedSheetProtectionAuthority, spreadsheetDateValidationFormula, defaultSpreadsheetColorScaleThresholds, spreadsheetDiagonalBorderFromCellValue, spreadsheetUnderlineCellValueFromXlsx, sheetHasProtectionState, spreadsheetConditionalComparisonNeedsUpperValue, isSpreadsheetConditionalIconSetName, spreadsheetConditionalThresholdsEqual, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetConditionalIconSetCount } from "./5045.js";
|
|
9
9
|
import { WorkFileImportController, materializeWorkFileSource } from "./9356.js";
|
|
10
10
|
import "./2591.js";
|
|
11
11
|
import "./3818.js";
|
|
@@ -3112,7 +3112,19 @@ function fortuneBorderInfoFromXlsxCells(entries) {
|
|
|
3112
3112
|
setFortuneBorderLine(value, 'r', border.right);
|
|
3113
3113
|
setFortuneBorderLine(value, 't', border.top);
|
|
3114
3114
|
setFortuneBorderLine(value, 'b', border.bottom);
|
|
3115
|
-
if (border.diagonal
|
|
3115
|
+
if (border.diagonal && (true === border.diagonalDown || true === border.diagonalUp)) {
|
|
3116
|
+
const line = fortuneBorderLine(border.diagonal);
|
|
3117
|
+
if (line) return [
|
|
3118
|
+
{
|
|
3119
|
+
rangeType: 'cell',
|
|
3120
|
+
value: spreadsheetCellValueWithDiagonalBorder(value, {
|
|
3121
|
+
down: true === border.diagonalDown,
|
|
3122
|
+
line,
|
|
3123
|
+
up: true === border.diagonalUp
|
|
3124
|
+
})
|
|
3125
|
+
}
|
|
3126
|
+
];
|
|
3127
|
+
}
|
|
3116
3128
|
return Object.keys(value).length > 2 ? [
|
|
3117
3129
|
{
|
|
3118
3130
|
rangeType: 'cell',
|
|
@@ -3170,11 +3182,18 @@ function applySpreadsheetCellBorderRecord(record, targets, borders) {
|
|
|
3170
3182
|
applyCellLine(border, 'right', record.value.r);
|
|
3171
3183
|
applyCellLine(border, 'top', record.value.t);
|
|
3172
3184
|
applyCellLine(border, 'bottom', record.value.b);
|
|
3173
|
-
const diagonal =
|
|
3174
|
-
if (void 0 !== diagonal) {
|
|
3175
|
-
|
|
3176
|
-
|
|
3185
|
+
const diagonal = spreadsheetDiagonalBorderFromCellValue(record.value);
|
|
3186
|
+
if (void 0 !== diagonal) if (diagonal) {
|
|
3187
|
+
const line = xlsxCellBorderLineFromFortune(diagonal.line);
|
|
3188
|
+
if (void 0 !== line) {
|
|
3189
|
+
border.diagonal = line;
|
|
3190
|
+
border.diagonalDown = null !== line && diagonal.down;
|
|
3191
|
+
border.diagonalUp = null !== line && diagonal.up;
|
|
3192
|
+
}
|
|
3193
|
+
} else {
|
|
3194
|
+
border.diagonal = null;
|
|
3177
3195
|
border.diagonalDown = false;
|
|
3196
|
+
border.diagonalUp = false;
|
|
3178
3197
|
}
|
|
3179
3198
|
borders.set(key, border);
|
|
3180
3199
|
}
|
|
@@ -3240,9 +3259,10 @@ function applySpreadsheetRangeBorder(borders, target, range, borderType, line) {
|
|
|
3240
3259
|
if (!onRight) border.right = line;
|
|
3241
3260
|
break;
|
|
3242
3261
|
case 'border-slash':
|
|
3243
|
-
border.
|
|
3244
|
-
border.diagonalUp =
|
|
3245
|
-
border.
|
|
3262
|
+
border.diagonalDown = null !== line;
|
|
3263
|
+
border.diagonalUp = true === border.diagonalUp;
|
|
3264
|
+
if (line) border.diagonal = line;
|
|
3265
|
+
else if (!border.diagonalUp) border.diagonal = null;
|
|
3246
3266
|
break;
|
|
3247
3267
|
default:
|
|
3248
3268
|
return;
|
|
@@ -3285,6 +3305,13 @@ function setFortuneBorderLine(target, name, line) {
|
|
|
3285
3305
|
style: fortuneBorderStyle(line.style)
|
|
3286
3306
|
};
|
|
3287
3307
|
}
|
|
3308
|
+
function fortuneBorderLine(line) {
|
|
3309
|
+
const color = normalizeRgbColor(line.color);
|
|
3310
|
+
return color ? {
|
|
3311
|
+
color,
|
|
3312
|
+
style: fortuneBorderStyle(line.style)
|
|
3313
|
+
} : null;
|
|
3314
|
+
}
|
|
3288
3315
|
function normalizeRgbColor(value) {
|
|
3289
3316
|
if ('string' != typeof value) return null;
|
|
3290
3317
|
const color = value.trim().toLowerCase();
|
|
@@ -3410,265 +3437,6 @@ function insertXlsxOrderedChild(parent, child, order) {
|
|
|
3410
3437
|
const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
|
|
3411
3438
|
parent.insertBefore(child, anchor ?? null);
|
|
3412
3439
|
}
|
|
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
3440
|
const defaultThemeColors = [
|
|
3673
3441
|
'ffffff',
|
|
3674
3442
|
'000000',
|
|
@@ -3870,19 +3638,633 @@ function hslToRgb(hue, saturation, lightness) {
|
|
|
3870
3638
|
}
|
|
3871
3639
|
return channels;
|
|
3872
3640
|
}
|
|
3873
|
-
function normalizedHexColor(value) {
|
|
3874
|
-
if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
|
|
3875
|
-
return value.slice(-6).toLowerCase();
|
|
3641
|
+
function normalizedHexColor(value) {
|
|
3642
|
+
if (!value || !/^[0-9a-f]{6,8}$/i.test(value)) return;
|
|
3643
|
+
return value.slice(-6).toLowerCase();
|
|
3644
|
+
}
|
|
3645
|
+
function boundedInteger(value, maximum) {
|
|
3646
|
+
if (null === value || !/^\d+$/.test(value)) return null;
|
|
3647
|
+
const parsed = Number(value);
|
|
3648
|
+
return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
|
|
3649
|
+
}
|
|
3650
|
+
function work_xlsx_colors_booleanAttribute(element, name) {
|
|
3651
|
+
const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
|
|
3652
|
+
return '1' === value || 'true' === value || 'on' === value;
|
|
3653
|
+
}
|
|
3654
|
+
const THEME_COLOR_NAMES = [
|
|
3655
|
+
'lt1',
|
|
3656
|
+
'dk1',
|
|
3657
|
+
'lt2',
|
|
3658
|
+
'dk2',
|
|
3659
|
+
'accent1',
|
|
3660
|
+
'accent2',
|
|
3661
|
+
'accent3',
|
|
3662
|
+
'accent4',
|
|
3663
|
+
'accent5',
|
|
3664
|
+
'accent6',
|
|
3665
|
+
'hlink',
|
|
3666
|
+
'folHlink'
|
|
3667
|
+
];
|
|
3668
|
+
const MAX_INDEXED_COLOR = 255;
|
|
3669
|
+
function readXlsxSemanticColorOrigin(element, colors) {
|
|
3670
|
+
if (!element || work_ooxml_package_attribute(element, 'rgb')) return;
|
|
3671
|
+
const renderedColor = resolveXlsxColor(element, colors);
|
|
3672
|
+
if (!renderedColor) return;
|
|
3673
|
+
const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
|
|
3674
|
+
const theme = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'theme'), THEME_COLOR_NAMES.length - 1);
|
|
3675
|
+
if (null !== theme && colors.theme[theme]) return {
|
|
3676
|
+
kind: 'theme',
|
|
3677
|
+
baseColor: `#${colors.theme[theme]}`,
|
|
3678
|
+
index: theme,
|
|
3679
|
+
renderedColor,
|
|
3680
|
+
...null === tint ? {} : {
|
|
3681
|
+
tint
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
const indexed = work_xlsx_cell_style_origin_boundedInteger(work_ooxml_package_attribute(element, 'indexed'), MAX_INDEXED_COLOR);
|
|
3685
|
+
if (null !== indexed && colors.indexed[indexed]) return {
|
|
3686
|
+
kind: 'indexed',
|
|
3687
|
+
baseColor: `#${colors.indexed[indexed]}`,
|
|
3688
|
+
index: indexed,
|
|
3689
|
+
renderedColor,
|
|
3690
|
+
...null === tint ? {} : {
|
|
3691
|
+
tint
|
|
3692
|
+
}
|
|
3693
|
+
};
|
|
3694
|
+
if (xlsxBooleanAttribute(element, 'auto')) return {
|
|
3695
|
+
kind: 'automatic',
|
|
3696
|
+
baseColor: '#000000',
|
|
3697
|
+
renderedColor,
|
|
3698
|
+
...null === tint ? {} : {
|
|
3699
|
+
tint
|
|
3700
|
+
}
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3703
|
+
function withXlsxCellStyleOrigin(cell, origin) {
|
|
3704
|
+
return origin && xlsxCellStyleOriginHasValues(origin) ? {
|
|
3705
|
+
...cell,
|
|
3706
|
+
a3sXlsxStyleOrigin: origin
|
|
3707
|
+
} : cell;
|
|
3708
|
+
}
|
|
3709
|
+
function xlsxCellStyleOrigin(cell) {
|
|
3710
|
+
const candidate = cell?.a3sXlsxStyleOrigin;
|
|
3711
|
+
if (!work_xlsx_cell_style_origin_isRecord(candidate)) return;
|
|
3712
|
+
const fontColor = normalizedXlsxSemanticColor(candidate.fontColor);
|
|
3713
|
+
const fillColor = normalizedXlsxSemanticColor(candidate.fillColor);
|
|
3714
|
+
const borderColors = normalizedBorderColors(candidate.borderColors);
|
|
3715
|
+
const origin = {
|
|
3716
|
+
...fontColor ? {
|
|
3717
|
+
fontColor
|
|
3718
|
+
} : {},
|
|
3719
|
+
...fillColor ? {
|
|
3720
|
+
fillColor
|
|
3721
|
+
} : {},
|
|
3722
|
+
...borderColors ? {
|
|
3723
|
+
borderColors
|
|
3724
|
+
} : {}
|
|
3725
|
+
};
|
|
3726
|
+
return xlsxCellStyleOriginHasValues(origin) ? origin : void 0;
|
|
3727
|
+
}
|
|
3728
|
+
function xlsxSemanticColorMatchesValue(origin, value) {
|
|
3729
|
+
return normalizedColor(value) === origin.renderedColor.toLowerCase();
|
|
3730
|
+
}
|
|
3731
|
+
function xlsxColorElementMatchesOrigin(element, origin) {
|
|
3732
|
+
if (!element || work_ooxml_package_attribute(element, 'rgb')) return false;
|
|
3733
|
+
if ('theme' === origin.kind) {
|
|
3734
|
+
if (work_ooxml_package_attribute(element, 'theme') !== String(origin.index)) return false;
|
|
3735
|
+
} else if ('indexed' === origin.kind) {
|
|
3736
|
+
if (work_ooxml_package_attribute(element, 'indexed') !== String(origin.index)) return false;
|
|
3737
|
+
} else if (!xlsxBooleanAttribute(element, 'auto')) return false;
|
|
3738
|
+
const tint = boundedTint(work_ooxml_package_attribute(element, 'tint'));
|
|
3739
|
+
return tint === (origin.tint ?? null);
|
|
3740
|
+
}
|
|
3741
|
+
function applyXlsxSemanticColorOrigin(element, origin) {
|
|
3742
|
+
for (const name of [
|
|
3743
|
+
'rgb',
|
|
3744
|
+
'theme',
|
|
3745
|
+
'indexed',
|
|
3746
|
+
'auto',
|
|
3747
|
+
'tint'
|
|
3748
|
+
])element.removeAttribute(name);
|
|
3749
|
+
if ('theme' === origin.kind) element.setAttribute('theme', String(origin.index));
|
|
3750
|
+
else if ('indexed' === origin.kind) element.setAttribute('indexed', String(origin.index));
|
|
3751
|
+
else element.setAttribute('auto', '1');
|
|
3752
|
+
if (void 0 !== origin.tint) element.setAttribute('tint', String(origin.tint));
|
|
3753
|
+
}
|
|
3754
|
+
function xlsxSemanticColorOriginKey(origin) {
|
|
3755
|
+
return origin ? `${origin.kind}:${'index' in origin ? origin.index : ''}:${origin.baseColor}:${origin.renderedColor}:${origin.tint ?? ''}` : '';
|
|
3756
|
+
}
|
|
3757
|
+
function xlsxSemanticColorOriginSupported(origin, palette) {
|
|
3758
|
+
if ('automatic' === origin.kind) return true;
|
|
3759
|
+
return palette?.[origin.kind].get(origin.index)?.toLowerCase() === origin.baseColor.toLowerCase();
|
|
3760
|
+
}
|
|
3761
|
+
function prepareXlsxSemanticPalette(styles, theme, origins) {
|
|
3762
|
+
const candidates = semanticPaletteCandidates(origins);
|
|
3763
|
+
const supportedTheme = new Map();
|
|
3764
|
+
let themeChanged = false;
|
|
3765
|
+
const scheme = theme ? firstDescendant(theme, 'clrScheme') : void 0;
|
|
3766
|
+
for (const [index, color] of candidates.theme){
|
|
3767
|
+
const name = THEME_COLOR_NAMES[index];
|
|
3768
|
+
const entry = name && scheme ? directChild(scheme, name) : void 0;
|
|
3769
|
+
if (entry) {
|
|
3770
|
+
themeChanged = writeThemeColor(entry, color) || themeChanged;
|
|
3771
|
+
supportedTheme.set(index, color);
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
const supportedIndexed = new Map();
|
|
3775
|
+
let stylesChanged = false;
|
|
3776
|
+
if (candidates.indexed.size) {
|
|
3777
|
+
const colors = ensureXlsxStyleCollection(styles, 'colors', [
|
|
3778
|
+
'extLst'
|
|
3779
|
+
]);
|
|
3780
|
+
let indexedColors = directChild(colors, 'indexedColors');
|
|
3781
|
+
if (!indexedColors) {
|
|
3782
|
+
indexedColors = styles.createElementNS(styles.documentElement.namespaceURI, 'indexedColors');
|
|
3783
|
+
colors.prepend(indexedColors);
|
|
3784
|
+
stylesChanged = true;
|
|
3785
|
+
}
|
|
3786
|
+
const resolver = createXlsxColorResolver(styles, theme);
|
|
3787
|
+
const highestIndex = Math.max(...candidates.indexed.keys());
|
|
3788
|
+
while(directChildren(indexedColors, 'rgbColor').length <= highestIndex){
|
|
3789
|
+
const index = directChildren(indexedColors, 'rgbColor').length;
|
|
3790
|
+
const element = styles.createElementNS(styles.documentElement.namespaceURI, 'rgbColor');
|
|
3791
|
+
element.setAttribute('rgb', `FF${(resolver.indexed[index] ?? '000000').toUpperCase()}`);
|
|
3792
|
+
indexedColors.append(element);
|
|
3793
|
+
stylesChanged = true;
|
|
3794
|
+
}
|
|
3795
|
+
const entries = directChildren(indexedColors, 'rgbColor');
|
|
3796
|
+
for (const [index, color] of candidates.indexed){
|
|
3797
|
+
const expected = `FF${color.slice(1).toUpperCase()}`;
|
|
3798
|
+
const entry = entries[index];
|
|
3799
|
+
if (entry) {
|
|
3800
|
+
if (work_ooxml_package_attribute(entry, 'rgb')?.toUpperCase() !== expected) {
|
|
3801
|
+
entry.setAttribute('rgb', expected);
|
|
3802
|
+
stylesChanged = true;
|
|
3803
|
+
}
|
|
3804
|
+
supportedIndexed.set(index, color);
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3808
|
+
return {
|
|
3809
|
+
palette: {
|
|
3810
|
+
indexed: supportedIndexed,
|
|
3811
|
+
theme: supportedTheme
|
|
3812
|
+
},
|
|
3813
|
+
stylesChanged,
|
|
3814
|
+
themeChanged
|
|
3815
|
+
};
|
|
3816
|
+
}
|
|
3817
|
+
function semanticPaletteCandidates(origins) {
|
|
3818
|
+
const theme = new Map();
|
|
3819
|
+
const indexed = new Map();
|
|
3820
|
+
const themeConflicts = new Set();
|
|
3821
|
+
const indexedConflicts = new Set();
|
|
3822
|
+
for (const origin of origins)for (const color of xlsxCellStyleOriginColors(origin)){
|
|
3823
|
+
if ('automatic' === color.kind) continue;
|
|
3824
|
+
const target = 'theme' === color.kind ? theme : indexed;
|
|
3825
|
+
const conflicts = 'theme' === color.kind ? themeConflicts : indexedConflicts;
|
|
3826
|
+
const current = target.get(color.index);
|
|
3827
|
+
if (current && current.toLowerCase() !== color.baseColor.toLowerCase()) conflicts.add(color.index);
|
|
3828
|
+
else if (!current) target.set(color.index, color.baseColor);
|
|
3829
|
+
}
|
|
3830
|
+
for (const index of themeConflicts)theme.delete(index);
|
|
3831
|
+
for (const index of indexedConflicts)indexed.delete(index);
|
|
3832
|
+
return {
|
|
3833
|
+
indexed,
|
|
3834
|
+
theme
|
|
3835
|
+
};
|
|
3836
|
+
}
|
|
3837
|
+
function xlsxCellStyleOriginColors(origin) {
|
|
3838
|
+
return [
|
|
3839
|
+
origin.fontColor,
|
|
3840
|
+
origin.fillColor,
|
|
3841
|
+
...Object.values(origin.borderColors ?? {})
|
|
3842
|
+
].filter((value)=>Boolean(value));
|
|
3843
|
+
}
|
|
3844
|
+
function writeThemeColor(entry, color) {
|
|
3845
|
+
const current = directChildren(entry)[0];
|
|
3846
|
+
if (current?.localName === 'srgbClr' && work_ooxml_package_attribute(current, 'val')?.toLowerCase() === color.slice(1).toLowerCase()) return false;
|
|
3847
|
+
for (const child of directChildren(entry))child.remove();
|
|
3848
|
+
const qualifiedName = entry.prefix ? `${entry.prefix}:srgbClr` : 'srgbClr';
|
|
3849
|
+
const replacement = entry.ownerDocument.createElementNS(entry.namespaceURI, qualifiedName);
|
|
3850
|
+
replacement.setAttribute('val', color.slice(1).toUpperCase());
|
|
3851
|
+
entry.append(replacement);
|
|
3852
|
+
return true;
|
|
3853
|
+
}
|
|
3854
|
+
function normalizedBorderColors(value) {
|
|
3855
|
+
if (!work_xlsx_cell_style_origin_isRecord(value)) return;
|
|
3856
|
+
const result = {};
|
|
3857
|
+
for (const side of [
|
|
3858
|
+
'bottom',
|
|
3859
|
+
'diagonal',
|
|
3860
|
+
'left',
|
|
3861
|
+
'right',
|
|
3862
|
+
'top'
|
|
3863
|
+
]){
|
|
3864
|
+
const color = normalizedXlsxSemanticColor(value[side]);
|
|
3865
|
+
if (color) result[side] = color;
|
|
3866
|
+
}
|
|
3867
|
+
return Object.keys(result).length ? result : void 0;
|
|
3868
|
+
}
|
|
3869
|
+
function normalizedXlsxSemanticColor(value) {
|
|
3870
|
+
if (!work_xlsx_cell_style_origin_isRecord(value)) return;
|
|
3871
|
+
const baseColor = normalizedColor(value.baseColor);
|
|
3872
|
+
const renderedColor = normalizedColor(value.renderedColor);
|
|
3873
|
+
const tint = normalizedTint(value.tint);
|
|
3874
|
+
if (!baseColor || !renderedColor || void 0 === tint) return;
|
|
3875
|
+
if ('automatic' === value.kind) return {
|
|
3876
|
+
kind: 'automatic',
|
|
3877
|
+
baseColor,
|
|
3878
|
+
renderedColor,
|
|
3879
|
+
...null === tint ? {} : {
|
|
3880
|
+
tint
|
|
3881
|
+
}
|
|
3882
|
+
};
|
|
3883
|
+
const maximum = 'theme' === value.kind ? THEME_COLOR_NAMES.length - 1 : MAX_INDEXED_COLOR;
|
|
3884
|
+
const index = boundedNumber(value.index, maximum);
|
|
3885
|
+
if ('theme' !== value.kind && 'indexed' !== value.kind || null === index) return;
|
|
3886
|
+
return {
|
|
3887
|
+
kind: value.kind,
|
|
3888
|
+
baseColor,
|
|
3889
|
+
index,
|
|
3890
|
+
renderedColor,
|
|
3891
|
+
...null === tint ? {} : {
|
|
3892
|
+
tint
|
|
3893
|
+
}
|
|
3894
|
+
};
|
|
3895
|
+
}
|
|
3896
|
+
function xlsxCellStyleOriginHasValues(origin) {
|
|
3897
|
+
return Boolean(origin.fontColor || origin.fillColor || Object.keys(origin.borderColors ?? {}).length);
|
|
3898
|
+
}
|
|
3899
|
+
function normalizedColor(value) {
|
|
3900
|
+
const rgb = xlsxRgbColor(value);
|
|
3901
|
+
return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
|
|
3902
|
+
}
|
|
3903
|
+
function normalizedTint(value) {
|
|
3904
|
+
if (void 0 === value) return null;
|
|
3905
|
+
return 'number' == typeof value && Number.isFinite(value) && value >= -1 && value <= 1 ? value : void 0;
|
|
3906
|
+
}
|
|
3907
|
+
function boundedTint(value) {
|
|
3908
|
+
if (null === value) return null;
|
|
3909
|
+
const tint = Number(value);
|
|
3910
|
+
return Number.isFinite(tint) && tint >= -1 && tint <= 1 ? tint : null;
|
|
3911
|
+
}
|
|
3912
|
+
function work_xlsx_cell_style_origin_boundedInteger(value, maximum) {
|
|
3913
|
+
if (null === value || !/^\d+$/.test(value)) return null;
|
|
3914
|
+
return boundedNumber(Number(value), maximum);
|
|
3915
|
+
}
|
|
3916
|
+
function boundedNumber(value, maximum) {
|
|
3917
|
+
return 'number' == typeof value && Number.isSafeInteger(value) && value >= 0 && value <= maximum ? value : null;
|
|
3918
|
+
}
|
|
3919
|
+
function xlsxBooleanAttribute(element, name) {
|
|
3920
|
+
const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
|
|
3921
|
+
return '1' === value || 'true' === value || 'on' === value;
|
|
3922
|
+
}
|
|
3923
|
+
function work_xlsx_cell_style_origin_isRecord(value) {
|
|
3924
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
3925
|
+
}
|
|
3926
|
+
function hasXlsxDirectFontStyle(cell) {
|
|
3927
|
+
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);
|
|
3928
|
+
}
|
|
3929
|
+
function directXlsxFontStyle(cell) {
|
|
3930
|
+
const color = void 0 !== cell.fc ? xlsxRgbColor(cell.fc) : null;
|
|
3931
|
+
return {
|
|
3932
|
+
...void 0 !== cell.bl ? {
|
|
3933
|
+
bold: 1 === Number(cell.bl)
|
|
3934
|
+
} : {},
|
|
3935
|
+
...color ? {
|
|
3936
|
+
color
|
|
3937
|
+
} : {},
|
|
3938
|
+
...void 0 !== cell.it ? {
|
|
3939
|
+
italic: 1 === Number(cell.it)
|
|
3940
|
+
} : {},
|
|
3941
|
+
...'string' == typeof cell.ff && cell.ff.trim() ? {
|
|
3942
|
+
name: cell.ff.trim()
|
|
3943
|
+
} : {},
|
|
3944
|
+
...'number' == typeof cell.fs && Number.isFinite(cell.fs) && cell.fs > 0 ? {
|
|
3945
|
+
size: cell.fs
|
|
3946
|
+
} : {},
|
|
3947
|
+
...void 0 !== cell.cl ? {
|
|
3948
|
+
strike: 1 === Number(cell.cl)
|
|
3949
|
+
} : {},
|
|
3950
|
+
...void 0 !== cell.un ? {
|
|
3951
|
+
underline: spreadsheetUnderlineStyle(cell.un)
|
|
3952
|
+
} : {}
|
|
3953
|
+
};
|
|
3954
|
+
}
|
|
3955
|
+
function directXlsxAlignment(cell) {
|
|
3956
|
+
const alignment = {};
|
|
3957
|
+
if (void 0 !== cell.ht) alignment.horizontal = 0 === Number(cell.ht) ? 'center' : 2 === Number(cell.ht) ? 'right' : 'left';
|
|
3958
|
+
if (void 0 !== cell.vt) alignment.vertical = 0 === Number(cell.vt) ? 'center' : 1 === Number(cell.vt) ? 'top' : 'bottom';
|
|
3959
|
+
if (void 0 !== cell.tb) alignment.wrapText = '2' === cell.tb;
|
|
3960
|
+
const rotation = spreadsheetTextOrientationXlsxValueFromCell(cell);
|
|
3961
|
+
if (null !== rotation) alignment.textRotation = rotation;
|
|
3962
|
+
return Object.keys(alignment).length ? alignment : null;
|
|
3876
3963
|
}
|
|
3877
|
-
function
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
return Number.isSafeInteger(parsed) && parsed <= maximum ? parsed : null;
|
|
3964
|
+
function xlsxStyleCollectionIndex(collection, childName, value) {
|
|
3965
|
+
const index = work_xlsx_cell_style_values_nonNegativeInteger(value) ?? 0;
|
|
3966
|
+
return directChildren(collection, childName)[index] ? index : 0;
|
|
3881
3967
|
}
|
|
3882
|
-
function
|
|
3968
|
+
function xlsxColorMatches(element, value, colors, fallback) {
|
|
3969
|
+
const rgb = xlsxRgbColor(value);
|
|
3970
|
+
const resolved = resolveXlsxColor(element, colors) ?? fallback;
|
|
3971
|
+
return Boolean(rgb && resolved && `#${rgb.slice(-6).toLowerCase()}` === resolved.toLowerCase());
|
|
3972
|
+
}
|
|
3973
|
+
function xlsxToggleEnabled(element) {
|
|
3974
|
+
if (!element) return false;
|
|
3975
|
+
const value = work_ooxml_package_attribute(element, 'val')?.trim().toLowerCase();
|
|
3976
|
+
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
3977
|
+
}
|
|
3978
|
+
function xlsxUnderlineStyle(element) {
|
|
3979
|
+
return element ? spreadsheetUnderlineStyle(spreadsheetUnderlineCellValueFromXlsx(work_ooxml_package_attribute(element, 'val'))) : 'none';
|
|
3980
|
+
}
|
|
3981
|
+
function xlsxBorderLineMatches(element, line, colors, semanticColor) {
|
|
3982
|
+
const style = element ? work_ooxml_package_attribute(element, 'style') : null;
|
|
3983
|
+
if (!line) return !style;
|
|
3984
|
+
return style === line.style && (semanticColor ? xlsxColorElementMatchesOrigin(element ? directChild(element, 'color') : void 0, semanticColor) : xlsxColorMatches(element ? directChild(element, 'color') : void 0, line.color, colors, '#000000'));
|
|
3985
|
+
}
|
|
3986
|
+
function activeXlsxSemanticColorOrigin(origin, value, palette) {
|
|
3987
|
+
return origin && xlsxSemanticColorMatchesValue(origin, value) && xlsxSemanticColorOriginSupported(origin, palette) ? origin : void 0;
|
|
3988
|
+
}
|
|
3989
|
+
function work_xlsx_cell_style_values_xlsxBooleanAttribute(element, name) {
|
|
3990
|
+
if (!element) return false;
|
|
3883
3991
|
const value = work_ooxml_package_attribute(element, name)?.trim().toLowerCase();
|
|
3884
3992
|
return '1' === value || 'true' === value || 'on' === value;
|
|
3885
3993
|
}
|
|
3994
|
+
function xlsxAlignmentMatches(xf, style) {
|
|
3995
|
+
const alignment = directChild(xf, 'alignment');
|
|
3996
|
+
if (void 0 !== style.horizontal && work_ooxml_package_attribute(alignment ?? xf, 'horizontal') !== style.horizontal) return false;
|
|
3997
|
+
if (void 0 !== style.vertical && work_ooxml_package_attribute(alignment ?? xf, 'vertical') !== style.vertical) return false;
|
|
3998
|
+
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;
|
|
3999
|
+
if (void 0 !== style.textRotation) {
|
|
4000
|
+
const rotation = work_xlsx_cell_style_values_nonNegativeInteger(alignment ? work_ooxml_package_attribute(alignment, 'textRotation') : null);
|
|
4001
|
+
if (rotation !== style.textRotation) return false;
|
|
4002
|
+
}
|
|
4003
|
+
return true;
|
|
4004
|
+
}
|
|
4005
|
+
function work_xlsx_cell_style_values_nonNegativeInteger(value) {
|
|
4006
|
+
if (null === value || !/^\d+$/.test(value)) return null;
|
|
4007
|
+
const parsed = Number(value);
|
|
4008
|
+
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
4009
|
+
}
|
|
4010
|
+
const fontChildOrder = [
|
|
4011
|
+
'name',
|
|
4012
|
+
'charset',
|
|
4013
|
+
'family',
|
|
4014
|
+
'b',
|
|
4015
|
+
'i',
|
|
4016
|
+
'strike',
|
|
4017
|
+
'outline',
|
|
4018
|
+
'shadow',
|
|
4019
|
+
'condense',
|
|
4020
|
+
'extend',
|
|
4021
|
+
'color',
|
|
4022
|
+
'sz',
|
|
4023
|
+
'u',
|
|
4024
|
+
'vertAlign',
|
|
4025
|
+
'scheme'
|
|
4026
|
+
];
|
|
4027
|
+
class XlsxDirectCellStyleWriter {
|
|
4028
|
+
styles;
|
|
4029
|
+
semanticPalette;
|
|
4030
|
+
fonts;
|
|
4031
|
+
fills;
|
|
4032
|
+
borders;
|
|
4033
|
+
cellXfs;
|
|
4034
|
+
generatedFonts = new Map();
|
|
4035
|
+
generatedFills = new Map();
|
|
4036
|
+
generatedBorders = new Map();
|
|
4037
|
+
generatedStyles = new Map();
|
|
4038
|
+
colors;
|
|
4039
|
+
changed = false;
|
|
4040
|
+
constructor(styles, theme = null, semanticPalette){
|
|
4041
|
+
this.styles = styles;
|
|
4042
|
+
this.semanticPalette = semanticPalette;
|
|
4043
|
+
this.colors = createXlsxColorResolver(styles, theme);
|
|
4044
|
+
const root = styles.documentElement;
|
|
4045
|
+
this.fonts = ensureXlsxStyleCollection(styles, 'fonts', [
|
|
4046
|
+
'fills',
|
|
4047
|
+
'borders',
|
|
4048
|
+
'cellStyleXfs',
|
|
4049
|
+
'cellXfs',
|
|
4050
|
+
'cellStyles',
|
|
4051
|
+
'dxfs',
|
|
4052
|
+
'tableStyles',
|
|
4053
|
+
'colors',
|
|
4054
|
+
'extLst'
|
|
4055
|
+
]);
|
|
4056
|
+
if (!directChildren(this.fonts, 'font').length) {
|
|
4057
|
+
this.fonts.append(styles.createElementNS(root.namespaceURI, 'font'));
|
|
4058
|
+
this.changed = true;
|
|
4059
|
+
}
|
|
4060
|
+
this.fills = ensureXlsxStyleCollection(styles, 'fills', [
|
|
4061
|
+
'borders',
|
|
4062
|
+
'cellStyleXfs',
|
|
4063
|
+
'cellXfs',
|
|
4064
|
+
'cellStyles',
|
|
4065
|
+
'dxfs',
|
|
4066
|
+
'tableStyles',
|
|
4067
|
+
'colors',
|
|
4068
|
+
'extLst'
|
|
4069
|
+
]);
|
|
4070
|
+
if (!directChildren(this.fills, 'fill').length) {
|
|
4071
|
+
this.fills.append(defaultXlsxFill(styles, 'none'));
|
|
4072
|
+
this.fills.append(defaultXlsxFill(styles, 'gray125'));
|
|
4073
|
+
this.changed = true;
|
|
4074
|
+
}
|
|
4075
|
+
this.borders = ensureXlsxStyleCollection(styles, 'borders', [
|
|
4076
|
+
'cellStyleXfs',
|
|
4077
|
+
'cellXfs',
|
|
4078
|
+
'cellStyles',
|
|
4079
|
+
'dxfs',
|
|
4080
|
+
'tableStyles',
|
|
4081
|
+
'colors',
|
|
4082
|
+
'extLst'
|
|
4083
|
+
]);
|
|
4084
|
+
if (!directChildren(this.borders, 'border').length) {
|
|
4085
|
+
this.borders.append(defaultXlsxBorder(styles));
|
|
4086
|
+
this.changed = true;
|
|
4087
|
+
}
|
|
4088
|
+
this.cellXfs = ensureXlsxStyleCollection(styles, 'cellXfs', [
|
|
4089
|
+
'cellStyles',
|
|
4090
|
+
'dxfs',
|
|
4091
|
+
'tableStyles',
|
|
4092
|
+
'colors',
|
|
4093
|
+
'extLst'
|
|
4094
|
+
]);
|
|
4095
|
+
if (!directChildren(this.cellXfs, 'xf').length) {
|
|
4096
|
+
const base = styles.createElementNS(root.namespaceURI, 'xf');
|
|
4097
|
+
base.setAttribute('numFmtId', '0');
|
|
4098
|
+
base.setAttribute('fontId', '0');
|
|
4099
|
+
base.setAttribute('fillId', '0');
|
|
4100
|
+
base.setAttribute('borderId', '0');
|
|
4101
|
+
base.setAttribute('xfId', '0');
|
|
4102
|
+
this.cellXfs.append(base);
|
|
4103
|
+
this.changed = true;
|
|
4104
|
+
}
|
|
4105
|
+
this.updateCounts();
|
|
4106
|
+
}
|
|
4107
|
+
styleId(baseStyleId, cell, border) {
|
|
4108
|
+
const styles = directChildren(this.cellXfs, 'xf');
|
|
4109
|
+
const baseIndex = Number.isInteger(baseStyleId) && styles[baseStyleId] ? baseStyleId : 0;
|
|
4110
|
+
const base = styles[baseIndex];
|
|
4111
|
+
const baseFontId = xlsxStyleCollectionIndex(this.fonts, 'font', work_ooxml_package_attribute(base, 'fontId'));
|
|
4112
|
+
const baseFillId = xlsxStyleCollectionIndex(this.fills, 'fill', work_ooxml_package_attribute(base, 'fillId'));
|
|
4113
|
+
const baseBorderId = xlsxStyleCollectionIndex(this.borders, 'border', work_ooxml_package_attribute(base, 'borderId'));
|
|
4114
|
+
const origin = xlsxCellStyleOrigin(cell);
|
|
4115
|
+
const fontId = this.fontId(baseFontId, cell, origin?.fontColor);
|
|
4116
|
+
const fillId = this.fillId(baseFillId, cell, origin?.fillColor);
|
|
4117
|
+
const borderId = this.borderId(baseBorderId, border, origin?.borderColors);
|
|
4118
|
+
const alignment = directXlsxAlignment(cell);
|
|
4119
|
+
const alignmentChanged = Boolean(alignment && !xlsxAlignmentMatches(base, alignment));
|
|
4120
|
+
if (fontId === baseFontId && fillId === baseFillId && borderId === baseBorderId && !alignmentChanged) return baseIndex;
|
|
4121
|
+
const key = `${baseIndex}:${fontId}:${fillId}:${borderId}:${alignmentChanged ? JSON.stringify(alignment) : ''}`;
|
|
4122
|
+
const cached = this.generatedStyles.get(key);
|
|
4123
|
+
if (void 0 !== cached) return cached;
|
|
4124
|
+
const clone = base.cloneNode(true);
|
|
4125
|
+
clone.setAttribute('fontId', String(fontId));
|
|
4126
|
+
clone.setAttribute('fillId', String(fillId));
|
|
4127
|
+
clone.setAttribute('borderId', String(borderId));
|
|
4128
|
+
if (fontId !== baseFontId) clone.setAttribute('applyFont', '1');
|
|
4129
|
+
if (fillId !== baseFillId) clone.setAttribute('applyFill', '1');
|
|
4130
|
+
if (borderId !== baseBorderId) clone.setAttribute('applyBorder', '1');
|
|
4131
|
+
if (alignment && alignmentChanged) {
|
|
4132
|
+
writeXlsxAlignment(this.styles, clone, alignment);
|
|
4133
|
+
clone.setAttribute('applyAlignment', '1');
|
|
4134
|
+
}
|
|
4135
|
+
const index = styles.length;
|
|
4136
|
+
this.cellXfs.append(clone);
|
|
4137
|
+
this.generatedStyles.set(key, index);
|
|
4138
|
+
this.changed = true;
|
|
4139
|
+
this.updateCounts();
|
|
4140
|
+
return index;
|
|
4141
|
+
}
|
|
4142
|
+
fontId(baseFontId, cell, colorOrigin) {
|
|
4143
|
+
if (!hasXlsxDirectFontStyle(cell)) return baseFontId;
|
|
4144
|
+
const fonts = directChildren(this.fonts, 'font');
|
|
4145
|
+
const baseIndex = fonts[baseFontId] ? baseFontId : 0;
|
|
4146
|
+
const style = directXlsxFontStyle(cell);
|
|
4147
|
+
const base = fonts[baseIndex];
|
|
4148
|
+
const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, style.color, this.semanticPalette);
|
|
4149
|
+
const nameChanged = void 0 !== style.name && work_ooxml_package_attribute(directChild(base, 'name') ?? base, 'val')?.trim() !== style.name;
|
|
4150
|
+
const sizeChanged = void 0 !== style.size && Number(work_ooxml_package_attribute(directChild(base, 'sz') ?? base, 'val')) !== style.size;
|
|
4151
|
+
const colorChanged = void 0 !== style.color && (semanticColor ? !xlsxColorElementMatchesOrigin(directChild(base, 'color'), semanticColor) : !xlsxColorMatches(directChild(base, 'color'), style.color, this.colors, '#000000'));
|
|
4152
|
+
const boldChanged = void 0 !== style.bold && xlsxToggleEnabled(directChild(base, 'b')) !== style.bold;
|
|
4153
|
+
const italicChanged = void 0 !== style.italic && xlsxToggleEnabled(directChild(base, 'i')) !== style.italic;
|
|
4154
|
+
const strikeChanged = void 0 !== style.strike && xlsxToggleEnabled(directChild(base, 'strike')) !== style.strike;
|
|
4155
|
+
const underlineChanged = void 0 !== style.underline && xlsxUnderlineStyle(directChild(base, 'u')) !== style.underline;
|
|
4156
|
+
if (!nameChanged && !sizeChanged && !colorChanged && !boldChanged && !italicChanged && !strikeChanged && !underlineChanged) return baseIndex;
|
|
4157
|
+
const key = `${baseIndex}:${JSON.stringify(style)}:${xlsxSemanticColorOriginKey(semanticColor)}`;
|
|
4158
|
+
const cached = this.generatedFonts.get(key);
|
|
4159
|
+
if (void 0 !== cached) return cached;
|
|
4160
|
+
const font = base.cloneNode(true);
|
|
4161
|
+
if (nameChanged && void 0 !== style.name) setXlsxValueChild(this.styles, font, 'name', style.name, fontChildOrder);
|
|
4162
|
+
if (sizeChanged && void 0 !== style.size) setXlsxValueChild(this.styles, font, 'sz', String(style.size), fontChildOrder);
|
|
4163
|
+
if (colorChanged && void 0 !== style.color) {
|
|
4164
|
+
setXlsxColorChild(this.styles, font, style.color, fontChildOrder);
|
|
4165
|
+
const color = directChild(font, 'color');
|
|
4166
|
+
if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
|
|
4167
|
+
}
|
|
4168
|
+
if (boldChanged && void 0 !== style.bold) setXlsxToggleChild(this.styles, font, 'b', style.bold, fontChildOrder);
|
|
4169
|
+
if (italicChanged && void 0 !== style.italic) setXlsxToggleChild(this.styles, font, 'i', style.italic, fontChildOrder);
|
|
4170
|
+
if (strikeChanged && void 0 !== style.strike) setXlsxToggleChild(this.styles, font, 'strike', style.strike, fontChildOrder);
|
|
4171
|
+
if (underlineChanged && void 0 !== style.underline) setXlsxUnderlineChild(this.styles, font, style.underline, fontChildOrder);
|
|
4172
|
+
const index = fonts.length;
|
|
4173
|
+
this.fonts.append(font);
|
|
4174
|
+
this.generatedFonts.set(key, index);
|
|
4175
|
+
this.changed = true;
|
|
4176
|
+
this.updateCounts();
|
|
4177
|
+
return index;
|
|
4178
|
+
}
|
|
4179
|
+
fillId(baseFillId, cell, colorOrigin) {
|
|
4180
|
+
if (void 0 === cell.bg) return baseFillId;
|
|
4181
|
+
const color = xlsxRgbColor(cell.bg);
|
|
4182
|
+
if (!color) return baseFillId;
|
|
4183
|
+
const fills = directChildren(this.fills, 'fill');
|
|
4184
|
+
const baseIndex = fills[baseFillId] ? baseFillId : 0;
|
|
4185
|
+
const basePattern = directChild(fills[baseIndex], 'patternFill');
|
|
4186
|
+
const semanticColor = activeXlsxSemanticColorOrigin(colorOrigin, color, this.semanticPalette);
|
|
4187
|
+
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;
|
|
4188
|
+
const key = `${color}:${xlsxSemanticColorOriginKey(semanticColor)}`;
|
|
4189
|
+
const cached = this.generatedFills.get(key);
|
|
4190
|
+
if (void 0 !== cached) return cached;
|
|
4191
|
+
const fill = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fill');
|
|
4192
|
+
const pattern = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'patternFill');
|
|
4193
|
+
pattern.setAttribute('patternType', 'solid');
|
|
4194
|
+
const foreground = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'fgColor');
|
|
4195
|
+
foreground.setAttribute('rgb', color);
|
|
4196
|
+
if (semanticColor) applyXlsxSemanticColorOrigin(foreground, semanticColor);
|
|
4197
|
+
const background = this.styles.createElementNS(this.styles.documentElement.namespaceURI, 'bgColor');
|
|
4198
|
+
background.setAttribute('indexed', '64');
|
|
4199
|
+
pattern.append(foreground, background);
|
|
4200
|
+
fill.append(pattern);
|
|
4201
|
+
const index = directChildren(this.fills, 'fill').length;
|
|
4202
|
+
this.fills.append(fill);
|
|
4203
|
+
this.generatedFills.set(key, index);
|
|
4204
|
+
this.changed = true;
|
|
4205
|
+
this.updateCounts();
|
|
4206
|
+
return index;
|
|
4207
|
+
}
|
|
4208
|
+
borderId(baseBorderId, update, colorOrigins) {
|
|
4209
|
+
if (!update) return baseBorderId;
|
|
4210
|
+
const borders = directChildren(this.borders, 'border');
|
|
4211
|
+
const baseIndex = borders[baseBorderId] ? baseBorderId : 0;
|
|
4212
|
+
const base = borders[baseIndex];
|
|
4213
|
+
const lineUpdates = [
|
|
4214
|
+
[
|
|
4215
|
+
'left',
|
|
4216
|
+
update.left
|
|
4217
|
+
],
|
|
4218
|
+
[
|
|
4219
|
+
'right',
|
|
4220
|
+
update.right
|
|
4221
|
+
],
|
|
4222
|
+
[
|
|
4223
|
+
'top',
|
|
4224
|
+
update.top
|
|
4225
|
+
],
|
|
4226
|
+
[
|
|
4227
|
+
'bottom',
|
|
4228
|
+
update.bottom
|
|
4229
|
+
],
|
|
4230
|
+
[
|
|
4231
|
+
'diagonal',
|
|
4232
|
+
update.diagonal
|
|
4233
|
+
]
|
|
4234
|
+
];
|
|
4235
|
+
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));
|
|
4236
|
+
const diagonalUpChanged = void 0 !== update.diagonalUp && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalUp') !== update.diagonalUp;
|
|
4237
|
+
const diagonalDownChanged = void 0 !== update.diagonalDown && work_xlsx_cell_style_values_xlsxBooleanAttribute(base, 'diagonalDown') !== update.diagonalDown;
|
|
4238
|
+
if (!lineChanged && !diagonalUpChanged && !diagonalDownChanged) return baseIndex;
|
|
4239
|
+
const key = `${baseIndex}:${JSON.stringify(update)}:${JSON.stringify(colorOrigins ?? {})}`;
|
|
4240
|
+
const cached = this.generatedBorders.get(key);
|
|
4241
|
+
if (void 0 !== cached) return cached;
|
|
4242
|
+
const border = base.cloneNode(true);
|
|
4243
|
+
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)) {
|
|
4244
|
+
setXlsxBorderLine(this.styles, border, name, line);
|
|
4245
|
+
const semanticColor = line ? activeXlsxSemanticColorOrigin(colorOrigins?.[name], line.color, this.semanticPalette) : void 0;
|
|
4246
|
+
const color = directChild(directChild(border, name) ?? border, 'color');
|
|
4247
|
+
if (color && semanticColor) applyXlsxSemanticColorOrigin(color, semanticColor);
|
|
4248
|
+
}
|
|
4249
|
+
if (diagonalUpChanged && void 0 !== update.diagonalUp) border.setAttribute('diagonalUp', update.diagonalUp ? '1' : '0');
|
|
4250
|
+
if (diagonalDownChanged && void 0 !== update.diagonalDown) border.setAttribute('diagonalDown', update.diagonalDown ? '1' : '0');
|
|
4251
|
+
const index = borders.length;
|
|
4252
|
+
this.borders.append(border);
|
|
4253
|
+
this.generatedBorders.set(key, index);
|
|
4254
|
+
this.changed = true;
|
|
4255
|
+
this.updateCounts();
|
|
4256
|
+
return index;
|
|
4257
|
+
}
|
|
4258
|
+
updateCounts() {
|
|
4259
|
+
this.fonts.setAttribute('count', String(directChildren(this.fonts, 'font').length));
|
|
4260
|
+
this.fills.setAttribute('count', String(directChildren(this.fills, 'fill').length));
|
|
4261
|
+
this.borders.setAttribute('count', String(directChildren(this.borders, 'border').length));
|
|
4262
|
+
this.cellXfs.setAttribute('count', String(directChildren(this.cellXfs, 'xf').length));
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
function hasXlsxDirectCellStyle(cell) {
|
|
4266
|
+
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);
|
|
4267
|
+
}
|
|
3886
4268
|
const xlsxCellBorderStyles = new Set([
|
|
3887
4269
|
'dashDot',
|
|
3888
4270
|
'dashDotDot',
|
|
@@ -3913,10 +4295,12 @@ function readXlsxDirectCellStyles(worksheet, styles, theme = null) {
|
|
|
3913
4295
|
if (!coordinate || !xf) return [];
|
|
3914
4296
|
const style = readDirectCellStyle(xf, fonts, fills, colors);
|
|
3915
4297
|
const border = readDirectCellBorder(xf, borders, colors);
|
|
4298
|
+
const origin = readDirectCellStyleOrigin(xf, fonts, fills, borders, colors);
|
|
3916
4299
|
return Object.keys(style).length || border ? [
|
|
3917
4300
|
{
|
|
3918
4301
|
...coordinate,
|
|
3919
4302
|
border,
|
|
4303
|
+
origin,
|
|
3920
4304
|
style
|
|
3921
4305
|
}
|
|
3922
4306
|
] : [];
|
|
@@ -3961,6 +4345,43 @@ function readDirectCellStyle(xf, fonts, fills, colors) {
|
|
|
3961
4345
|
if (alignment) readDirectAlignmentStyle(style, alignment);
|
|
3962
4346
|
return style;
|
|
3963
4347
|
}
|
|
4348
|
+
function readDirectCellStyleOrigin(xf, fonts, fills, borders, colors) {
|
|
4349
|
+
const fontId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fontId')) ?? 0;
|
|
4350
|
+
const font = fonts[fontId];
|
|
4351
|
+
const fontColor = font && (0 !== fontId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyFont')) ? readXlsxSemanticColorOrigin(directChild(font, 'color'), colors) : void 0;
|
|
4352
|
+
const fillId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'fillId')) ?? 0;
|
|
4353
|
+
const fill = fills[fillId];
|
|
4354
|
+
const pattern = fill ? directChild(fill, 'patternFill') : void 0;
|
|
4355
|
+
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;
|
|
4356
|
+
const borderId = work_xlsx_cell_styles_nonNegativeInteger(work_ooxml_package_attribute(xf, 'borderId')) ?? 0;
|
|
4357
|
+
const border = borders[borderId];
|
|
4358
|
+
const borderColors = {};
|
|
4359
|
+
if (border && (0 !== borderId || work_xlsx_cell_styles_booleanAttribute(xf, 'applyBorder'))) for (const side of [
|
|
4360
|
+
'bottom',
|
|
4361
|
+
'diagonal',
|
|
4362
|
+
'left',
|
|
4363
|
+
'right',
|
|
4364
|
+
'top'
|
|
4365
|
+
]){
|
|
4366
|
+
const line = directChild(border, side);
|
|
4367
|
+
const lineStyle = line ? work_ooxml_package_attribute(line, 'style') : null;
|
|
4368
|
+
if (!line || !lineStyle || !xlsxCellBorderStyles.has(lineStyle)) continue;
|
|
4369
|
+
const color = readXlsxSemanticColorOrigin(directChild(line, 'color'), colors);
|
|
4370
|
+
if (color) borderColors[side] = color;
|
|
4371
|
+
}
|
|
4372
|
+
if (!fontColor && !fillColor && !Object.keys(borderColors).length) return;
|
|
4373
|
+
return {
|
|
4374
|
+
...fontColor ? {
|
|
4375
|
+
fontColor
|
|
4376
|
+
} : {},
|
|
4377
|
+
...fillColor ? {
|
|
4378
|
+
fillColor
|
|
4379
|
+
} : {},
|
|
4380
|
+
...Object.keys(borderColors).length ? {
|
|
4381
|
+
borderColors
|
|
4382
|
+
} : {}
|
|
4383
|
+
};
|
|
4384
|
+
}
|
|
3964
4385
|
function readDirectFontStyle(style, font, colors) {
|
|
3965
4386
|
const bold = directChild(font, 'b');
|
|
3966
4387
|
if (bold && toggleEnabled(bold)) style.bl = 1;
|
|
@@ -6381,8 +6802,10 @@ async function patchXlsxSheetFeatures(buffer, content) {
|
|
|
6381
6802
|
const worksheetParts = await work_xlsx_interop_readWorksheetParts(archive);
|
|
6382
6803
|
const zip = await jszip.loadAsync(buffer);
|
|
6383
6804
|
const styles = archive.has('xl/styles.xml') ? await archive.xml('xl/styles.xml') : null;
|
|
6805
|
+
const theme = archive.has('xl/theme/theme1.xml') ? await archive.xml('xl/theme/theme1.xml') : null;
|
|
6806
|
+
const semanticPalette = styles ? prepareXlsxSemanticPalette(styles, theme, spreadsheetXlsxStyleOrigins(content)) : void 0;
|
|
6384
6807
|
const differentialFormats = styles ? new XlsxDifferentialFormatWriter(styles) : void 0;
|
|
6385
|
-
const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles) : void 0;
|
|
6808
|
+
const directCellStyles = styles ? new XlsxDirectCellStyleWriter(styles, theme, semanticPalette?.palette) : void 0;
|
|
6386
6809
|
const cellProtection = styles ? new XlsxCellProtectionWriter(styles) : void 0;
|
|
6387
6810
|
for (const sheet of sheets){
|
|
6388
6811
|
const pageBreaks = sheet.id ? pageBreaksBySheetId.get(sheet.id) : void 0;
|
|
@@ -6402,12 +6825,21 @@ async function patchXlsxSheetFeatures(buffer, content) {
|
|
|
6402
6825
|
writeXlsxManualPageBreaks(document1, pageBreaks);
|
|
6403
6826
|
zip.file(partPath, new XMLSerializer().serializeToString(document1));
|
|
6404
6827
|
}
|
|
6405
|
-
if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
|
|
6828
|
+
if (styles && (differentialFormats?.changed || directCellStyles?.changed || cellProtection?.changed || semanticPalette?.stylesChanged)) zip.file('xl/styles.xml', new XMLSerializer().serializeToString(styles));
|
|
6829
|
+
if (theme && semanticPalette?.themeChanged) zip.file('xl/theme/theme1.xml', new XMLSerializer().serializeToString(theme));
|
|
6406
6830
|
return zip.generateAsync({
|
|
6407
6831
|
type: 'arraybuffer',
|
|
6408
6832
|
compression: 'DEFLATE'
|
|
6409
6833
|
});
|
|
6410
6834
|
}
|
|
6835
|
+
function spreadsheetXlsxStyleOrigins(content) {
|
|
6836
|
+
const origins = [];
|
|
6837
|
+
for (const sheet of content.sheets)for (const [, row] of sparseArrayEntries(sheet.data))for (const [, cell] of sparseArrayEntries(row)){
|
|
6838
|
+
const origin = xlsxCellStyleOrigin(cell);
|
|
6839
|
+
if (origin) origins.push(origin);
|
|
6840
|
+
}
|
|
6841
|
+
return origins;
|
|
6842
|
+
}
|
|
6411
6843
|
async function work_xlsx_interop_readWorksheetParts(archive, workbookDocument) {
|
|
6412
6844
|
if (!archive.has('xl/workbook.xml')) return new Map();
|
|
6413
6845
|
const workbook = workbookDocument ?? await archive.xml('xl/workbook.xml');
|
|
@@ -8320,7 +8752,7 @@ async function importWorkSpreadsheetFile(file, extension, context) {
|
|
|
8320
8752
|
const directCellStyle = directCellStyles.get(spreadsheetCellKey(row, column));
|
|
8321
8753
|
directCellStyles.delete(spreadsheetCellKey(row, column));
|
|
8322
8754
|
data[row] ??= [];
|
|
8323
|
-
data[row][column] = freezeImportedSpreadsheetCell(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style));
|
|
8755
|
+
data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin(fortuneCellFromXlsx(source, row, column, id, hyperlink, comment, XLSX, directCellStyle?.style), directCellStyle?.origin));
|
|
8324
8756
|
if (source.f) formulaCells.push({
|
|
8325
8757
|
column,
|
|
8326
8758
|
row
|
|
@@ -8333,15 +8765,15 @@ async function importWorkSpreadsheetFile(file, extension, context) {
|
|
|
8333
8765
|
}
|
|
8334
8766
|
releaseImportedWorksheetCells(worksheet);
|
|
8335
8767
|
}
|
|
8336
|
-
for (const { column, row, style } of directCellStyles.values()){
|
|
8768
|
+
for (const { column, origin, row, style } of directCellStyles.values()){
|
|
8337
8769
|
rowCount = Math.max(rowCount, row + 1);
|
|
8338
8770
|
columnCount = Math.max(columnCount, column + 1);
|
|
8339
8771
|
data[row] ??= [];
|
|
8340
8772
|
const existing = data[row][column];
|
|
8341
|
-
data[row][column] = freezeImportedSpreadsheetCell({
|
|
8773
|
+
data[row][column] = freezeImportedSpreadsheetCell(withXlsxCellStyleOrigin({
|
|
8342
8774
|
...existing ?? {},
|
|
8343
8775
|
...style
|
|
8344
|
-
});
|
|
8776
|
+
}, origin));
|
|
8345
8777
|
if (!existing) entryIndex += 1;
|
|
8346
8778
|
}
|
|
8347
8779
|
populatedCellCount += entryIndex;
|