ooxml-core 1.19.1 → 1.19.2
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/automation/index.cjs +167 -60
- package/dist/automation/index.mjs +167 -60
- package/dist/docx/embedded.cjs +4 -1
- package/dist/docx/embedded.mjs +4 -1
- package/dist/docx/index.cjs +4 -1
- package/dist/docx/index.mjs +4 -1
- package/dist/docx/load/index.cjs +4 -1
- package/dist/docx/load/index.mjs +4 -1
- package/dist/docx/write-table.d.ts.map +1 -1
- package/dist/xlsx/edit/row-autofit.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +145 -38
- package/dist/xlsx/index.mjs +145 -38
- package/dist/xlsx/layout/merge-sweep.d.ts +36 -0
- package/dist/xlsx/layout/merge-sweep.d.ts.map +1 -0
- package/dist/xlsx/layout/metrics.d.ts +5 -0
- package/dist/xlsx/layout/metrics.d.ts.map +1 -1
- package/dist/xlsx/layout/row-autofit.d.ts +6 -0
- package/dist/xlsx/layout/row-autofit.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +143 -39
- package/dist/xlsx/ui/index.mjs +143 -39
- package/package.json +2 -2
package/dist/xlsx/index.cjs
CHANGED
|
@@ -32806,9 +32806,9 @@ function toHtml(cells, theme2) {
|
|
|
32806
32806
|
for (let r = link.range.start.row; r <= link.range.end.row; r++)
|
|
32807
32807
|
for (let c2 = link.range.start.col; c2 <= link.range.end.col; c2++) links.set(`${r},${c2}`, link);
|
|
32808
32808
|
const covered = /* @__PURE__ */ new Set();
|
|
32809
|
-
const
|
|
32809
|
+
const spans3 = /* @__PURE__ */ new Map();
|
|
32810
32810
|
for (const m of cells.merges) {
|
|
32811
|
-
|
|
32811
|
+
spans3.set(`${m.start.row},${m.start.col}`, m);
|
|
32812
32812
|
for (let r = m.start.row; r <= m.end.row; r++)
|
|
32813
32813
|
for (let c2 = m.start.col; c2 <= m.end.col; c2++)
|
|
32814
32814
|
if (r !== m.start.row || c2 !== m.start.col) covered.add(`${r},${c2}`);
|
|
@@ -32820,7 +32820,7 @@ function toHtml(cells, theme2) {
|
|
|
32820
32820
|
if (covered.has(`${r},${c2}`)) continue;
|
|
32821
32821
|
const cell = cells.data[r]?.[c2] ?? null;
|
|
32822
32822
|
const attrs2 = [];
|
|
32823
|
-
const span3 =
|
|
32823
|
+
const span3 = spans3.get(`${r},${c2}`);
|
|
32824
32824
|
if (span3 && span3.end.row > span3.start.row)
|
|
32825
32825
|
attrs2.push(`rowspan="${span3.end.row - span3.start.row + 1}"`);
|
|
32826
32826
|
if (span3 && span3.end.col > span3.start.col)
|
|
@@ -35234,16 +35234,27 @@ function columnOverrides(sheet, mdw, defaultPx) {
|
|
|
35234
35234
|
}
|
|
35235
35235
|
return out;
|
|
35236
35236
|
}
|
|
35237
|
-
function
|
|
35238
|
-
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35237
|
+
function pixelScale(zoom) {
|
|
35239
35238
|
const factor = zoom / 100;
|
|
35240
|
-
|
|
35241
|
-
|
|
35239
|
+
return (px) => px > 0 ? Math.max(1, Math.round(px * factor)) : 0;
|
|
35240
|
+
}
|
|
35241
|
+
function columnAxis(sheet, mdw, scale2) {
|
|
35242
35242
|
const defaultColPx = defaultColumnPixels(sheet.defaultColWidth, mdw);
|
|
35243
35243
|
const colOverrides = [...columnOverrides(sheet, mdw, defaultColPx)].map(
|
|
35244
35244
|
([c2, px]) => [c2, scale2(px)]
|
|
35245
35245
|
);
|
|
35246
|
-
|
|
35246
|
+
return new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
|
|
35247
|
+
}
|
|
35248
|
+
function createColumnWidths(sheet, options2 = {}) {
|
|
35249
|
+
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35250
|
+
const cols = columnAxis(sheet, options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH, pixelScale(zoom));
|
|
35251
|
+
return (c2) => cols.size(c2);
|
|
35252
|
+
}
|
|
35253
|
+
function createGridMetrics(sheet, options2 = {}) {
|
|
35254
|
+
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35255
|
+
const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
|
|
35256
|
+
const scale2 = pixelScale(zoom);
|
|
35257
|
+
const cols = columnAxis(sheet, mdw, scale2);
|
|
35247
35258
|
const defaultRowPx = pointsToPixels(sheet.defaultRowHeight);
|
|
35248
35259
|
const rowOverrides = [];
|
|
35249
35260
|
for (const [r, info] of sheet.rowInfo) {
|
|
@@ -39596,6 +39607,87 @@ function cellView(workbook, sheetIndex2, row2, col, cf, options2 = {}) {
|
|
|
39596
39607
|
return view;
|
|
39597
39608
|
}
|
|
39598
39609
|
|
|
39610
|
+
// xlsx/layout/merge-sweep.ts
|
|
39611
|
+
var NONE = { merged: false, spanned: false };
|
|
39612
|
+
var SINGLE2 = { merged: true, spanned: false };
|
|
39613
|
+
var SPANNED = { merged: true, spanned: true };
|
|
39614
|
+
var spans2 = (merge2) => merge2.start.row !== merge2.end.row || merge2.start.col !== merge2.end.col;
|
|
39615
|
+
function firstRightOf(merges, col) {
|
|
39616
|
+
let lo = 0;
|
|
39617
|
+
let hi = merges.length;
|
|
39618
|
+
while (lo < hi) {
|
|
39619
|
+
const mid = lo + hi >> 1;
|
|
39620
|
+
if ((merges[mid]?.start.col ?? 0) <= col) lo = mid + 1;
|
|
39621
|
+
else hi = mid;
|
|
39622
|
+
}
|
|
39623
|
+
return lo;
|
|
39624
|
+
}
|
|
39625
|
+
var MergeSweep = class {
|
|
39626
|
+
/** The merges by first row; `next` is the first one the sweep has not reached. */
|
|
39627
|
+
byRow;
|
|
39628
|
+
next = 0;
|
|
39629
|
+
row = Number.NEGATIVE_INFINITY;
|
|
39630
|
+
/** The merges covering the current row, by first column. */
|
|
39631
|
+
active = [];
|
|
39632
|
+
/** The last row of the earliest-ending active merge. */
|
|
39633
|
+
firstEnd = Number.POSITIVE_INFINITY;
|
|
39634
|
+
overlapping = false;
|
|
39635
|
+
constructor(merges) {
|
|
39636
|
+
this.byRow = [...merges].sort((a2, b) => a2.start.row - b.start.row);
|
|
39637
|
+
}
|
|
39638
|
+
/** How many merges cover the current row, which is everything the sweep holds. */
|
|
39639
|
+
get size() {
|
|
39640
|
+
return this.active.length;
|
|
39641
|
+
}
|
|
39642
|
+
/** Moves to `row`, which must not be above the previous one. */
|
|
39643
|
+
moveTo(row2) {
|
|
39644
|
+
if (row2 < this.row) throw new RangeError(`Rows must not go up: ${row2} after ${this.row}`);
|
|
39645
|
+
this.row = row2;
|
|
39646
|
+
if (row2 > this.firstEnd) this.dropEnded(row2);
|
|
39647
|
+
for (; this.next < this.byRow.length; this.next++) {
|
|
39648
|
+
const merge2 = this.byRow[this.next];
|
|
39649
|
+
if (!merge2 || merge2.start.row > row2) break;
|
|
39650
|
+
if (merge2.end.row >= row2) this.add(merge2);
|
|
39651
|
+
}
|
|
39652
|
+
}
|
|
39653
|
+
/** How the merges cover column `col` of the current row. */
|
|
39654
|
+
at(col) {
|
|
39655
|
+
if (this.overlapping) {
|
|
39656
|
+
let merged = false;
|
|
39657
|
+
for (const merge3 of this.active) {
|
|
39658
|
+
if (col < merge3.start.col || col > merge3.end.col) continue;
|
|
39659
|
+
if (spans2(merge3)) return SPANNED;
|
|
39660
|
+
merged = true;
|
|
39661
|
+
}
|
|
39662
|
+
return merged ? SINGLE2 : NONE;
|
|
39663
|
+
}
|
|
39664
|
+
const merge2 = this.active[firstRightOf(this.active, col) - 1];
|
|
39665
|
+
if (!merge2 || col > merge2.end.col) return NONE;
|
|
39666
|
+
return spans2(merge2) ? SPANNED : SINGLE2;
|
|
39667
|
+
}
|
|
39668
|
+
add(merge2) {
|
|
39669
|
+
const at = firstRightOf(this.active, merge2.start.col);
|
|
39670
|
+
const before = this.active[at - 1];
|
|
39671
|
+
const after = this.active[at];
|
|
39672
|
+
if (before && before.end.col >= merge2.start.col || after && merge2.end.col >= after.start.col)
|
|
39673
|
+
this.overlapping = true;
|
|
39674
|
+
this.active.splice(at, 0, merge2);
|
|
39675
|
+
this.firstEnd = Math.min(this.firstEnd, merge2.end.row);
|
|
39676
|
+
}
|
|
39677
|
+
dropEnded(row2) {
|
|
39678
|
+
let kept = 0;
|
|
39679
|
+
let firstEnd = Number.POSITIVE_INFINITY;
|
|
39680
|
+
for (const merge2 of this.active) {
|
|
39681
|
+
if (merge2.end.row < row2) continue;
|
|
39682
|
+
this.active[kept++] = merge2;
|
|
39683
|
+
firstEnd = Math.min(firstEnd, merge2.end.row);
|
|
39684
|
+
}
|
|
39685
|
+
this.active.length = kept;
|
|
39686
|
+
this.firstEnd = firstEnd;
|
|
39687
|
+
if (!kept) this.overlapping = false;
|
|
39688
|
+
}
|
|
39689
|
+
};
|
|
39690
|
+
|
|
39599
39691
|
// xlsx/layout/row-autofit.ts
|
|
39600
39692
|
var LINE_HEIGHTS = [
|
|
39601
39693
|
[6, 8.25],
|
|
@@ -39656,29 +39748,41 @@ function wrappedLineCount(text4, width, measure2) {
|
|
|
39656
39748
|
return lines;
|
|
39657
39749
|
}
|
|
39658
39750
|
function autoFitRowHeight(workbook, sheetIndex2, row2, measure2) {
|
|
39751
|
+
return fitRowHeights(workbook, sheetIndex2, [row2], measure2).get(row2) ?? 15;
|
|
39752
|
+
}
|
|
39753
|
+
function fitRowHeights(workbook, sheetIndex2, rows, measure2) {
|
|
39754
|
+
const heights = /* @__PURE__ */ new Map();
|
|
39659
39755
|
const sheet = workbook.sheets[sheetIndex2];
|
|
39660
|
-
if (!sheet) return
|
|
39661
|
-
const
|
|
39662
|
-
|
|
39663
|
-
|
|
39664
|
-
|
|
39665
|
-
|
|
39666
|
-
|
|
39667
|
-
|
|
39668
|
-
|
|
39669
|
-
|
|
39670
|
-
|
|
39671
|
-
|
|
39672
|
-
const
|
|
39673
|
-
|
|
39674
|
-
|
|
39675
|
-
|
|
39676
|
-
|
|
39677
|
-
|
|
39678
|
-
|
|
39679
|
-
|
|
39680
|
-
|
|
39681
|
-
|
|
39756
|
+
if (!sheet) return heights;
|
|
39757
|
+
const filled2 = [];
|
|
39758
|
+
for (const row2 of new Set(rows)) {
|
|
39759
|
+
if (sheet.rows.get(row2)?.size) filled2.push(row2);
|
|
39760
|
+
else heights.set(row2, sheet.defaultRowHeight);
|
|
39761
|
+
}
|
|
39762
|
+
filled2.sort((a2, b) => a2 - b);
|
|
39763
|
+
const merges = new MergeSweep(sheet.merges);
|
|
39764
|
+
let colWidth;
|
|
39765
|
+
for (const row2 of filled2) {
|
|
39766
|
+
merges.moveTo(row2);
|
|
39767
|
+
let tallest = 0;
|
|
39768
|
+
for (const col of sheet.rows.get(row2)?.keys() ?? []) {
|
|
39769
|
+
const cover = merges.at(col);
|
|
39770
|
+
if (cover.spanned) continue;
|
|
39771
|
+
const view = cellView(workbook, sheetIndex2, row2, col, void 0, { merged: cover.merged });
|
|
39772
|
+
if (!view.text) continue;
|
|
39773
|
+
const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
|
|
39774
|
+
const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
|
|
39775
|
+
let lines = 1;
|
|
39776
|
+
if (view.wrap) {
|
|
39777
|
+
colWidth ??= createColumnWidths(sheet, { zoom: 100 });
|
|
39778
|
+
const width = colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
|
|
39779
|
+
lines = wrappedLineCount(view.text, width, (text4) => measure2(text4, view.font));
|
|
39780
|
+
}
|
|
39781
|
+
tallest = Math.max(tallest, lines * lineHeightPoints(sizePt));
|
|
39782
|
+
}
|
|
39783
|
+
heights.set(row2, tallest > 0 ? tallest : sheet.defaultRowHeight);
|
|
39784
|
+
}
|
|
39785
|
+
return heights;
|
|
39682
39786
|
}
|
|
39683
39787
|
var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bold ? 0.58 : 0.53);
|
|
39684
39788
|
|
|
@@ -39686,13 +39790,16 @@ var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bol
|
|
|
39686
39790
|
var MAX_HEIGHT2 = 409;
|
|
39687
39791
|
function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
|
|
39688
39792
|
const sheet = sheetAt(ctx.workbook, s);
|
|
39689
|
-
const
|
|
39690
|
-
for (const row2 of new Set(rows)) {
|
|
39793
|
+
const candidates = [...new Set(rows)].filter((row2) => {
|
|
39691
39794
|
const info = sheet.rowInfo.get(row2);
|
|
39692
|
-
|
|
39693
|
-
|
|
39795
|
+
return !info?.customHeight && !info?.hidden;
|
|
39796
|
+
});
|
|
39797
|
+
const fits = fitRowHeights(ctx.workbook, s, candidates, measure2);
|
|
39798
|
+
const updates = [];
|
|
39799
|
+
for (const row2 of candidates) {
|
|
39800
|
+
const fit2 = Math.min(MAX_HEIGHT2, fits.get(row2) ?? sheet.defaultRowHeight);
|
|
39694
39801
|
const next = Math.abs(fit2 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit2;
|
|
39695
|
-
const current =
|
|
39802
|
+
const current = sheet.rowInfo.get(row2)?.height;
|
|
39696
39803
|
if (current === next) continue;
|
|
39697
39804
|
if (current !== void 0 && next !== void 0 && Math.abs(current - next) < 1e-9) continue;
|
|
39698
39805
|
updates.push([row2, next]);
|
|
@@ -44523,13 +44630,13 @@ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
|
44523
44630
|
measured ? 4 : 0
|
|
44524
44631
|
);
|
|
44525
44632
|
let baseline = 8 + (metrics[0]?.size ?? base.size ?? 14) + (vertical[0]?.before ?? 0) + (vertical[0]?.leading ?? 0);
|
|
44526
|
-
const
|
|
44633
|
+
const spans3 = [];
|
|
44527
44634
|
for (const [index3, line3] of metrics.entries()) {
|
|
44528
44635
|
if (index3)
|
|
44529
44636
|
baseline += vertical[index3 - 1].descent + vertical[index3 - 1].after + vertical[index3].before + vertical[index3].ascent;
|
|
44530
44637
|
let x = line3.align === "l" ? (width - boxWidth) / 2 + 4 : line3.align === "r" ? (width + boxWidth) / 2 - 4 - line3.width : (width - line3.width) / 2;
|
|
44531
44638
|
for (const run2 of line3.runs) {
|
|
44532
|
-
|
|
44639
|
+
spans3.push(
|
|
44533
44640
|
text3(x, baseline, run2.text, {
|
|
44534
44641
|
...run2.attrs,
|
|
44535
44642
|
anchor: "start"
|
|
@@ -44540,7 +44647,7 @@ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
|
44540
44647
|
}
|
|
44541
44648
|
const parent = text3(0, 0, "", { ...base, underline: false }).replace(
|
|
44542
44649
|
"</text>",
|
|
44543
|
-
`${
|
|
44650
|
+
`${spans3.join("")}</text>`
|
|
44544
44651
|
);
|
|
44545
44652
|
const markup = chartAreaRect(model, "title", {
|
|
44546
44653
|
x: (width - boxWidth) / 2,
|
package/dist/xlsx/index.mjs
CHANGED
|
@@ -32800,9 +32800,9 @@ function toHtml(cells, theme2) {
|
|
|
32800
32800
|
for (let r = link.range.start.row; r <= link.range.end.row; r++)
|
|
32801
32801
|
for (let c2 = link.range.start.col; c2 <= link.range.end.col; c2++) links.set(`${r},${c2}`, link);
|
|
32802
32802
|
const covered = /* @__PURE__ */ new Set();
|
|
32803
|
-
const
|
|
32803
|
+
const spans3 = /* @__PURE__ */ new Map();
|
|
32804
32804
|
for (const m of cells.merges) {
|
|
32805
|
-
|
|
32805
|
+
spans3.set(`${m.start.row},${m.start.col}`, m);
|
|
32806
32806
|
for (let r = m.start.row; r <= m.end.row; r++)
|
|
32807
32807
|
for (let c2 = m.start.col; c2 <= m.end.col; c2++)
|
|
32808
32808
|
if (r !== m.start.row || c2 !== m.start.col) covered.add(`${r},${c2}`);
|
|
@@ -32814,7 +32814,7 @@ function toHtml(cells, theme2) {
|
|
|
32814
32814
|
if (covered.has(`${r},${c2}`)) continue;
|
|
32815
32815
|
const cell = cells.data[r]?.[c2] ?? null;
|
|
32816
32816
|
const attrs2 = [];
|
|
32817
|
-
const span3 =
|
|
32817
|
+
const span3 = spans3.get(`${r},${c2}`);
|
|
32818
32818
|
if (span3 && span3.end.row > span3.start.row)
|
|
32819
32819
|
attrs2.push(`rowspan="${span3.end.row - span3.start.row + 1}"`);
|
|
32820
32820
|
if (span3 && span3.end.col > span3.start.col)
|
|
@@ -35228,16 +35228,27 @@ function columnOverrides(sheet, mdw, defaultPx) {
|
|
|
35228
35228
|
}
|
|
35229
35229
|
return out;
|
|
35230
35230
|
}
|
|
35231
|
-
function
|
|
35232
|
-
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35231
|
+
function pixelScale(zoom) {
|
|
35233
35232
|
const factor = zoom / 100;
|
|
35234
|
-
|
|
35235
|
-
|
|
35233
|
+
return (px) => px > 0 ? Math.max(1, Math.round(px * factor)) : 0;
|
|
35234
|
+
}
|
|
35235
|
+
function columnAxis(sheet, mdw, scale2) {
|
|
35236
35236
|
const defaultColPx = defaultColumnPixels(sheet.defaultColWidth, mdw);
|
|
35237
35237
|
const colOverrides = [...columnOverrides(sheet, mdw, defaultColPx)].map(
|
|
35238
35238
|
([c2, px]) => [c2, scale2(px)]
|
|
35239
35239
|
);
|
|
35240
|
-
|
|
35240
|
+
return new AxisMetrics(scale2(defaultColPx), MAX_COL + 1, colOverrides);
|
|
35241
|
+
}
|
|
35242
|
+
function createColumnWidths(sheet, options2 = {}) {
|
|
35243
|
+
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35244
|
+
const cols = columnAxis(sheet, options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH, pixelScale(zoom));
|
|
35245
|
+
return (c2) => cols.size(c2);
|
|
35246
|
+
}
|
|
35247
|
+
function createGridMetrics(sheet, options2 = {}) {
|
|
35248
|
+
const zoom = zoomPercent(options2.zoom ?? sheet.view.zoom);
|
|
35249
|
+
const mdw = options2.mdw ?? DEFAULT_MAX_DIGIT_WIDTH;
|
|
35250
|
+
const scale2 = pixelScale(zoom);
|
|
35251
|
+
const cols = columnAxis(sheet, mdw, scale2);
|
|
35241
35252
|
const defaultRowPx = pointsToPixels(sheet.defaultRowHeight);
|
|
35242
35253
|
const rowOverrides = [];
|
|
35243
35254
|
for (const [r, info] of sheet.rowInfo) {
|
|
@@ -39590,6 +39601,87 @@ function cellView(workbook, sheetIndex2, row2, col, cf, options2 = {}) {
|
|
|
39590
39601
|
return view;
|
|
39591
39602
|
}
|
|
39592
39603
|
|
|
39604
|
+
// xlsx/layout/merge-sweep.ts
|
|
39605
|
+
var NONE = { merged: false, spanned: false };
|
|
39606
|
+
var SINGLE2 = { merged: true, spanned: false };
|
|
39607
|
+
var SPANNED = { merged: true, spanned: true };
|
|
39608
|
+
var spans2 = (merge2) => merge2.start.row !== merge2.end.row || merge2.start.col !== merge2.end.col;
|
|
39609
|
+
function firstRightOf(merges, col) {
|
|
39610
|
+
let lo = 0;
|
|
39611
|
+
let hi = merges.length;
|
|
39612
|
+
while (lo < hi) {
|
|
39613
|
+
const mid = lo + hi >> 1;
|
|
39614
|
+
if ((merges[mid]?.start.col ?? 0) <= col) lo = mid + 1;
|
|
39615
|
+
else hi = mid;
|
|
39616
|
+
}
|
|
39617
|
+
return lo;
|
|
39618
|
+
}
|
|
39619
|
+
var MergeSweep = class {
|
|
39620
|
+
/** The merges by first row; `next` is the first one the sweep has not reached. */
|
|
39621
|
+
byRow;
|
|
39622
|
+
next = 0;
|
|
39623
|
+
row = Number.NEGATIVE_INFINITY;
|
|
39624
|
+
/** The merges covering the current row, by first column. */
|
|
39625
|
+
active = [];
|
|
39626
|
+
/** The last row of the earliest-ending active merge. */
|
|
39627
|
+
firstEnd = Number.POSITIVE_INFINITY;
|
|
39628
|
+
overlapping = false;
|
|
39629
|
+
constructor(merges) {
|
|
39630
|
+
this.byRow = [...merges].sort((a2, b) => a2.start.row - b.start.row);
|
|
39631
|
+
}
|
|
39632
|
+
/** How many merges cover the current row, which is everything the sweep holds. */
|
|
39633
|
+
get size() {
|
|
39634
|
+
return this.active.length;
|
|
39635
|
+
}
|
|
39636
|
+
/** Moves to `row`, which must not be above the previous one. */
|
|
39637
|
+
moveTo(row2) {
|
|
39638
|
+
if (row2 < this.row) throw new RangeError(`Rows must not go up: ${row2} after ${this.row}`);
|
|
39639
|
+
this.row = row2;
|
|
39640
|
+
if (row2 > this.firstEnd) this.dropEnded(row2);
|
|
39641
|
+
for (; this.next < this.byRow.length; this.next++) {
|
|
39642
|
+
const merge2 = this.byRow[this.next];
|
|
39643
|
+
if (!merge2 || merge2.start.row > row2) break;
|
|
39644
|
+
if (merge2.end.row >= row2) this.add(merge2);
|
|
39645
|
+
}
|
|
39646
|
+
}
|
|
39647
|
+
/** How the merges cover column `col` of the current row. */
|
|
39648
|
+
at(col) {
|
|
39649
|
+
if (this.overlapping) {
|
|
39650
|
+
let merged = false;
|
|
39651
|
+
for (const merge3 of this.active) {
|
|
39652
|
+
if (col < merge3.start.col || col > merge3.end.col) continue;
|
|
39653
|
+
if (spans2(merge3)) return SPANNED;
|
|
39654
|
+
merged = true;
|
|
39655
|
+
}
|
|
39656
|
+
return merged ? SINGLE2 : NONE;
|
|
39657
|
+
}
|
|
39658
|
+
const merge2 = this.active[firstRightOf(this.active, col) - 1];
|
|
39659
|
+
if (!merge2 || col > merge2.end.col) return NONE;
|
|
39660
|
+
return spans2(merge2) ? SPANNED : SINGLE2;
|
|
39661
|
+
}
|
|
39662
|
+
add(merge2) {
|
|
39663
|
+
const at = firstRightOf(this.active, merge2.start.col);
|
|
39664
|
+
const before = this.active[at - 1];
|
|
39665
|
+
const after = this.active[at];
|
|
39666
|
+
if (before && before.end.col >= merge2.start.col || after && merge2.end.col >= after.start.col)
|
|
39667
|
+
this.overlapping = true;
|
|
39668
|
+
this.active.splice(at, 0, merge2);
|
|
39669
|
+
this.firstEnd = Math.min(this.firstEnd, merge2.end.row);
|
|
39670
|
+
}
|
|
39671
|
+
dropEnded(row2) {
|
|
39672
|
+
let kept = 0;
|
|
39673
|
+
let firstEnd = Number.POSITIVE_INFINITY;
|
|
39674
|
+
for (const merge2 of this.active) {
|
|
39675
|
+
if (merge2.end.row < row2) continue;
|
|
39676
|
+
this.active[kept++] = merge2;
|
|
39677
|
+
firstEnd = Math.min(firstEnd, merge2.end.row);
|
|
39678
|
+
}
|
|
39679
|
+
this.active.length = kept;
|
|
39680
|
+
this.firstEnd = firstEnd;
|
|
39681
|
+
if (!kept) this.overlapping = false;
|
|
39682
|
+
}
|
|
39683
|
+
};
|
|
39684
|
+
|
|
39593
39685
|
// xlsx/layout/row-autofit.ts
|
|
39594
39686
|
var LINE_HEIGHTS = [
|
|
39595
39687
|
[6, 8.25],
|
|
@@ -39650,29 +39742,41 @@ function wrappedLineCount(text4, width, measure2) {
|
|
|
39650
39742
|
return lines;
|
|
39651
39743
|
}
|
|
39652
39744
|
function autoFitRowHeight(workbook, sheetIndex2, row2, measure2) {
|
|
39745
|
+
return fitRowHeights(workbook, sheetIndex2, [row2], measure2).get(row2) ?? 15;
|
|
39746
|
+
}
|
|
39747
|
+
function fitRowHeights(workbook, sheetIndex2, rows, measure2) {
|
|
39748
|
+
const heights = /* @__PURE__ */ new Map();
|
|
39653
39749
|
const sheet = workbook.sheets[sheetIndex2];
|
|
39654
|
-
if (!sheet) return
|
|
39655
|
-
const
|
|
39656
|
-
|
|
39657
|
-
|
|
39658
|
-
|
|
39659
|
-
|
|
39660
|
-
|
|
39661
|
-
|
|
39662
|
-
|
|
39663
|
-
|
|
39664
|
-
|
|
39665
|
-
|
|
39666
|
-
const
|
|
39667
|
-
|
|
39668
|
-
|
|
39669
|
-
|
|
39670
|
-
|
|
39671
|
-
|
|
39672
|
-
|
|
39673
|
-
|
|
39674
|
-
|
|
39675
|
-
|
|
39750
|
+
if (!sheet) return heights;
|
|
39751
|
+
const filled2 = [];
|
|
39752
|
+
for (const row2 of new Set(rows)) {
|
|
39753
|
+
if (sheet.rows.get(row2)?.size) filled2.push(row2);
|
|
39754
|
+
else heights.set(row2, sheet.defaultRowHeight);
|
|
39755
|
+
}
|
|
39756
|
+
filled2.sort((a2, b) => a2 - b);
|
|
39757
|
+
const merges = new MergeSweep(sheet.merges);
|
|
39758
|
+
let colWidth;
|
|
39759
|
+
for (const row2 of filled2) {
|
|
39760
|
+
merges.moveTo(row2);
|
|
39761
|
+
let tallest = 0;
|
|
39762
|
+
for (const col of sheet.rows.get(row2)?.keys() ?? []) {
|
|
39763
|
+
const cover = merges.at(col);
|
|
39764
|
+
if (cover.spanned) continue;
|
|
39765
|
+
const view = cellView(workbook, sheetIndex2, row2, col, void 0, { merged: cover.merged });
|
|
39766
|
+
if (!view.text) continue;
|
|
39767
|
+
const fonts = view.rich?.length ? view.rich.map((run2) => run2.font) : [view.font];
|
|
39768
|
+
const sizePt = Math.max(...fonts.map((f6) => f6.sizePx * 3 / 4));
|
|
39769
|
+
let lines = 1;
|
|
39770
|
+
if (view.wrap) {
|
|
39771
|
+
colWidth ??= createColumnWidths(sheet, { zoom: 100 });
|
|
39772
|
+
const width = colWidth(col) - COLUMN_PADDING_PX - 1 - view.indentPx;
|
|
39773
|
+
lines = wrappedLineCount(view.text, width, (text4) => measure2(text4, view.font));
|
|
39774
|
+
}
|
|
39775
|
+
tallest = Math.max(tallest, lines * lineHeightPoints(sizePt));
|
|
39776
|
+
}
|
|
39777
|
+
heights.set(row2, tallest > 0 ? tallest : sheet.defaultRowHeight);
|
|
39778
|
+
}
|
|
39779
|
+
return heights;
|
|
39676
39780
|
}
|
|
39677
39781
|
var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bold ? 0.58 : 0.53);
|
|
39678
39782
|
|
|
@@ -39680,13 +39784,16 @@ var approximateMeasure = (text4, font) => text4.length * font.sizePx * (font.bol
|
|
|
39680
39784
|
var MAX_HEIGHT2 = 409;
|
|
39681
39785
|
function autoGrowRows(ctx, s, rows, measure2 = approximateMeasure) {
|
|
39682
39786
|
const sheet = sheetAt(ctx.workbook, s);
|
|
39683
|
-
const
|
|
39684
|
-
for (const row2 of new Set(rows)) {
|
|
39787
|
+
const candidates = [...new Set(rows)].filter((row2) => {
|
|
39685
39788
|
const info = sheet.rowInfo.get(row2);
|
|
39686
|
-
|
|
39687
|
-
|
|
39789
|
+
return !info?.customHeight && !info?.hidden;
|
|
39790
|
+
});
|
|
39791
|
+
const fits = fitRowHeights(ctx.workbook, s, candidates, measure2);
|
|
39792
|
+
const updates = [];
|
|
39793
|
+
for (const row2 of candidates) {
|
|
39794
|
+
const fit2 = Math.min(MAX_HEIGHT2, fits.get(row2) ?? sheet.defaultRowHeight);
|
|
39688
39795
|
const next = Math.abs(fit2 - sheet.defaultRowHeight) < 1e-9 ? void 0 : fit2;
|
|
39689
|
-
const current =
|
|
39796
|
+
const current = sheet.rowInfo.get(row2)?.height;
|
|
39690
39797
|
if (current === next) continue;
|
|
39691
39798
|
if (current !== void 0 && next !== void 0 && Math.abs(current - next) < 1e-9) continue;
|
|
39692
39799
|
updates.push([row2, next]);
|
|
@@ -44517,13 +44624,13 @@ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
|
44517
44624
|
measured ? 4 : 0
|
|
44518
44625
|
);
|
|
44519
44626
|
let baseline = 8 + (metrics[0]?.size ?? base.size ?? 14) + (vertical[0]?.before ?? 0) + (vertical[0]?.leading ?? 0);
|
|
44520
|
-
const
|
|
44627
|
+
const spans3 = [];
|
|
44521
44628
|
for (const [index3, line3] of metrics.entries()) {
|
|
44522
44629
|
if (index3)
|
|
44523
44630
|
baseline += vertical[index3 - 1].descent + vertical[index3 - 1].after + vertical[index3].before + vertical[index3].ascent;
|
|
44524
44631
|
let x = line3.align === "l" ? (width - boxWidth) / 2 + 4 : line3.align === "r" ? (width + boxWidth) / 2 - 4 - line3.width : (width - line3.width) / 2;
|
|
44525
44632
|
for (const run2 of line3.runs) {
|
|
44526
|
-
|
|
44633
|
+
spans3.push(
|
|
44527
44634
|
text3(x, baseline, run2.text, {
|
|
44528
44635
|
...run2.attrs,
|
|
44529
44636
|
anchor: "start"
|
|
@@ -44534,7 +44641,7 @@ function chartRichTitleSvg(model, width, options2 = {}, frameHeight = 400) {
|
|
|
44534
44641
|
}
|
|
44535
44642
|
const parent = text3(0, 0, "", { ...base, underline: false }).replace(
|
|
44536
44643
|
"</text>",
|
|
44537
|
-
`${
|
|
44644
|
+
`${spans3.join("")}</text>`
|
|
44538
44645
|
);
|
|
44539
44646
|
const markup = chartAreaRect(model, "title", {
|
|
44540
44647
|
x: (width - boxWidth) / 2,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CellRange } from '../address.js';
|
|
2
|
+
/** How the merges cover one cell. */
|
|
3
|
+
export interface MergeCover {
|
|
4
|
+
/** Some merge covers the cell. */
|
|
5
|
+
readonly merged: boolean;
|
|
6
|
+
/** Some merge of more than one cell covers it. */
|
|
7
|
+
readonly spanned: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Sweeps a sheet's rows top to bottom (`moveTo`) and tells how the merges cover a cell of the
|
|
11
|
+
* current row (`at`). It holds only the merges covering the current row: a sheet's merges do not
|
|
12
|
+
* overlap, so those are disjoint column spans, kept in column order and found by binary search.
|
|
13
|
+
* Overlapping merges, which only a malformed file has, are detected and answered by a scan of the
|
|
14
|
+
* current row's merges instead, which gives the same result.
|
|
15
|
+
*/
|
|
16
|
+
export declare class MergeSweep {
|
|
17
|
+
/** The merges by first row; `next` is the first one the sweep has not reached. */
|
|
18
|
+
private readonly byRow;
|
|
19
|
+
private next;
|
|
20
|
+
private row;
|
|
21
|
+
/** The merges covering the current row, by first column. */
|
|
22
|
+
private readonly active;
|
|
23
|
+
/** The last row of the earliest-ending active merge. */
|
|
24
|
+
private firstEnd;
|
|
25
|
+
private overlapping;
|
|
26
|
+
constructor(merges: readonly CellRange[]);
|
|
27
|
+
/** How many merges cover the current row, which is everything the sweep holds. */
|
|
28
|
+
get size(): number;
|
|
29
|
+
/** Moves to `row`, which must not be above the previous one. */
|
|
30
|
+
moveTo(row: number): void;
|
|
31
|
+
/** How the merges cover column `col` of the current row. */
|
|
32
|
+
at(col: number): MergeCover;
|
|
33
|
+
private add;
|
|
34
|
+
private dropEnded;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=merge-sweep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-sweep.d.ts","sourceRoot":"","sources":["../../../xlsx/layout/merge-sweep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,qCAAqC;AACrC,MAAM,WAAW,UAAU;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAqBD;;;;;;GAMG;AACH,qBAAa,UAAU;IACtB,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,GAAG,CAA4B;IACvC,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,WAAW,CAAS;IAE5B,YAAY,MAAM,EAAE,SAAS,SAAS,EAAE,EAEvC;IAED,kFAAkF;IAClF,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gEAAgE;IAChE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CASxB;IAED,4DAA4D;IAC5D,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAa1B;IAED,OAAO,CAAC,GAAG;IAeX,OAAO,CAAC,SAAS;CAYjB"}
|
|
@@ -36,6 +36,11 @@ export interface GridMetricsOptions {
|
|
|
36
36
|
}
|
|
37
37
|
/** Normalizes a zoom given as percent or factor to percent within Excel's 10%-400% range. */
|
|
38
38
|
export declare function zoomPercent(zoom: number | undefined): number;
|
|
39
|
+
/**
|
|
40
|
+
* The column widths of `createGridMetrics(sheet, options).colWidth`, read from the column
|
|
41
|
+
* definitions alone: unlike the full metrics, this never walks the sheet's cells or rows.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createColumnWidths(sheet: Worksheet, options?: Pick<GridMetricsOptions, 'zoom' | 'mdw'>): (c: number) => number;
|
|
39
44
|
/** Builds the grid geometry of a sheet. Sizes are whole pixels scaled by the zoom. */
|
|
40
45
|
export declare function createGridMetrics(sheet: Worksheet, options?: GridMetricsOptions): GridMetrics;
|
|
41
46
|
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../xlsx/layout/metrics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAS1C,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,iEAAiE;IACjE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,2DAA2D;IAC3D,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iEAAiE;IACjE,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,+DAA+D;IAC/D,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI5D;
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../xlsx/layout/metrics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAS1C,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC3B,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,iEAAiE;IACjE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,2DAA2D;IAC3D,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,iEAAiE;IACjE,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,+DAA+D;IAC/D,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IAClC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI5D;AAiCD;;;GAGG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,KAAK,CAAM,GACpD,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAIvB;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAwCjG"}
|
|
@@ -12,6 +12,12 @@ export declare function wrappedLineCount(text: string, width: number, measure: (
|
|
|
12
12
|
* Calibri metrics, so other fonts are approximate.
|
|
13
13
|
*/
|
|
14
14
|
export declare function autoFitRowHeight(workbook: Workbook, sheetIndex: number, row: number, measure: MeasureText): number;
|
|
15
|
+
/**
|
|
16
|
+
* {@link autoFitRowHeight} for many rows of one sheet at once (a missing sheet gives an empty
|
|
17
|
+
* map). The column widths and the merges are read once for all of `rows`, so the cost follows
|
|
18
|
+
* the cells of those rows, not the size of the sheet.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fitRowHeights(workbook: Workbook, sheetIndex: number, rows: Iterable<number>, measure: MeasureText): Map<number, number>;
|
|
15
21
|
/** A font-size based text measure (px) for when no real text measurement is available. */
|
|
16
22
|
export declare const approximateMeasure: MeasureText;
|
|
17
23
|
//# sourceMappingURL=row-autofit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"row-autofit.d.ts","sourceRoot":"","sources":["../../../xlsx/layout/row-autofit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"row-autofit.d.ts","sourceRoot":"","sources":["../../../xlsx/layout/row-autofit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AA2B7C,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAevD;AAED,iGAAiG;AACjG,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC/B,MAAM,CAwBR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,GAClB,MAAM,CAER;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EACtB,OAAO,EAAE,WAAW,GAClB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCrB;AAED,0FAA0F;AAC1F,eAAO,MAAM,kBAAkB,EAAE,WACqB,CAAC"}
|