ooxml.js 2.6.18 → 2.7.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/typed/xlsx/build.cjs +51 -14
- package/dist/typed/xlsx/build.js +52 -15
- package/dist/typed/xlsx/content.cjs +24 -12
- package/dist/typed/xlsx/content.js +25 -13
- package/dist/typed/xlsx/styles.cjs +288 -15
- package/dist/typed/xlsx/styles.d.cts +70 -4
- package/dist/typed/xlsx/styles.d.ts +70 -4
- package/dist/typed/xlsx/styles.js +286 -16
- package/package.json +2 -2
|
@@ -194,28 +194,55 @@ function buildStylesPart(cellFormats) {
|
|
|
194
194
|
}));
|
|
195
195
|
children.push(require_xml_fragment.el("numFmts", { count: String(numFmtElements.length) }, numFmtElements));
|
|
196
196
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
require_xml_fragment.el("
|
|
203
|
-
|
|
197
|
+
const fillElements = cellFormats.fillDeclarations().map((fill) => {
|
|
198
|
+
if (fill.patternType === "solid") {
|
|
199
|
+
const rgb = fill.rgb ?? "000000";
|
|
200
|
+
return require_xml_fragment.el("fill", {}, [require_xml_fragment.el("patternFill", { patternType: "solid" }, [require_xml_fragment.el("fgColor", { rgb: `FF${rgb}` }), require_xml_fragment.el("bgColor", { indexed: "64" })])]);
|
|
201
|
+
}
|
|
202
|
+
return require_xml_fragment.el("fill", {}, [require_xml_fragment.el("patternFill", { patternType: fill.patternType })]);
|
|
203
|
+
});
|
|
204
|
+
const borderElements = cellFormats.borderDeclarations().map((border) => {
|
|
205
|
+
const edgeElements = [];
|
|
206
|
+
for (const edge of [
|
|
207
|
+
"left",
|
|
208
|
+
"right",
|
|
209
|
+
"top",
|
|
210
|
+
"bottom"
|
|
211
|
+
]) {
|
|
212
|
+
const present = border.edges[edge];
|
|
213
|
+
if (present !== void 0) edgeElements.push(require_xml_fragment.el(edge, { style: present.style }, [require_xml_fragment.el("color", { rgb: `FF${present.rgb}` })]));
|
|
214
|
+
else edgeElements.push(require_xml_fragment.el(edge));
|
|
215
|
+
}
|
|
216
|
+
edgeElements.push(require_xml_fragment.el("diagonal"));
|
|
217
|
+
return require_xml_fragment.el("border", {}, edgeElements);
|
|
218
|
+
});
|
|
219
|
+
children.push(require_xml_fragment.el("fonts", { count: "1" }, [require_xml_fragment.el("font", {}, [require_xml_fragment.el("sz", { val: "11" }), require_xml_fragment.el("name", { val: "Calibri" })])]), require_xml_fragment.el("fills", { count: String(fillElements.length) }, fillElements), require_xml_fragment.el("borders", { count: String(borderElements.length) }, borderElements), require_xml_fragment.el("cellStyleXfs", { count: "1" }, [require_xml_fragment.el("xf", {
|
|
204
220
|
numFmtId: "0",
|
|
205
221
|
fontId: "0",
|
|
206
222
|
fillId: "0",
|
|
207
223
|
borderId: "0"
|
|
208
224
|
})]));
|
|
209
|
-
const xfElements = cellFormats.
|
|
225
|
+
const xfElements = cellFormats.cellFormatRecords().map((record) => {
|
|
210
226
|
const attrs = {
|
|
211
|
-
numFmtId: String(numFmtId),
|
|
227
|
+
numFmtId: String(record.numFmtId),
|
|
212
228
|
fontId: "0",
|
|
213
|
-
fillId:
|
|
214
|
-
borderId:
|
|
229
|
+
fillId: String(record.fillId),
|
|
230
|
+
borderId: String(record.borderId),
|
|
215
231
|
xfId: "0"
|
|
216
232
|
};
|
|
217
|
-
if (numFmtId !== 0) attrs.applyNumberFormat = require_typed_xlsx_util.writeXmlBool(true);
|
|
218
|
-
|
|
233
|
+
if (record.numFmtId !== 0) attrs.applyNumberFormat = require_typed_xlsx_util.writeXmlBool(true);
|
|
234
|
+
if (record.fillId !== require_typed_xlsx_styles.RESERVED_FILL_INDICES.none) attrs.applyFill = require_typed_xlsx_util.writeXmlBool(true);
|
|
235
|
+
if (record.borderId !== require_typed_xlsx_styles.RESERVED_BORDER_INDICES.empty) attrs.applyBorder = require_typed_xlsx_util.writeXmlBool(true);
|
|
236
|
+
const xfChildren = [];
|
|
237
|
+
if (record.alignment !== void 0) {
|
|
238
|
+
attrs.applyAlignment = require_typed_xlsx_util.writeXmlBool(true);
|
|
239
|
+
const alignmentAttrs = {};
|
|
240
|
+
if (record.alignment.horizontal !== void 0) alignmentAttrs.horizontal = record.alignment.horizontal;
|
|
241
|
+
if (record.alignment.vertical === "top") alignmentAttrs.vertical = "top";
|
|
242
|
+
else if (record.alignment.vertical === "middle") alignmentAttrs.vertical = "center";
|
|
243
|
+
xfChildren.push(require_xml_fragment.el("alignment", alignmentAttrs));
|
|
244
|
+
}
|
|
245
|
+
return require_xml_fragment.el("xf", attrs, xfChildren);
|
|
219
246
|
});
|
|
220
247
|
children.push(require_xml_fragment.el("cellXfs", { count: String(xfElements.length) }, xfElements));
|
|
221
248
|
children.push(require_xml_fragment.el("cellStyles", { count: "1" }, [require_xml_fragment.el("cellStyle", {
|
|
@@ -332,7 +359,17 @@ function renderTemporal(serial, iso, format, isFormulaResult, sharedStrings) {
|
|
|
332
359
|
function buildCellElement(cell, sharedStrings, cellFormats) {
|
|
333
360
|
const children = [];
|
|
334
361
|
const rendered = renderCellValue(cell.value, cell.formula !== void 0, sharedStrings);
|
|
335
|
-
const
|
|
362
|
+
const decoration = cell.background !== void 0 || cell.borders !== void 0 || cell.alignment !== void 0 || cell.verticalAlignment !== void 0 ? {
|
|
363
|
+
background: cell.background,
|
|
364
|
+
borders: cell.borders,
|
|
365
|
+
alignment: cell.alignment,
|
|
366
|
+
verticalAlignment: cell.verticalAlignment
|
|
367
|
+
} : void 0;
|
|
368
|
+
const format = rendered?.format;
|
|
369
|
+
const styleIndex = format === void 0 && decoration === void 0 ? 0 : cellFormats.intern(format ?? {
|
|
370
|
+
kind: "builtin",
|
|
371
|
+
id: 0
|
|
372
|
+
}, decoration);
|
|
336
373
|
const attrs = {
|
|
337
374
|
r: require_typed_xlsx_a1.cellReference(cell.row, cell.column),
|
|
338
375
|
s: String(styleIndex)
|
package/dist/typed/xlsx/build.js
CHANGED
|
@@ -8,7 +8,7 @@ import { BOOLEAN_NUMBER_FORMAT, DATE_NUMBER_FORMAT, DATE_TIME_NUMBER_FORMAT, PER
|
|
|
8
8
|
import { pageSizeToPaperSizeCode, ptToUniversalMeasure, writeXmlBool } from "./util.js";
|
|
9
9
|
import { DEFAULT_HEADER_FOOTER_MARGIN_PT } from "./print-settings.js";
|
|
10
10
|
import { isoDateTimeToSerial, isoDateToSerial, isoTimeToSerial } from "./serial.js";
|
|
11
|
-
import { CellFormatTable } from "./styles.js";
|
|
11
|
+
import { CellFormatTable, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES } from "./styles.js";
|
|
12
12
|
import { ptToColumnWidthChars } from "./units.js";
|
|
13
13
|
//#region src/typed/xlsx/build.ts
|
|
14
14
|
const SML_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
@@ -193,28 +193,55 @@ function buildStylesPart(cellFormats) {
|
|
|
193
193
|
}));
|
|
194
194
|
children.push(el("numFmts", { count: String(numFmtElements.length) }, numFmtElements));
|
|
195
195
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
el("
|
|
202
|
-
|
|
196
|
+
const fillElements = cellFormats.fillDeclarations().map((fill) => {
|
|
197
|
+
if (fill.patternType === "solid") {
|
|
198
|
+
const rgb = fill.rgb ?? "000000";
|
|
199
|
+
return el("fill", {}, [el("patternFill", { patternType: "solid" }, [el("fgColor", { rgb: `FF${rgb}` }), el("bgColor", { indexed: "64" })])]);
|
|
200
|
+
}
|
|
201
|
+
return el("fill", {}, [el("patternFill", { patternType: fill.patternType })]);
|
|
202
|
+
});
|
|
203
|
+
const borderElements = cellFormats.borderDeclarations().map((border) => {
|
|
204
|
+
const edgeElements = [];
|
|
205
|
+
for (const edge of [
|
|
206
|
+
"left",
|
|
207
|
+
"right",
|
|
208
|
+
"top",
|
|
209
|
+
"bottom"
|
|
210
|
+
]) {
|
|
211
|
+
const present = border.edges[edge];
|
|
212
|
+
if (present !== void 0) edgeElements.push(el(edge, { style: present.style }, [el("color", { rgb: `FF${present.rgb}` })]));
|
|
213
|
+
else edgeElements.push(el(edge));
|
|
214
|
+
}
|
|
215
|
+
edgeElements.push(el("diagonal"));
|
|
216
|
+
return el("border", {}, edgeElements);
|
|
217
|
+
});
|
|
218
|
+
children.push(el("fonts", { count: "1" }, [el("font", {}, [el("sz", { val: "11" }), el("name", { val: "Calibri" })])]), el("fills", { count: String(fillElements.length) }, fillElements), el("borders", { count: String(borderElements.length) }, borderElements), el("cellStyleXfs", { count: "1" }, [el("xf", {
|
|
203
219
|
numFmtId: "0",
|
|
204
220
|
fontId: "0",
|
|
205
221
|
fillId: "0",
|
|
206
222
|
borderId: "0"
|
|
207
223
|
})]));
|
|
208
|
-
const xfElements = cellFormats.
|
|
224
|
+
const xfElements = cellFormats.cellFormatRecords().map((record) => {
|
|
209
225
|
const attrs = {
|
|
210
|
-
numFmtId: String(numFmtId),
|
|
226
|
+
numFmtId: String(record.numFmtId),
|
|
211
227
|
fontId: "0",
|
|
212
|
-
fillId:
|
|
213
|
-
borderId:
|
|
228
|
+
fillId: String(record.fillId),
|
|
229
|
+
borderId: String(record.borderId),
|
|
214
230
|
xfId: "0"
|
|
215
231
|
};
|
|
216
|
-
if (numFmtId !== 0) attrs.applyNumberFormat = writeXmlBool(true);
|
|
217
|
-
|
|
232
|
+
if (record.numFmtId !== 0) attrs.applyNumberFormat = writeXmlBool(true);
|
|
233
|
+
if (record.fillId !== RESERVED_FILL_INDICES.none) attrs.applyFill = writeXmlBool(true);
|
|
234
|
+
if (record.borderId !== RESERVED_BORDER_INDICES.empty) attrs.applyBorder = writeXmlBool(true);
|
|
235
|
+
const xfChildren = [];
|
|
236
|
+
if (record.alignment !== void 0) {
|
|
237
|
+
attrs.applyAlignment = writeXmlBool(true);
|
|
238
|
+
const alignmentAttrs = {};
|
|
239
|
+
if (record.alignment.horizontal !== void 0) alignmentAttrs.horizontal = record.alignment.horizontal;
|
|
240
|
+
if (record.alignment.vertical === "top") alignmentAttrs.vertical = "top";
|
|
241
|
+
else if (record.alignment.vertical === "middle") alignmentAttrs.vertical = "center";
|
|
242
|
+
xfChildren.push(el("alignment", alignmentAttrs));
|
|
243
|
+
}
|
|
244
|
+
return el("xf", attrs, xfChildren);
|
|
218
245
|
});
|
|
219
246
|
children.push(el("cellXfs", { count: String(xfElements.length) }, xfElements));
|
|
220
247
|
children.push(el("cellStyles", { count: "1" }, [el("cellStyle", {
|
|
@@ -331,7 +358,17 @@ function renderTemporal(serial, iso, format, isFormulaResult, sharedStrings) {
|
|
|
331
358
|
function buildCellElement(cell, sharedStrings, cellFormats) {
|
|
332
359
|
const children = [];
|
|
333
360
|
const rendered = renderCellValue(cell.value, cell.formula !== void 0, sharedStrings);
|
|
334
|
-
const
|
|
361
|
+
const decoration = cell.background !== void 0 || cell.borders !== void 0 || cell.alignment !== void 0 || cell.verticalAlignment !== void 0 ? {
|
|
362
|
+
background: cell.background,
|
|
363
|
+
borders: cell.borders,
|
|
364
|
+
alignment: cell.alignment,
|
|
365
|
+
verticalAlignment: cell.verticalAlignment
|
|
366
|
+
} : void 0;
|
|
367
|
+
const format = rendered?.format;
|
|
368
|
+
const styleIndex = format === void 0 && decoration === void 0 ? 0 : cellFormats.intern(format ?? {
|
|
369
|
+
kind: "builtin",
|
|
370
|
+
id: 0
|
|
371
|
+
}, decoration);
|
|
335
372
|
const attrs = {
|
|
336
373
|
r: cellReference(cell.row, cell.column),
|
|
337
374
|
s: String(styleIndex)
|
|
@@ -98,16 +98,21 @@ function deriveDisplayText(value) {
|
|
|
98
98
|
}
|
|
99
99
|
const DEFAULT_CELL_STYLE_INDEX = 0;
|
|
100
100
|
const PLAIN_NUMBER = { kind: "number" };
|
|
101
|
-
function
|
|
101
|
+
function readCellFormatContext(pkg) {
|
|
102
102
|
return {
|
|
103
|
-
|
|
103
|
+
entries: require_typed_xlsx_styles.readCellStyles(pkg),
|
|
104
104
|
date1904: require_typed_xlsx_serial.readDate1904(pkg)
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
function
|
|
107
|
+
function entryOf(cell, context) {
|
|
108
108
|
const raw = require_typed_util.attr(cell, "s");
|
|
109
109
|
const index = raw === void 0 ? DEFAULT_CELL_STYLE_INDEX : Number.parseInt(raw, 10);
|
|
110
|
-
return
|
|
110
|
+
return Number.isInteger(index) ? context.entries[index] : void 0;
|
|
111
|
+
}
|
|
112
|
+
function numberFormatOf(cell, context) {
|
|
113
|
+
const entry = entryOf(cell, context);
|
|
114
|
+
if (entry?.numberFormatCode === void 0) return PLAIN_NUMBER;
|
|
115
|
+
return require_typed_xlsx_number_format.classifyNumberFormat(entry.numberFormatCode);
|
|
111
116
|
}
|
|
112
117
|
function resolveNumericValue(num, cell, context) {
|
|
113
118
|
const format = numberFormatOf(cell, context);
|
|
@@ -231,13 +236,13 @@ function readCellValue(cell, sharedStrings, numericFormats) {
|
|
|
231
236
|
displayText: deriveDisplayText(value)
|
|
232
237
|
};
|
|
233
238
|
}
|
|
234
|
-
function readCell(cell, sharedStrings,
|
|
239
|
+
function readCell(cell, sharedStrings, context) {
|
|
235
240
|
const reference = require_typed_util.attr(cell, "r");
|
|
236
241
|
const position = reference === void 0 ? void 0 : require_typed_xlsx_a1.parseCellReference(reference);
|
|
237
242
|
if (position === void 0) return;
|
|
238
243
|
const formulaEl = require_typed_util.childrenWithTag(cell, "f")[0];
|
|
239
244
|
const formula = formulaEl === void 0 ? void 0 : require_typed_util.textContent(formulaEl);
|
|
240
|
-
const resolved = readCellValue(cell, sharedStrings,
|
|
245
|
+
const resolved = readCellValue(cell, sharedStrings, context);
|
|
241
246
|
if (resolved === void 0) {
|
|
242
247
|
if (formula === void 0) return;
|
|
243
248
|
return {
|
|
@@ -255,6 +260,13 @@ function readCell(cell, sharedStrings, numericFormats) {
|
|
|
255
260
|
displayText: resolved.displayText
|
|
256
261
|
};
|
|
257
262
|
if (formula !== void 0) cellEntry.formula = formula;
|
|
263
|
+
const entry = entryOf(cell, context);
|
|
264
|
+
if (entry !== void 0) {
|
|
265
|
+
if (entry.background !== void 0) cellEntry.background = entry.background;
|
|
266
|
+
if (entry.borders !== void 0) cellEntry.borders = entry.borders;
|
|
267
|
+
if (entry.alignment !== void 0) cellEntry.alignment = entry.alignment;
|
|
268
|
+
if (entry.verticalAlignment !== void 0) cellEntry.verticalAlignment = entry.verticalAlignment;
|
|
269
|
+
}
|
|
258
270
|
return cellEntry;
|
|
259
271
|
}
|
|
260
272
|
function applyMergedRanges(worksheet, cells) {
|
|
@@ -274,18 +286,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
274
286
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
275
287
|
}
|
|
276
288
|
}
|
|
277
|
-
function readCells(worksheet, sharedStrings,
|
|
289
|
+
function readCells(worksheet, sharedStrings, context) {
|
|
278
290
|
const sheetData = require_typed_util.childrenWithTag(worksheet, "sheetData")[0];
|
|
279
291
|
if (sheetData === void 0) return [];
|
|
280
292
|
const cells = [];
|
|
281
293
|
for (const row of require_typed_util.childrenWithTag(sheetData, "row")) for (const cell of require_typed_util.childrenWithTag(row, "c")) {
|
|
282
|
-
const read = readCell(cell, sharedStrings,
|
|
294
|
+
const read = readCell(cell, sharedStrings, context);
|
|
283
295
|
if (read !== void 0) cells.push(read);
|
|
284
296
|
}
|
|
285
297
|
applyMergedRanges(worksheet, cells);
|
|
286
298
|
return cells;
|
|
287
299
|
}
|
|
288
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet,
|
|
300
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
|
|
289
301
|
const worksheet = require_typed_util.rootElement(pkg.parts[entry.path]);
|
|
290
302
|
if (worksheet === void 0) return {
|
|
291
303
|
name: entry.name,
|
|
@@ -297,7 +309,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, n
|
|
|
297
309
|
};
|
|
298
310
|
return {
|
|
299
311
|
name: entry.name,
|
|
300
|
-
cells: readCells(worksheet, sharedStrings,
|
|
312
|
+
cells: readCells(worksheet, sharedStrings, context),
|
|
301
313
|
columns: readColumns(worksheet),
|
|
302
314
|
rows: readRows(worksheet),
|
|
303
315
|
images: [],
|
|
@@ -315,8 +327,8 @@ function fallbackEmptyWorksheet() {
|
|
|
315
327
|
function readXlsxContent(pkg) {
|
|
316
328
|
const sharedStrings = require_typed_xlsx_shared_strings.loadSharedStrings(pkg);
|
|
317
329
|
const definedNamesBySheet = require_typed_xlsx_defined_names.readDefinedNamesBySheet(pkg);
|
|
318
|
-
const
|
|
319
|
-
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet,
|
|
330
|
+
const context = readCellFormatContext(pkg);
|
|
331
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context));
|
|
320
332
|
return {
|
|
321
333
|
kind: "spreadsheet",
|
|
322
334
|
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
@@ -7,7 +7,7 @@ import { classifyNumberFormat } from "./number-format.js";
|
|
|
7
7
|
import { readXmlBool } from "./util.js";
|
|
8
8
|
import { readPrintSettings } from "./print-settings.js";
|
|
9
9
|
import { readDate1904, serialToIsoDate, serialToIsoDateTime, serialToIsoTime } from "./serial.js";
|
|
10
|
-
import {
|
|
10
|
+
import { readCellStyles } from "./styles.js";
|
|
11
11
|
import { columnWidthCharsToPt } from "./units.js";
|
|
12
12
|
import { CONTENT_FORMAT_VERSION } from "document-schema.js";
|
|
13
13
|
//#region src/typed/xlsx/content.ts
|
|
@@ -97,16 +97,21 @@ function deriveDisplayText(value) {
|
|
|
97
97
|
}
|
|
98
98
|
const DEFAULT_CELL_STYLE_INDEX = 0;
|
|
99
99
|
const PLAIN_NUMBER = { kind: "number" };
|
|
100
|
-
function
|
|
100
|
+
function readCellFormatContext(pkg) {
|
|
101
101
|
return {
|
|
102
|
-
|
|
102
|
+
entries: readCellStyles(pkg),
|
|
103
103
|
date1904: readDate1904(pkg)
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
-
function
|
|
106
|
+
function entryOf(cell, context) {
|
|
107
107
|
const raw = attr(cell, "s");
|
|
108
108
|
const index = raw === void 0 ? DEFAULT_CELL_STYLE_INDEX : Number.parseInt(raw, 10);
|
|
109
|
-
return
|
|
109
|
+
return Number.isInteger(index) ? context.entries[index] : void 0;
|
|
110
|
+
}
|
|
111
|
+
function numberFormatOf(cell, context) {
|
|
112
|
+
const entry = entryOf(cell, context);
|
|
113
|
+
if (entry?.numberFormatCode === void 0) return PLAIN_NUMBER;
|
|
114
|
+
return classifyNumberFormat(entry.numberFormatCode);
|
|
110
115
|
}
|
|
111
116
|
function resolveNumericValue(num, cell, context) {
|
|
112
117
|
const format = numberFormatOf(cell, context);
|
|
@@ -230,13 +235,13 @@ function readCellValue(cell, sharedStrings, numericFormats) {
|
|
|
230
235
|
displayText: deriveDisplayText(value)
|
|
231
236
|
};
|
|
232
237
|
}
|
|
233
|
-
function readCell(cell, sharedStrings,
|
|
238
|
+
function readCell(cell, sharedStrings, context) {
|
|
234
239
|
const reference = attr(cell, "r");
|
|
235
240
|
const position = reference === void 0 ? void 0 : parseCellReference(reference);
|
|
236
241
|
if (position === void 0) return;
|
|
237
242
|
const formulaEl = childrenWithTag(cell, "f")[0];
|
|
238
243
|
const formula = formulaEl === void 0 ? void 0 : textContent(formulaEl);
|
|
239
|
-
const resolved = readCellValue(cell, sharedStrings,
|
|
244
|
+
const resolved = readCellValue(cell, sharedStrings, context);
|
|
240
245
|
if (resolved === void 0) {
|
|
241
246
|
if (formula === void 0) return;
|
|
242
247
|
return {
|
|
@@ -254,6 +259,13 @@ function readCell(cell, sharedStrings, numericFormats) {
|
|
|
254
259
|
displayText: resolved.displayText
|
|
255
260
|
};
|
|
256
261
|
if (formula !== void 0) cellEntry.formula = formula;
|
|
262
|
+
const entry = entryOf(cell, context);
|
|
263
|
+
if (entry !== void 0) {
|
|
264
|
+
if (entry.background !== void 0) cellEntry.background = entry.background;
|
|
265
|
+
if (entry.borders !== void 0) cellEntry.borders = entry.borders;
|
|
266
|
+
if (entry.alignment !== void 0) cellEntry.alignment = entry.alignment;
|
|
267
|
+
if (entry.verticalAlignment !== void 0) cellEntry.verticalAlignment = entry.verticalAlignment;
|
|
268
|
+
}
|
|
257
269
|
return cellEntry;
|
|
258
270
|
}
|
|
259
271
|
function applyMergedRanges(worksheet, cells) {
|
|
@@ -273,18 +285,18 @@ function applyMergedRanges(worksheet, cells) {
|
|
|
273
285
|
if (rowSpan > 1) anchor.rowSpan = rowSpan;
|
|
274
286
|
}
|
|
275
287
|
}
|
|
276
|
-
function readCells(worksheet, sharedStrings,
|
|
288
|
+
function readCells(worksheet, sharedStrings, context) {
|
|
277
289
|
const sheetData = childrenWithTag(worksheet, "sheetData")[0];
|
|
278
290
|
if (sheetData === void 0) return [];
|
|
279
291
|
const cells = [];
|
|
280
292
|
for (const row of childrenWithTag(sheetData, "row")) for (const cell of childrenWithTag(row, "c")) {
|
|
281
|
-
const read = readCell(cell, sharedStrings,
|
|
293
|
+
const read = readCell(cell, sharedStrings, context);
|
|
282
294
|
if (read !== void 0) cells.push(read);
|
|
283
295
|
}
|
|
284
296
|
applyMergedRanges(worksheet, cells);
|
|
285
297
|
return cells;
|
|
286
298
|
}
|
|
287
|
-
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet,
|
|
299
|
+
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
|
|
288
300
|
const worksheet = rootElement(pkg.parts[entry.path]);
|
|
289
301
|
if (worksheet === void 0) return {
|
|
290
302
|
name: entry.name,
|
|
@@ -296,7 +308,7 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, n
|
|
|
296
308
|
};
|
|
297
309
|
return {
|
|
298
310
|
name: entry.name,
|
|
299
|
-
cells: readCells(worksheet, sharedStrings,
|
|
311
|
+
cells: readCells(worksheet, sharedStrings, context),
|
|
300
312
|
columns: readColumns(worksheet),
|
|
301
313
|
rows: readRows(worksheet),
|
|
302
314
|
images: [],
|
|
@@ -314,8 +326,8 @@ function fallbackEmptyWorksheet() {
|
|
|
314
326
|
function readXlsxContent(pkg) {
|
|
315
327
|
const sharedStrings = loadSharedStrings(pkg);
|
|
316
328
|
const definedNamesBySheet = readDefinedNamesBySheet(pkg);
|
|
317
|
-
const
|
|
318
|
-
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet,
|
|
329
|
+
const context = readCellFormatContext(pkg);
|
|
330
|
+
const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context));
|
|
319
331
|
return {
|
|
320
332
|
kind: "spreadsheet",
|
|
321
333
|
formatVersion: CONTENT_FORMAT_VERSION,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_typed_util = require("../util.cjs");
|
|
3
3
|
const require_typed_xlsx_number_format = require("./number-format.cjs");
|
|
4
|
+
let document_schema_js = require("document-schema.js");
|
|
4
5
|
//#region src/typed/xlsx/styles.ts
|
|
5
6
|
const STYLES_PATH = "xl/styles.xml";
|
|
6
7
|
const GENERAL_NUM_FMT_ID = 0;
|
|
@@ -17,37 +18,249 @@ function readNumberFormatCodesById(styleSheet) {
|
|
|
17
18
|
}
|
|
18
19
|
return codes;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
const BORDER_WIDTH_PT = {
|
|
22
|
+
hair: .5,
|
|
23
|
+
thin: .75,
|
|
24
|
+
medium: 1.5,
|
|
25
|
+
thick: 2.25
|
|
26
|
+
};
|
|
27
|
+
const XLSX_BORDER_STYLE = {
|
|
28
|
+
thin: {
|
|
29
|
+
weight: "thin",
|
|
30
|
+
pattern: "solid"
|
|
31
|
+
},
|
|
32
|
+
medium: {
|
|
33
|
+
weight: "medium",
|
|
34
|
+
pattern: "solid"
|
|
35
|
+
},
|
|
36
|
+
thick: {
|
|
37
|
+
weight: "thick",
|
|
38
|
+
pattern: "solid"
|
|
39
|
+
},
|
|
40
|
+
hair: {
|
|
41
|
+
weight: "hair",
|
|
42
|
+
pattern: "solid"
|
|
43
|
+
},
|
|
44
|
+
dashed: {
|
|
45
|
+
weight: "thin",
|
|
46
|
+
pattern: "dashed"
|
|
47
|
+
},
|
|
48
|
+
dotted: {
|
|
49
|
+
weight: "thin",
|
|
50
|
+
pattern: "dotted"
|
|
51
|
+
},
|
|
52
|
+
double: {
|
|
53
|
+
weight: "thin",
|
|
54
|
+
pattern: "double"
|
|
55
|
+
},
|
|
56
|
+
mediumDashed: {
|
|
57
|
+
weight: "medium",
|
|
58
|
+
pattern: "dashed"
|
|
59
|
+
},
|
|
60
|
+
dashDot: {
|
|
61
|
+
weight: "thin",
|
|
62
|
+
pattern: "dashed"
|
|
63
|
+
},
|
|
64
|
+
mediumDashDot: {
|
|
65
|
+
weight: "medium",
|
|
66
|
+
pattern: "dashed"
|
|
67
|
+
},
|
|
68
|
+
dashDotDot: {
|
|
69
|
+
weight: "thin",
|
|
70
|
+
pattern: "dashed"
|
|
71
|
+
},
|
|
72
|
+
mediumDashDotDot: {
|
|
73
|
+
weight: "medium",
|
|
74
|
+
pattern: "dashed"
|
|
75
|
+
},
|
|
76
|
+
slantDashDot: {
|
|
77
|
+
weight: "medium",
|
|
78
|
+
pattern: "dashed"
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const BORDER_WEIGHT_UPPER_PT = {
|
|
82
|
+
hair: .625,
|
|
83
|
+
thin: 1.125,
|
|
84
|
+
medium: 1.875
|
|
85
|
+
};
|
|
86
|
+
function readColorRgb(container, colorTag) {
|
|
87
|
+
const colorEl = require_typed_util.childrenWithTag(container, colorTag)[0];
|
|
88
|
+
if (colorEl === void 0) return;
|
|
89
|
+
const raw = require_typed_util.attr(colorEl, "rgb");
|
|
90
|
+
if (raw === void 0) return;
|
|
91
|
+
const hex = raw.length >= 6 ? raw.slice(-6) : raw;
|
|
92
|
+
if (!/^[0-9a-fA-F]{6}$/.test(hex)) return;
|
|
93
|
+
try {
|
|
94
|
+
return (0, document_schema_js.rgbHexToColor)(hex);
|
|
95
|
+
} catch {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function readFillBackground(fill) {
|
|
100
|
+
const patternFill = require_typed_util.childrenWithTag(fill, "patternFill")[0];
|
|
101
|
+
if (patternFill === void 0 || require_typed_util.attr(patternFill, "patternType") !== "solid") return;
|
|
102
|
+
return readColorRgb(patternFill, "fgColor") ?? readColorRgb(patternFill, "bgColor");
|
|
103
|
+
}
|
|
104
|
+
function readFills(styleSheet) {
|
|
105
|
+
const fillsEl = require_typed_util.childrenWithTag(styleSheet, "fills")[0];
|
|
106
|
+
if (fillsEl === void 0) return [];
|
|
107
|
+
return require_typed_util.childrenWithTag(fillsEl, "fill").map(readFillBackground);
|
|
108
|
+
}
|
|
109
|
+
function readBorderEdge(border, edge) {
|
|
110
|
+
const edgeEl = require_typed_util.childrenWithTag(border, edge)[0];
|
|
111
|
+
if (edgeEl === void 0) return;
|
|
112
|
+
const styleToken = require_typed_util.attr(edgeEl, "style");
|
|
113
|
+
if (styleToken === void 0 || styleToken === "none") return;
|
|
114
|
+
const resolved = XLSX_BORDER_STYLE[styleToken];
|
|
115
|
+
if (resolved === void 0) return;
|
|
116
|
+
const color = readColorRgb(edgeEl, "color");
|
|
117
|
+
if (color === void 0) return;
|
|
118
|
+
const result = {
|
|
119
|
+
color,
|
|
120
|
+
widthPt: BORDER_WIDTH_PT[resolved.weight]
|
|
121
|
+
};
|
|
122
|
+
if (resolved.pattern !== "solid") result.style = resolved.pattern;
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
function readBorders(styleSheet) {
|
|
126
|
+
const bordersEl = require_typed_util.childrenWithTag(styleSheet, "borders")[0];
|
|
127
|
+
if (bordersEl === void 0) return [];
|
|
128
|
+
return require_typed_util.childrenWithTag(bordersEl, "border").map((border) => {
|
|
129
|
+
const left = readBorderEdge(border, "left");
|
|
130
|
+
const right = readBorderEdge(border, "right");
|
|
131
|
+
const top = readBorderEdge(border, "top");
|
|
132
|
+
const bottom = readBorderEdge(border, "bottom");
|
|
133
|
+
if (left === void 0 && right === void 0 && top === void 0 && bottom === void 0) return;
|
|
134
|
+
const result = {};
|
|
135
|
+
if (left !== void 0) result.left = left;
|
|
136
|
+
if (right !== void 0) result.right = right;
|
|
137
|
+
if (top !== void 0) result.top = top;
|
|
138
|
+
if (bottom !== void 0) result.bottom = bottom;
|
|
139
|
+
return result;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function readHorizontalAlignment(alignment) {
|
|
143
|
+
const value = require_typed_util.attr(alignment, "horizontal");
|
|
144
|
+
if (value === "left" || value === "center" || value === "right" || value === "justify") return value;
|
|
145
|
+
}
|
|
146
|
+
function readVerticalAlignment(alignment) {
|
|
147
|
+
const value = require_typed_util.attr(alignment, "vertical");
|
|
148
|
+
if (value === "top") return "top";
|
|
149
|
+
if (value === "center") return "middle";
|
|
150
|
+
}
|
|
151
|
+
function readAlignment(xf) {
|
|
152
|
+
const alignment = require_typed_util.childrenWithTag(xf, "alignment")[0];
|
|
153
|
+
if (alignment === void 0) return {};
|
|
154
|
+
return {
|
|
155
|
+
alignment: readHorizontalAlignment(alignment),
|
|
156
|
+
verticalAlignment: readVerticalAlignment(alignment)
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function readCellStyles(pkg) {
|
|
21
160
|
const styleSheet = require_typed_util.rootElement(pkg.parts[STYLES_PATH]);
|
|
22
161
|
if (styleSheet === void 0) return [];
|
|
23
162
|
const cellXfsEl = require_typed_util.childrenWithTag(styleSheet, "cellXfs")[0];
|
|
24
163
|
if (cellXfsEl === void 0) return [];
|
|
25
164
|
const codes = readNumberFormatCodesById(styleSheet);
|
|
165
|
+
const fills = readFills(styleSheet);
|
|
166
|
+
const borders = readBorders(styleSheet);
|
|
26
167
|
return require_typed_util.childrenWithTag(cellXfsEl, "xf").map((xf) => {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
168
|
+
const numFmtRaw = require_typed_util.attr(xf, "numFmtId");
|
|
169
|
+
const numFmtId = numFmtRaw === void 0 ? 0 : Number.parseInt(numFmtRaw, 10);
|
|
170
|
+
const entry = {};
|
|
171
|
+
if (Number.isInteger(numFmtId)) {
|
|
172
|
+
const code = codes.get(numFmtId);
|
|
173
|
+
if (code !== void 0) entry.numberFormatCode = code;
|
|
174
|
+
}
|
|
175
|
+
const fillId = parseChildIndex(require_typed_util.attr(xf, "fillId"));
|
|
176
|
+
if (fillId !== void 0) entry.background = fills[fillId];
|
|
177
|
+
const borderId = parseChildIndex(require_typed_util.attr(xf, "borderId"));
|
|
178
|
+
if (borderId !== void 0) entry.borders = borders[borderId];
|
|
179
|
+
const { alignment, verticalAlignment } = readAlignment(xf);
|
|
180
|
+
if (alignment !== void 0) entry.alignment = alignment;
|
|
181
|
+
if (verticalAlignment !== void 0) entry.verticalAlignment = verticalAlignment;
|
|
182
|
+
return entry;
|
|
30
183
|
});
|
|
31
184
|
}
|
|
185
|
+
function parseChildIndex(value) {
|
|
186
|
+
if (value === void 0) return;
|
|
187
|
+
const n = Number.parseInt(value, 10);
|
|
188
|
+
return Number.isInteger(n) ? n : void 0;
|
|
189
|
+
}
|
|
190
|
+
function readCellFormatCodes(pkg) {
|
|
191
|
+
return readCellStyles(pkg).map((entry) => entry.numberFormatCode);
|
|
192
|
+
}
|
|
32
193
|
const FIRST_CUSTOM_NUM_FMT_ID = 164;
|
|
33
194
|
const DEFAULT_CELL_FORMAT_INDEX = 0;
|
|
34
|
-
|
|
195
|
+
const NONE_FILL_INDEX = 0;
|
|
196
|
+
const GRAY125_FILL_INDEX = 1;
|
|
197
|
+
const FIRST_REAL_FILL_INDEX = 2;
|
|
198
|
+
const EMPTY_BORDER_INDEX = 0;
|
|
199
|
+
const FIRST_REAL_BORDER_INDEX = 1;
|
|
200
|
+
function signatureOfNumberFormat(format) {
|
|
35
201
|
return format.kind === "builtin" ? `builtin:${format.id}` : `custom:${format.code}`;
|
|
36
202
|
}
|
|
203
|
+
const EMPTY_DECORATION = {};
|
|
204
|
+
function signatureOfDecoration(decoration) {
|
|
205
|
+
let sig = "";
|
|
206
|
+
if (decoration.background !== void 0) sig += `|bg:${(0, document_schema_js.colorToRgbHex)(decoration.background)}`;
|
|
207
|
+
const borders = decoration.borders;
|
|
208
|
+
if (borders !== void 0) for (const edge of [
|
|
209
|
+
"left",
|
|
210
|
+
"right",
|
|
211
|
+
"top",
|
|
212
|
+
"bottom"
|
|
213
|
+
]) {
|
|
214
|
+
const border = borders[edge];
|
|
215
|
+
if (border !== void 0) sig += `|${edge}:${border.style ?? "solid"}:${(0, document_schema_js.colorToRgbHex)(border.color)}:${border.widthPt.toFixed(4)}`;
|
|
216
|
+
}
|
|
217
|
+
if (decoration.alignment !== void 0) sig += `|h:${decoration.alignment}`;
|
|
218
|
+
if (decoration.verticalAlignment !== void 0) sig += `|v:${decoration.verticalAlignment}`;
|
|
219
|
+
return sig;
|
|
220
|
+
}
|
|
221
|
+
function borderToXlsxStyle(border) {
|
|
222
|
+
switch (border.style) {
|
|
223
|
+
case "double": return "double";
|
|
224
|
+
case "dotted": return "dotted";
|
|
225
|
+
case "dashed": return border.widthPt >= BORDER_WEIGHT_UPPER_PT.thin ? "mediumDashed" : "dashed";
|
|
226
|
+
case "solid":
|
|
227
|
+
case void 0:
|
|
228
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.hair) return "hair";
|
|
229
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.thin) return "thin";
|
|
230
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.medium) return "medium";
|
|
231
|
+
return "thick";
|
|
232
|
+
}
|
|
233
|
+
}
|
|
37
234
|
var CellFormatTable = class {
|
|
38
|
-
indexBySignature = /* @__PURE__ */ new Map([[
|
|
235
|
+
indexBySignature = /* @__PURE__ */ new Map([[signatureOfNumberFormat({
|
|
39
236
|
kind: "builtin",
|
|
40
237
|
id: 0
|
|
41
|
-
}), 0]]);
|
|
42
|
-
|
|
238
|
+
}) + signatureOfDecoration(EMPTY_DECORATION), 0]]);
|
|
239
|
+
records = [{
|
|
240
|
+
numFmtId: 0,
|
|
241
|
+
fillId: NONE_FILL_INDEX,
|
|
242
|
+
borderId: EMPTY_BORDER_INDEX
|
|
243
|
+
}];
|
|
43
244
|
declared = [];
|
|
44
|
-
|
|
45
|
-
|
|
245
|
+
fillIndexByRgb = /* @__PURE__ */ new Map();
|
|
246
|
+
fills = [{ patternType: "none" }, { patternType: "gray125" }];
|
|
247
|
+
borderIndexBySignature = /* @__PURE__ */ new Map();
|
|
248
|
+
borders = [{ edges: {} }];
|
|
249
|
+
intern(format, decoration = EMPTY_DECORATION) {
|
|
250
|
+
const signature = signatureOfNumberFormat(format) + signatureOfDecoration(decoration);
|
|
46
251
|
const existing = this.indexBySignature.get(signature);
|
|
47
252
|
if (existing !== void 0) return existing;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
253
|
+
const record = {
|
|
254
|
+
numFmtId: format.kind === "builtin" ? format.id : this.declareNumberFormat(format.code),
|
|
255
|
+
fillId: decoration.background === void 0 ? NONE_FILL_INDEX : this.internFill(decoration.background),
|
|
256
|
+
borderId: decoration.borders === void 0 ? EMPTY_BORDER_INDEX : this.internBorder(decoration.borders)
|
|
257
|
+
};
|
|
258
|
+
if (decoration.alignment !== void 0 || decoration.verticalAlignment !== void 0) record.alignment = {
|
|
259
|
+
horizontal: decoration.alignment,
|
|
260
|
+
vertical: decoration.verticalAlignment
|
|
261
|
+
};
|
|
262
|
+
const index = this.records.length;
|
|
263
|
+
this.records.push(record);
|
|
51
264
|
this.indexBySignature.set(signature, index);
|
|
52
265
|
return index;
|
|
53
266
|
}
|
|
@@ -55,9 +268,18 @@ var CellFormatTable = class {
|
|
|
55
268
|
return this.declared;
|
|
56
269
|
}
|
|
57
270
|
cellFormats() {
|
|
58
|
-
return this.
|
|
271
|
+
return this.records.map((record) => record.numFmtId);
|
|
59
272
|
}
|
|
60
|
-
|
|
273
|
+
cellFormatRecords() {
|
|
274
|
+
return this.records;
|
|
275
|
+
}
|
|
276
|
+
fillDeclarations() {
|
|
277
|
+
return this.fills;
|
|
278
|
+
}
|
|
279
|
+
borderDeclarations() {
|
|
280
|
+
return this.borders;
|
|
281
|
+
}
|
|
282
|
+
declareNumberFormat(code) {
|
|
61
283
|
const id = FIRST_CUSTOM_NUM_FMT_ID + this.declared.length;
|
|
62
284
|
this.declared.push({
|
|
63
285
|
id,
|
|
@@ -65,9 +287,60 @@ var CellFormatTable = class {
|
|
|
65
287
|
});
|
|
66
288
|
return id;
|
|
67
289
|
}
|
|
290
|
+
internFill(background) {
|
|
291
|
+
const rgb = (0, document_schema_js.colorToRgbHex)(background);
|
|
292
|
+
const existing = this.fillIndexByRgb.get(rgb);
|
|
293
|
+
if (existing !== void 0) return existing;
|
|
294
|
+
const index = this.fills.length;
|
|
295
|
+
this.fills.push({
|
|
296
|
+
patternType: "solid",
|
|
297
|
+
rgb
|
|
298
|
+
});
|
|
299
|
+
this.fillIndexByRgb.set(rgb, index);
|
|
300
|
+
return index;
|
|
301
|
+
}
|
|
302
|
+
internBorder(borders) {
|
|
303
|
+
const edges = {};
|
|
304
|
+
let signature = "";
|
|
305
|
+
for (const edge of [
|
|
306
|
+
"left",
|
|
307
|
+
"right",
|
|
308
|
+
"top",
|
|
309
|
+
"bottom"
|
|
310
|
+
]) {
|
|
311
|
+
const border = borders[edge];
|
|
312
|
+
if (border !== void 0) {
|
|
313
|
+
const style = borderToXlsxStyle(border);
|
|
314
|
+
const rgb = (0, document_schema_js.colorToRgbHex)(border.color);
|
|
315
|
+
edges[edge] = {
|
|
316
|
+
style,
|
|
317
|
+
rgb
|
|
318
|
+
};
|
|
319
|
+
signature += `|${edge}:${style}:${rgb}`;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const existing = this.borderIndexBySignature.get(signature);
|
|
323
|
+
if (existing !== void 0) return existing;
|
|
324
|
+
const index = this.borders.length;
|
|
325
|
+
this.borders.push({ edges });
|
|
326
|
+
this.borderIndexBySignature.set(signature, index);
|
|
327
|
+
return index;
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
const RESERVED_FILL_INDICES = {
|
|
331
|
+
none: NONE_FILL_INDEX,
|
|
332
|
+
gray125: GRAY125_FILL_INDEX,
|
|
333
|
+
firstReal: FIRST_REAL_FILL_INDEX
|
|
334
|
+
};
|
|
335
|
+
const RESERVED_BORDER_INDICES = {
|
|
336
|
+
empty: EMPTY_BORDER_INDEX,
|
|
337
|
+
firstReal: FIRST_REAL_BORDER_INDEX
|
|
68
338
|
};
|
|
69
339
|
//#endregion
|
|
70
340
|
exports.CellFormatTable = CellFormatTable;
|
|
71
341
|
exports.DEFAULT_CELL_FORMAT_INDEX = DEFAULT_CELL_FORMAT_INDEX;
|
|
72
342
|
exports.GENERAL_NUM_FMT_ID = GENERAL_NUM_FMT_ID;
|
|
343
|
+
exports.RESERVED_BORDER_INDICES = RESERVED_BORDER_INDICES;
|
|
344
|
+
exports.RESERVED_FILL_INDICES = RESERVED_FILL_INDICES;
|
|
73
345
|
exports.readCellFormatCodes = readCellFormatCodes;
|
|
346
|
+
exports.readCellStyles = readCellStyles;
|
|
@@ -1,21 +1,87 @@
|
|
|
1
1
|
import { r as Package } from "../../package-L24lkba-.cjs";
|
|
2
2
|
import { CellNumberFormat } from "./number-format.cjs";
|
|
3
|
+
import { Alignment, Color, ContentCellBorders } from "document-schema.js";
|
|
3
4
|
//#region src/typed/xlsx/styles.d.ts
|
|
4
5
|
declare const GENERAL_NUM_FMT_ID = 0;
|
|
6
|
+
interface CellStyleEntry {
|
|
7
|
+
numberFormatCode?: string;
|
|
8
|
+
background?: Color;
|
|
9
|
+
borders?: ContentCellBorders;
|
|
10
|
+
alignment?: Alignment;
|
|
11
|
+
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
12
|
+
}
|
|
13
|
+
declare function readCellStyles(pkg: Package): readonly CellStyleEntry[];
|
|
5
14
|
declare function readCellFormatCodes(pkg: Package): readonly (string | undefined)[];
|
|
6
15
|
declare const DEFAULT_CELL_FORMAT_INDEX = 0;
|
|
7
16
|
interface DeclaredNumberFormat {
|
|
8
17
|
id: number;
|
|
9
18
|
code: string;
|
|
10
19
|
}
|
|
20
|
+
interface CellFormatDecoration {
|
|
21
|
+
background?: Color;
|
|
22
|
+
borders?: ContentCellBorders;
|
|
23
|
+
alignment?: Alignment;
|
|
24
|
+
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
25
|
+
}
|
|
26
|
+
interface DeclaredFill {
|
|
27
|
+
patternType: 'none' | 'gray125' | 'solid';
|
|
28
|
+
rgb?: string;
|
|
29
|
+
}
|
|
30
|
+
interface DeclaredBorder {
|
|
31
|
+
edges: {
|
|
32
|
+
left?: {
|
|
33
|
+
style: string;
|
|
34
|
+
rgb: string;
|
|
35
|
+
};
|
|
36
|
+
right?: {
|
|
37
|
+
style: string;
|
|
38
|
+
rgb: string;
|
|
39
|
+
};
|
|
40
|
+
top?: {
|
|
41
|
+
style: string;
|
|
42
|
+
rgb: string;
|
|
43
|
+
};
|
|
44
|
+
bottom?: {
|
|
45
|
+
style: string;
|
|
46
|
+
rgb: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
interface CellFormatRecord {
|
|
51
|
+
numFmtId: number;
|
|
52
|
+
fillId: number;
|
|
53
|
+
borderId: number;
|
|
54
|
+
alignment?: {
|
|
55
|
+
horizontal?: Alignment;
|
|
56
|
+
vertical?: 'top' | 'middle' | 'bottom';
|
|
57
|
+
};
|
|
58
|
+
}
|
|
11
59
|
declare class CellFormatTable {
|
|
12
60
|
private readonly indexBySignature;
|
|
13
|
-
private readonly
|
|
61
|
+
private readonly records;
|
|
14
62
|
private readonly declared;
|
|
15
|
-
|
|
63
|
+
private readonly fillIndexByRgb;
|
|
64
|
+
private readonly fills;
|
|
65
|
+
private readonly borderIndexBySignature;
|
|
66
|
+
private readonly borders;
|
|
67
|
+
intern(format: CellNumberFormat, decoration?: CellFormatDecoration): number;
|
|
16
68
|
declarations(): readonly DeclaredNumberFormat[];
|
|
17
69
|
cellFormats(): readonly number[];
|
|
18
|
-
|
|
70
|
+
cellFormatRecords(): readonly CellFormatRecord[];
|
|
71
|
+
fillDeclarations(): readonly DeclaredFill[];
|
|
72
|
+
borderDeclarations(): readonly DeclaredBorder[];
|
|
73
|
+
private declareNumberFormat;
|
|
74
|
+
private internFill;
|
|
75
|
+
private internBorder;
|
|
19
76
|
}
|
|
77
|
+
declare const RESERVED_FILL_INDICES: {
|
|
78
|
+
readonly none: 0;
|
|
79
|
+
readonly gray125: 1;
|
|
80
|
+
readonly firstReal: 2;
|
|
81
|
+
};
|
|
82
|
+
declare const RESERVED_BORDER_INDICES: {
|
|
83
|
+
readonly empty: 0;
|
|
84
|
+
readonly firstReal: 1;
|
|
85
|
+
};
|
|
20
86
|
//#endregion
|
|
21
|
-
export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, readCellFormatCodes };
|
|
87
|
+
export { CellFormatDecoration, CellFormatRecord, CellFormatTable, CellStyleEntry, DEFAULT_CELL_FORMAT_INDEX, DeclaredBorder, DeclaredFill, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES, readCellFormatCodes, readCellStyles };
|
|
@@ -1,21 +1,87 @@
|
|
|
1
1
|
import { r as Package } from "../../package-BUojjTXf.js";
|
|
2
2
|
import { CellNumberFormat } from "./number-format.js";
|
|
3
|
+
import { Alignment, Color, ContentCellBorders } from "document-schema.js";
|
|
3
4
|
//#region src/typed/xlsx/styles.d.ts
|
|
4
5
|
declare const GENERAL_NUM_FMT_ID = 0;
|
|
6
|
+
interface CellStyleEntry {
|
|
7
|
+
numberFormatCode?: string;
|
|
8
|
+
background?: Color;
|
|
9
|
+
borders?: ContentCellBorders;
|
|
10
|
+
alignment?: Alignment;
|
|
11
|
+
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
12
|
+
}
|
|
13
|
+
declare function readCellStyles(pkg: Package): readonly CellStyleEntry[];
|
|
5
14
|
declare function readCellFormatCodes(pkg: Package): readonly (string | undefined)[];
|
|
6
15
|
declare const DEFAULT_CELL_FORMAT_INDEX = 0;
|
|
7
16
|
interface DeclaredNumberFormat {
|
|
8
17
|
id: number;
|
|
9
18
|
code: string;
|
|
10
19
|
}
|
|
20
|
+
interface CellFormatDecoration {
|
|
21
|
+
background?: Color;
|
|
22
|
+
borders?: ContentCellBorders;
|
|
23
|
+
alignment?: Alignment;
|
|
24
|
+
verticalAlignment?: 'top' | 'middle' | 'bottom';
|
|
25
|
+
}
|
|
26
|
+
interface DeclaredFill {
|
|
27
|
+
patternType: 'none' | 'gray125' | 'solid';
|
|
28
|
+
rgb?: string;
|
|
29
|
+
}
|
|
30
|
+
interface DeclaredBorder {
|
|
31
|
+
edges: {
|
|
32
|
+
left?: {
|
|
33
|
+
style: string;
|
|
34
|
+
rgb: string;
|
|
35
|
+
};
|
|
36
|
+
right?: {
|
|
37
|
+
style: string;
|
|
38
|
+
rgb: string;
|
|
39
|
+
};
|
|
40
|
+
top?: {
|
|
41
|
+
style: string;
|
|
42
|
+
rgb: string;
|
|
43
|
+
};
|
|
44
|
+
bottom?: {
|
|
45
|
+
style: string;
|
|
46
|
+
rgb: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
interface CellFormatRecord {
|
|
51
|
+
numFmtId: number;
|
|
52
|
+
fillId: number;
|
|
53
|
+
borderId: number;
|
|
54
|
+
alignment?: {
|
|
55
|
+
horizontal?: Alignment;
|
|
56
|
+
vertical?: 'top' | 'middle' | 'bottom';
|
|
57
|
+
};
|
|
58
|
+
}
|
|
11
59
|
declare class CellFormatTable {
|
|
12
60
|
private readonly indexBySignature;
|
|
13
|
-
private readonly
|
|
61
|
+
private readonly records;
|
|
14
62
|
private readonly declared;
|
|
15
|
-
|
|
63
|
+
private readonly fillIndexByRgb;
|
|
64
|
+
private readonly fills;
|
|
65
|
+
private readonly borderIndexBySignature;
|
|
66
|
+
private readonly borders;
|
|
67
|
+
intern(format: CellNumberFormat, decoration?: CellFormatDecoration): number;
|
|
16
68
|
declarations(): readonly DeclaredNumberFormat[];
|
|
17
69
|
cellFormats(): readonly number[];
|
|
18
|
-
|
|
70
|
+
cellFormatRecords(): readonly CellFormatRecord[];
|
|
71
|
+
fillDeclarations(): readonly DeclaredFill[];
|
|
72
|
+
borderDeclarations(): readonly DeclaredBorder[];
|
|
73
|
+
private declareNumberFormat;
|
|
74
|
+
private internFill;
|
|
75
|
+
private internBorder;
|
|
19
76
|
}
|
|
77
|
+
declare const RESERVED_FILL_INDICES: {
|
|
78
|
+
readonly none: 0;
|
|
79
|
+
readonly gray125: 1;
|
|
80
|
+
readonly firstReal: 2;
|
|
81
|
+
};
|
|
82
|
+
declare const RESERVED_BORDER_INDICES: {
|
|
83
|
+
readonly empty: 0;
|
|
84
|
+
readonly firstReal: 1;
|
|
85
|
+
};
|
|
20
86
|
//#endregion
|
|
21
|
-
export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, readCellFormatCodes };
|
|
87
|
+
export { CellFormatDecoration, CellFormatRecord, CellFormatTable, CellStyleEntry, DEFAULT_CELL_FORMAT_INDEX, DeclaredBorder, DeclaredFill, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES, readCellFormatCodes, readCellStyles };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { attr, childrenWithTag, decodeEntities, rootElement } from "../util.js";
|
|
2
2
|
import { BUILTIN_NUMBER_FORMATS } from "./number-format.js";
|
|
3
|
+
import { colorToRgbHex, rgbHexToColor } from "document-schema.js";
|
|
3
4
|
//#region src/typed/xlsx/styles.ts
|
|
4
5
|
const STYLES_PATH = "xl/styles.xml";
|
|
5
6
|
const GENERAL_NUM_FMT_ID = 0;
|
|
@@ -16,37 +17,249 @@ function readNumberFormatCodesById(styleSheet) {
|
|
|
16
17
|
}
|
|
17
18
|
return codes;
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
const BORDER_WIDTH_PT = {
|
|
21
|
+
hair: .5,
|
|
22
|
+
thin: .75,
|
|
23
|
+
medium: 1.5,
|
|
24
|
+
thick: 2.25
|
|
25
|
+
};
|
|
26
|
+
const XLSX_BORDER_STYLE = {
|
|
27
|
+
thin: {
|
|
28
|
+
weight: "thin",
|
|
29
|
+
pattern: "solid"
|
|
30
|
+
},
|
|
31
|
+
medium: {
|
|
32
|
+
weight: "medium",
|
|
33
|
+
pattern: "solid"
|
|
34
|
+
},
|
|
35
|
+
thick: {
|
|
36
|
+
weight: "thick",
|
|
37
|
+
pattern: "solid"
|
|
38
|
+
},
|
|
39
|
+
hair: {
|
|
40
|
+
weight: "hair",
|
|
41
|
+
pattern: "solid"
|
|
42
|
+
},
|
|
43
|
+
dashed: {
|
|
44
|
+
weight: "thin",
|
|
45
|
+
pattern: "dashed"
|
|
46
|
+
},
|
|
47
|
+
dotted: {
|
|
48
|
+
weight: "thin",
|
|
49
|
+
pattern: "dotted"
|
|
50
|
+
},
|
|
51
|
+
double: {
|
|
52
|
+
weight: "thin",
|
|
53
|
+
pattern: "double"
|
|
54
|
+
},
|
|
55
|
+
mediumDashed: {
|
|
56
|
+
weight: "medium",
|
|
57
|
+
pattern: "dashed"
|
|
58
|
+
},
|
|
59
|
+
dashDot: {
|
|
60
|
+
weight: "thin",
|
|
61
|
+
pattern: "dashed"
|
|
62
|
+
},
|
|
63
|
+
mediumDashDot: {
|
|
64
|
+
weight: "medium",
|
|
65
|
+
pattern: "dashed"
|
|
66
|
+
},
|
|
67
|
+
dashDotDot: {
|
|
68
|
+
weight: "thin",
|
|
69
|
+
pattern: "dashed"
|
|
70
|
+
},
|
|
71
|
+
mediumDashDotDot: {
|
|
72
|
+
weight: "medium",
|
|
73
|
+
pattern: "dashed"
|
|
74
|
+
},
|
|
75
|
+
slantDashDot: {
|
|
76
|
+
weight: "medium",
|
|
77
|
+
pattern: "dashed"
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const BORDER_WEIGHT_UPPER_PT = {
|
|
81
|
+
hair: .625,
|
|
82
|
+
thin: 1.125,
|
|
83
|
+
medium: 1.875
|
|
84
|
+
};
|
|
85
|
+
function readColorRgb(container, colorTag) {
|
|
86
|
+
const colorEl = childrenWithTag(container, colorTag)[0];
|
|
87
|
+
if (colorEl === void 0) return;
|
|
88
|
+
const raw = attr(colorEl, "rgb");
|
|
89
|
+
if (raw === void 0) return;
|
|
90
|
+
const hex = raw.length >= 6 ? raw.slice(-6) : raw;
|
|
91
|
+
if (!/^[0-9a-fA-F]{6}$/.test(hex)) return;
|
|
92
|
+
try {
|
|
93
|
+
return rgbHexToColor(hex);
|
|
94
|
+
} catch {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function readFillBackground(fill) {
|
|
99
|
+
const patternFill = childrenWithTag(fill, "patternFill")[0];
|
|
100
|
+
if (patternFill === void 0 || attr(patternFill, "patternType") !== "solid") return;
|
|
101
|
+
return readColorRgb(patternFill, "fgColor") ?? readColorRgb(patternFill, "bgColor");
|
|
102
|
+
}
|
|
103
|
+
function readFills(styleSheet) {
|
|
104
|
+
const fillsEl = childrenWithTag(styleSheet, "fills")[0];
|
|
105
|
+
if (fillsEl === void 0) return [];
|
|
106
|
+
return childrenWithTag(fillsEl, "fill").map(readFillBackground);
|
|
107
|
+
}
|
|
108
|
+
function readBorderEdge(border, edge) {
|
|
109
|
+
const edgeEl = childrenWithTag(border, edge)[0];
|
|
110
|
+
if (edgeEl === void 0) return;
|
|
111
|
+
const styleToken = attr(edgeEl, "style");
|
|
112
|
+
if (styleToken === void 0 || styleToken === "none") return;
|
|
113
|
+
const resolved = XLSX_BORDER_STYLE[styleToken];
|
|
114
|
+
if (resolved === void 0) return;
|
|
115
|
+
const color = readColorRgb(edgeEl, "color");
|
|
116
|
+
if (color === void 0) return;
|
|
117
|
+
const result = {
|
|
118
|
+
color,
|
|
119
|
+
widthPt: BORDER_WIDTH_PT[resolved.weight]
|
|
120
|
+
};
|
|
121
|
+
if (resolved.pattern !== "solid") result.style = resolved.pattern;
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
function readBorders(styleSheet) {
|
|
125
|
+
const bordersEl = childrenWithTag(styleSheet, "borders")[0];
|
|
126
|
+
if (bordersEl === void 0) return [];
|
|
127
|
+
return childrenWithTag(bordersEl, "border").map((border) => {
|
|
128
|
+
const left = readBorderEdge(border, "left");
|
|
129
|
+
const right = readBorderEdge(border, "right");
|
|
130
|
+
const top = readBorderEdge(border, "top");
|
|
131
|
+
const bottom = readBorderEdge(border, "bottom");
|
|
132
|
+
if (left === void 0 && right === void 0 && top === void 0 && bottom === void 0) return;
|
|
133
|
+
const result = {};
|
|
134
|
+
if (left !== void 0) result.left = left;
|
|
135
|
+
if (right !== void 0) result.right = right;
|
|
136
|
+
if (top !== void 0) result.top = top;
|
|
137
|
+
if (bottom !== void 0) result.bottom = bottom;
|
|
138
|
+
return result;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function readHorizontalAlignment(alignment) {
|
|
142
|
+
const value = attr(alignment, "horizontal");
|
|
143
|
+
if (value === "left" || value === "center" || value === "right" || value === "justify") return value;
|
|
144
|
+
}
|
|
145
|
+
function readVerticalAlignment(alignment) {
|
|
146
|
+
const value = attr(alignment, "vertical");
|
|
147
|
+
if (value === "top") return "top";
|
|
148
|
+
if (value === "center") return "middle";
|
|
149
|
+
}
|
|
150
|
+
function readAlignment(xf) {
|
|
151
|
+
const alignment = childrenWithTag(xf, "alignment")[0];
|
|
152
|
+
if (alignment === void 0) return {};
|
|
153
|
+
return {
|
|
154
|
+
alignment: readHorizontalAlignment(alignment),
|
|
155
|
+
verticalAlignment: readVerticalAlignment(alignment)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function readCellStyles(pkg) {
|
|
20
159
|
const styleSheet = rootElement(pkg.parts[STYLES_PATH]);
|
|
21
160
|
if (styleSheet === void 0) return [];
|
|
22
161
|
const cellXfsEl = childrenWithTag(styleSheet, "cellXfs")[0];
|
|
23
162
|
if (cellXfsEl === void 0) return [];
|
|
24
163
|
const codes = readNumberFormatCodesById(styleSheet);
|
|
164
|
+
const fills = readFills(styleSheet);
|
|
165
|
+
const borders = readBorders(styleSheet);
|
|
25
166
|
return childrenWithTag(cellXfsEl, "xf").map((xf) => {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
167
|
+
const numFmtRaw = attr(xf, "numFmtId");
|
|
168
|
+
const numFmtId = numFmtRaw === void 0 ? 0 : Number.parseInt(numFmtRaw, 10);
|
|
169
|
+
const entry = {};
|
|
170
|
+
if (Number.isInteger(numFmtId)) {
|
|
171
|
+
const code = codes.get(numFmtId);
|
|
172
|
+
if (code !== void 0) entry.numberFormatCode = code;
|
|
173
|
+
}
|
|
174
|
+
const fillId = parseChildIndex(attr(xf, "fillId"));
|
|
175
|
+
if (fillId !== void 0) entry.background = fills[fillId];
|
|
176
|
+
const borderId = parseChildIndex(attr(xf, "borderId"));
|
|
177
|
+
if (borderId !== void 0) entry.borders = borders[borderId];
|
|
178
|
+
const { alignment, verticalAlignment } = readAlignment(xf);
|
|
179
|
+
if (alignment !== void 0) entry.alignment = alignment;
|
|
180
|
+
if (verticalAlignment !== void 0) entry.verticalAlignment = verticalAlignment;
|
|
181
|
+
return entry;
|
|
29
182
|
});
|
|
30
183
|
}
|
|
184
|
+
function parseChildIndex(value) {
|
|
185
|
+
if (value === void 0) return;
|
|
186
|
+
const n = Number.parseInt(value, 10);
|
|
187
|
+
return Number.isInteger(n) ? n : void 0;
|
|
188
|
+
}
|
|
189
|
+
function readCellFormatCodes(pkg) {
|
|
190
|
+
return readCellStyles(pkg).map((entry) => entry.numberFormatCode);
|
|
191
|
+
}
|
|
31
192
|
const FIRST_CUSTOM_NUM_FMT_ID = 164;
|
|
32
193
|
const DEFAULT_CELL_FORMAT_INDEX = 0;
|
|
33
|
-
|
|
194
|
+
const NONE_FILL_INDEX = 0;
|
|
195
|
+
const GRAY125_FILL_INDEX = 1;
|
|
196
|
+
const FIRST_REAL_FILL_INDEX = 2;
|
|
197
|
+
const EMPTY_BORDER_INDEX = 0;
|
|
198
|
+
const FIRST_REAL_BORDER_INDEX = 1;
|
|
199
|
+
function signatureOfNumberFormat(format) {
|
|
34
200
|
return format.kind === "builtin" ? `builtin:${format.id}` : `custom:${format.code}`;
|
|
35
201
|
}
|
|
202
|
+
const EMPTY_DECORATION = {};
|
|
203
|
+
function signatureOfDecoration(decoration) {
|
|
204
|
+
let sig = "";
|
|
205
|
+
if (decoration.background !== void 0) sig += `|bg:${colorToRgbHex(decoration.background)}`;
|
|
206
|
+
const borders = decoration.borders;
|
|
207
|
+
if (borders !== void 0) for (const edge of [
|
|
208
|
+
"left",
|
|
209
|
+
"right",
|
|
210
|
+
"top",
|
|
211
|
+
"bottom"
|
|
212
|
+
]) {
|
|
213
|
+
const border = borders[edge];
|
|
214
|
+
if (border !== void 0) sig += `|${edge}:${border.style ?? "solid"}:${colorToRgbHex(border.color)}:${border.widthPt.toFixed(4)}`;
|
|
215
|
+
}
|
|
216
|
+
if (decoration.alignment !== void 0) sig += `|h:${decoration.alignment}`;
|
|
217
|
+
if (decoration.verticalAlignment !== void 0) sig += `|v:${decoration.verticalAlignment}`;
|
|
218
|
+
return sig;
|
|
219
|
+
}
|
|
220
|
+
function borderToXlsxStyle(border) {
|
|
221
|
+
switch (border.style) {
|
|
222
|
+
case "double": return "double";
|
|
223
|
+
case "dotted": return "dotted";
|
|
224
|
+
case "dashed": return border.widthPt >= BORDER_WEIGHT_UPPER_PT.thin ? "mediumDashed" : "dashed";
|
|
225
|
+
case "solid":
|
|
226
|
+
case void 0:
|
|
227
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.hair) return "hair";
|
|
228
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.thin) return "thin";
|
|
229
|
+
if (border.widthPt < BORDER_WEIGHT_UPPER_PT.medium) return "medium";
|
|
230
|
+
return "thick";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
36
233
|
var CellFormatTable = class {
|
|
37
|
-
indexBySignature = /* @__PURE__ */ new Map([[
|
|
234
|
+
indexBySignature = /* @__PURE__ */ new Map([[signatureOfNumberFormat({
|
|
38
235
|
kind: "builtin",
|
|
39
236
|
id: 0
|
|
40
|
-
}), 0]]);
|
|
41
|
-
|
|
237
|
+
}) + signatureOfDecoration(EMPTY_DECORATION), 0]]);
|
|
238
|
+
records = [{
|
|
239
|
+
numFmtId: 0,
|
|
240
|
+
fillId: NONE_FILL_INDEX,
|
|
241
|
+
borderId: EMPTY_BORDER_INDEX
|
|
242
|
+
}];
|
|
42
243
|
declared = [];
|
|
43
|
-
|
|
44
|
-
|
|
244
|
+
fillIndexByRgb = /* @__PURE__ */ new Map();
|
|
245
|
+
fills = [{ patternType: "none" }, { patternType: "gray125" }];
|
|
246
|
+
borderIndexBySignature = /* @__PURE__ */ new Map();
|
|
247
|
+
borders = [{ edges: {} }];
|
|
248
|
+
intern(format, decoration = EMPTY_DECORATION) {
|
|
249
|
+
const signature = signatureOfNumberFormat(format) + signatureOfDecoration(decoration);
|
|
45
250
|
const existing = this.indexBySignature.get(signature);
|
|
46
251
|
if (existing !== void 0) return existing;
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
252
|
+
const record = {
|
|
253
|
+
numFmtId: format.kind === "builtin" ? format.id : this.declareNumberFormat(format.code),
|
|
254
|
+
fillId: decoration.background === void 0 ? NONE_FILL_INDEX : this.internFill(decoration.background),
|
|
255
|
+
borderId: decoration.borders === void 0 ? EMPTY_BORDER_INDEX : this.internBorder(decoration.borders)
|
|
256
|
+
};
|
|
257
|
+
if (decoration.alignment !== void 0 || decoration.verticalAlignment !== void 0) record.alignment = {
|
|
258
|
+
horizontal: decoration.alignment,
|
|
259
|
+
vertical: decoration.verticalAlignment
|
|
260
|
+
};
|
|
261
|
+
const index = this.records.length;
|
|
262
|
+
this.records.push(record);
|
|
50
263
|
this.indexBySignature.set(signature, index);
|
|
51
264
|
return index;
|
|
52
265
|
}
|
|
@@ -54,9 +267,18 @@ var CellFormatTable = class {
|
|
|
54
267
|
return this.declared;
|
|
55
268
|
}
|
|
56
269
|
cellFormats() {
|
|
57
|
-
return this.
|
|
270
|
+
return this.records.map((record) => record.numFmtId);
|
|
58
271
|
}
|
|
59
|
-
|
|
272
|
+
cellFormatRecords() {
|
|
273
|
+
return this.records;
|
|
274
|
+
}
|
|
275
|
+
fillDeclarations() {
|
|
276
|
+
return this.fills;
|
|
277
|
+
}
|
|
278
|
+
borderDeclarations() {
|
|
279
|
+
return this.borders;
|
|
280
|
+
}
|
|
281
|
+
declareNumberFormat(code) {
|
|
60
282
|
const id = FIRST_CUSTOM_NUM_FMT_ID + this.declared.length;
|
|
61
283
|
this.declared.push({
|
|
62
284
|
id,
|
|
@@ -64,6 +286,54 @@ var CellFormatTable = class {
|
|
|
64
286
|
});
|
|
65
287
|
return id;
|
|
66
288
|
}
|
|
289
|
+
internFill(background) {
|
|
290
|
+
const rgb = colorToRgbHex(background);
|
|
291
|
+
const existing = this.fillIndexByRgb.get(rgb);
|
|
292
|
+
if (existing !== void 0) return existing;
|
|
293
|
+
const index = this.fills.length;
|
|
294
|
+
this.fills.push({
|
|
295
|
+
patternType: "solid",
|
|
296
|
+
rgb
|
|
297
|
+
});
|
|
298
|
+
this.fillIndexByRgb.set(rgb, index);
|
|
299
|
+
return index;
|
|
300
|
+
}
|
|
301
|
+
internBorder(borders) {
|
|
302
|
+
const edges = {};
|
|
303
|
+
let signature = "";
|
|
304
|
+
for (const edge of [
|
|
305
|
+
"left",
|
|
306
|
+
"right",
|
|
307
|
+
"top",
|
|
308
|
+
"bottom"
|
|
309
|
+
]) {
|
|
310
|
+
const border = borders[edge];
|
|
311
|
+
if (border !== void 0) {
|
|
312
|
+
const style = borderToXlsxStyle(border);
|
|
313
|
+
const rgb = colorToRgbHex(border.color);
|
|
314
|
+
edges[edge] = {
|
|
315
|
+
style,
|
|
316
|
+
rgb
|
|
317
|
+
};
|
|
318
|
+
signature += `|${edge}:${style}:${rgb}`;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
const existing = this.borderIndexBySignature.get(signature);
|
|
322
|
+
if (existing !== void 0) return existing;
|
|
323
|
+
const index = this.borders.length;
|
|
324
|
+
this.borders.push({ edges });
|
|
325
|
+
this.borderIndexBySignature.set(signature, index);
|
|
326
|
+
return index;
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
const RESERVED_FILL_INDICES = {
|
|
330
|
+
none: NONE_FILL_INDEX,
|
|
331
|
+
gray125: GRAY125_FILL_INDEX,
|
|
332
|
+
firstReal: FIRST_REAL_FILL_INDEX
|
|
333
|
+
};
|
|
334
|
+
const RESERVED_BORDER_INDICES = {
|
|
335
|
+
empty: EMPTY_BORDER_INDEX,
|
|
336
|
+
firstReal: FIRST_REAL_BORDER_INDEX
|
|
67
337
|
};
|
|
68
338
|
//#endregion
|
|
69
|
-
export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, GENERAL_NUM_FMT_ID, readCellFormatCodes };
|
|
339
|
+
export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, GENERAL_NUM_FMT_ID, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES, readCellFormatCodes, readCellStyles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ooxml.js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Type-safe, lossless round-trip conversion between OOXML packages (docx, pptx, xlsx) and JSON, built on Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"license": "MIT",
|
|
70
70
|
"packageManager": "pnpm@11.6.0",
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"document-schema.js": "^2.3.
|
|
72
|
+
"document-schema.js": "^2.3.4",
|
|
73
73
|
"fast-xml-parser": "^5.10.1",
|
|
74
74
|
"fflate": "^0.8.3",
|
|
75
75
|
"zod": "^4.4.3"
|