@shbernal/pptxgenjs 5.1.0 → 5.2.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/{browser-tG59vAUr.js → browser-DraPrTLD.js} +5 -5
- package/dist/browser-DraPrTLD.js.map +1 -0
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +3 -3
- package/dist/{core-enums-BCaI1VAf.js → core-interfaces-vUc0ElZs.js} +106 -2
- package/dist/core-interfaces-vUc0ElZs.js.map +1 -0
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/node.d.ts +3 -3
- package/dist/node.js +4 -4
- package/dist/node.js.map +1 -1
- package/dist/{pptxgen-3gNqxx8n.js → pptxgen--5RWzhb4.js} +446 -134
- package/dist/pptxgen--5RWzhb4.js.map +1 -0
- package/dist/{pptxgen-CKBnfeDh.d.ts → pptxgen-DzBNFPxG.d.ts} +32 -2
- package/dist/pptxgen-DzBNFPxG.d.ts.map +1 -0
- package/dist/standalone.d.ts +343 -2
- package/dist/standalone.d.ts.map +1 -1
- package/dist/standalone.js +551 -135
- package/dist/standalone.js.map +1 -1
- package/dist/{units-Bv8xqGyH.d.ts → units-y594YyBo.d.ts} +314 -3
- package/dist/units-y594YyBo.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/browser-tG59vAUr.js.map +0 -1
- package/dist/core-enums-BCaI1VAf.js.map +0 -1
- package/dist/pptxgen-3gNqxx8n.js.map +0 -1
- package/dist/pptxgen-CKBnfeDh.d.ts.map +0 -1
- package/dist/units-Bv8xqGyH.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as emuToInches, c as inchesToEmu, i as STANDARD_LAYOUTS } from "./units-DmzbVUNp.js";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as DEF_TEXT_GLOW, B as ONEPT, D as DEF_SHAPE_SHADOW, G as SCHEME_COLOR_NAMES, H as PIECHART_COLORS, I as LAYOUT_IDX_SERIES_BASE, K as SHAPE_TYPE, L as LETTERS, M as EMU, N as IMG_BROKEN, R as LINEH_MODIFIER, T as DEF_PRES_LAYOUT_NAME, U as PLACEHOLDER_TYPES, V as OutputType, W as REGEX_HEX_COLOR, X as ShapeType, Y as SchemeColor, _ as DEF_CELL_MARGIN_IN, a as AXIS_ID_SERIES_PRIMARY, b as DEF_CHART_GRIDLINE, c as AlignH, f as CHART_TYPE, g as DEF_CELL_BORDER, i as AXIS_ID_CATEGORY_SECONDARY, j as DEF_TEXT_SHADOW, k as DEF_SLIDE_MARGIN_IN, l as AlignV, m as ChartType, o as AXIS_ID_VALUE_PRIMARY, q as SLDNUMFLDID, r as AXIS_ID_CATEGORY_PRIMARY, s as AXIS_ID_VALUE_SECONDARY, u as BARCHART_COLORS, w as DEF_PRES_LAYOUT, x as DEF_FONT_COLOR, y as DEF_CHART_BORDER } from "./core-interfaces-vUc0ElZs.js";
|
|
3
3
|
import JSZip from "jszip";
|
|
4
4
|
//#region src/gen-utils.ts
|
|
5
5
|
/**
|
|
@@ -244,6 +244,17 @@ function genXmlGradientFill(gradient) {
|
|
|
244
244
|
return strXml;
|
|
245
245
|
}
|
|
246
246
|
/**
|
|
247
|
+
* Create a native DrawingML pattern fill.
|
|
248
|
+
* @param {PatternFillProps} pattern pattern fill options
|
|
249
|
+
* @returns XML string
|
|
250
|
+
*/
|
|
251
|
+
function genXmlPatternFill(pattern) {
|
|
252
|
+
if (!pattern) throw new Error("Pattern fill requires a pattern object.");
|
|
253
|
+
const fgColor = pattern.fgColor ?? "000000";
|
|
254
|
+
const bgColor = pattern.bgColor ?? "FFFFFF";
|
|
255
|
+
return `<a:pattFill prst="${pattern.preset}"><a:fgClr>${createColorElement(fgColor)}</a:fgClr><a:bgClr>${createColorElement(bgColor)}</a:bgClr></a:pattFill>`;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
247
258
|
* Create color selection
|
|
248
259
|
* @param {Color | ShapeFillProps | ShapeLineProps} props fill props
|
|
249
260
|
* @returns XML string
|
|
@@ -268,6 +279,9 @@ function genXmlColorSelection(props) {
|
|
|
268
279
|
case "gradient":
|
|
269
280
|
outText += genXmlGradientFill(typeof props === "string" ? void 0 : props.gradient);
|
|
270
281
|
break;
|
|
282
|
+
case "pattern":
|
|
283
|
+
outText += genXmlPatternFill(typeof props === "string" ? void 0 : props.pattern);
|
|
284
|
+
break;
|
|
271
285
|
default:
|
|
272
286
|
outText += "";
|
|
273
287
|
break;
|
|
@@ -333,6 +347,123 @@ function svgMarkupToDataUri(svg) {
|
|
|
333
347
|
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
334
348
|
return `data:image/svg+xml;base64,${btoa(binary)}`;
|
|
335
349
|
}
|
|
350
|
+
/**
|
|
351
|
+
* Decode a base64 image payload (raw base64 or a `data:` URI) to bytes.
|
|
352
|
+
* - tolerant of the `data:[mime];base64,` prefix and of whitespace in the payload
|
|
353
|
+
* @param {string} b64 - base64 string or data URI
|
|
354
|
+
* @returns {Uint8Array | null} decoded bytes, or `null` when the payload is empty/undecodable
|
|
355
|
+
*/
|
|
356
|
+
function decodeBase64ToBytes(b64) {
|
|
357
|
+
if (!b64) return null;
|
|
358
|
+
const comma = b64.indexOf("base64,");
|
|
359
|
+
const payload = (comma >= 0 ? b64.slice(comma + 7) : b64).replace(/\s/g, "");
|
|
360
|
+
if (!payload) return null;
|
|
361
|
+
try {
|
|
362
|
+
const binary = atob(payload);
|
|
363
|
+
const bytes = new Uint8Array(binary.length);
|
|
364
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
365
|
+
return bytes;
|
|
366
|
+
} catch {
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Read the intrinsic pixel dimensions of a raster image from its header bytes.
|
|
372
|
+
* - synchronous: parses only file-format headers, never decodes pixels
|
|
373
|
+
* - supports PNG, JPEG, GIF, BMP, and WebP (VP8 / VP8L / VP8X)
|
|
374
|
+
* - vector (SVG) and unrecognized formats return `null` (no intrinsic pixel size)
|
|
375
|
+
*
|
|
376
|
+
* Used by image `sizing: 'cover' | 'contain'` to compute an aspect-correct
|
|
377
|
+
* `<a:srcRect>` crop from the *natural* image ratio rather than the displayed box.
|
|
378
|
+
* @param {string} dataB64 - base64 image payload or `data:` URI
|
|
379
|
+
* @returns {{ w: number, h: number } | null} natural pixel size, or `null` when unmeasurable
|
|
380
|
+
*/
|
|
381
|
+
function getImageSizeFromBase64(dataB64) {
|
|
382
|
+
const b = decodeBase64ToBytes(dataB64);
|
|
383
|
+
if (!b || b.length < 24) return null;
|
|
384
|
+
if (b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) {
|
|
385
|
+
const w = b[16] << 24 | b[17] << 16 | b[18] << 8 | b[19];
|
|
386
|
+
const h = b[20] << 24 | b[21] << 16 | b[22] << 8 | b[23];
|
|
387
|
+
return w > 0 && h > 0 ? {
|
|
388
|
+
w,
|
|
389
|
+
h
|
|
390
|
+
} : null;
|
|
391
|
+
}
|
|
392
|
+
if (b[0] === 71 && b[1] === 73 && b[2] === 70) {
|
|
393
|
+
const w = b[6] | b[7] << 8;
|
|
394
|
+
const h = b[8] | b[9] << 8;
|
|
395
|
+
return w > 0 && h > 0 ? {
|
|
396
|
+
w,
|
|
397
|
+
h
|
|
398
|
+
} : null;
|
|
399
|
+
}
|
|
400
|
+
if (b[0] === 66 && b[1] === 77) {
|
|
401
|
+
const w = b[18] | b[19] << 8 | b[20] << 16 | b[21] << 24;
|
|
402
|
+
const h = b[22] | b[23] << 8 | b[24] << 16 | b[25] << 24;
|
|
403
|
+
const aw = Math.abs(w);
|
|
404
|
+
const ah = Math.abs(h);
|
|
405
|
+
return aw > 0 && ah > 0 ? {
|
|
406
|
+
w: aw,
|
|
407
|
+
h: ah
|
|
408
|
+
} : null;
|
|
409
|
+
}
|
|
410
|
+
if (b[0] === 82 && b[1] === 73 && b[2] === 70 && b[3] === 70 && b[8] === 87 && b[9] === 69 && b[10] === 66 && b[11] === 80) {
|
|
411
|
+
const fourCC = String.fromCharCode(b[12], b[13], b[14], b[15]);
|
|
412
|
+
if (fourCC === "VP8 " && b.length >= 30) {
|
|
413
|
+
const w = (b[26] | b[27] << 8) & 16383;
|
|
414
|
+
const h = (b[28] | b[29] << 8) & 16383;
|
|
415
|
+
return w > 0 && h > 0 ? {
|
|
416
|
+
w,
|
|
417
|
+
h
|
|
418
|
+
} : null;
|
|
419
|
+
}
|
|
420
|
+
if (fourCC === "VP8L" && b.length >= 25) {
|
|
421
|
+
const bits = b[21] | b[22] << 8 | b[23] << 16 | b[24] << 24;
|
|
422
|
+
const w = (bits & 16383) + 1;
|
|
423
|
+
const h = (bits >> 14 & 16383) + 1;
|
|
424
|
+
return w > 0 && h > 0 ? {
|
|
425
|
+
w,
|
|
426
|
+
h
|
|
427
|
+
} : null;
|
|
428
|
+
}
|
|
429
|
+
if (fourCC === "VP8X" && b.length >= 30) {
|
|
430
|
+
const w = (b[24] | b[25] << 8 | b[26] << 16) + 1;
|
|
431
|
+
const h = (b[27] | b[28] << 8 | b[29] << 16) + 1;
|
|
432
|
+
return w > 0 && h > 0 ? {
|
|
433
|
+
w,
|
|
434
|
+
h
|
|
435
|
+
} : null;
|
|
436
|
+
}
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
if (b[0] === 255 && b[1] === 216) {
|
|
440
|
+
let i = 2;
|
|
441
|
+
while (i + 9 < b.length) {
|
|
442
|
+
if (b[i] !== 255) {
|
|
443
|
+
i++;
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
const marker = b[i + 1];
|
|
447
|
+
if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
|
|
448
|
+
const h = b[i + 5] << 8 | b[i + 6];
|
|
449
|
+
const w = b[i + 7] << 8 | b[i + 8];
|
|
450
|
+
return w > 0 && h > 0 ? {
|
|
451
|
+
w,
|
|
452
|
+
h
|
|
453
|
+
} : null;
|
|
454
|
+
}
|
|
455
|
+
if (marker >= 208 && marker <= 217 || marker === 1) {
|
|
456
|
+
i += 2;
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
const segLen = b[i + 2] << 8 | b[i + 3];
|
|
460
|
+
if (segLen < 2) break;
|
|
461
|
+
i += 2 + segLen;
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
336
467
|
//#endregion
|
|
337
468
|
//#region src/gen-tables.ts
|
|
338
469
|
/**
|
|
@@ -386,52 +517,62 @@ function parseTextToLines(cell, colWidth, verbose) {
|
|
|
386
517
|
*/
|
|
387
518
|
let newLine = [];
|
|
388
519
|
inputCells.forEach((cell) => {
|
|
389
|
-
if (typeof cell.text
|
|
390
|
-
|
|
391
|
-
|
|
520
|
+
if (typeof cell.text !== "string") return;
|
|
521
|
+
if (cell.text.includes("\n")) {
|
|
522
|
+
const parts = cell.text.split("\n");
|
|
523
|
+
parts.forEach((part, partIdx) => {
|
|
524
|
+
if (partIdx === parts.length - 1) newLine.push({
|
|
392
525
|
_type: "tablecell",
|
|
393
|
-
text:
|
|
394
|
-
options:
|
|
395
|
-
...cell.options,
|
|
396
|
-
breakLine: true
|
|
397
|
-
}
|
|
526
|
+
text: part,
|
|
527
|
+
options: cell.options
|
|
398
528
|
});
|
|
529
|
+
else {
|
|
530
|
+
newLine.push({
|
|
531
|
+
_type: "tablecell",
|
|
532
|
+
text: part,
|
|
533
|
+
options: {
|
|
534
|
+
...cell.options,
|
|
535
|
+
breakLine: true
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
inputLines1.push(newLine);
|
|
539
|
+
newLine = [];
|
|
540
|
+
}
|
|
399
541
|
});
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
inputLines1.push(newLine);
|
|
408
|
-
newLine = [];
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
if (newLine.length > 0) {
|
|
542
|
+
} else newLine.push({
|
|
543
|
+
_type: "tablecell",
|
|
544
|
+
text: cell.text.trim(),
|
|
545
|
+
options: cell.options
|
|
546
|
+
});
|
|
547
|
+
if (cell.options?.breakLine) {
|
|
548
|
+
if (verbose) console.log(`inputCells: new line > ${JSON.stringify(newLine)}`);
|
|
412
549
|
inputLines1.push(newLine);
|
|
413
550
|
newLine = [];
|
|
414
551
|
}
|
|
415
552
|
});
|
|
553
|
+
if (newLine.length > 0) {
|
|
554
|
+
inputLines1.push(newLine);
|
|
555
|
+
newLine = [];
|
|
556
|
+
}
|
|
416
557
|
if (verbose) {
|
|
417
558
|
console.log(`[2/4] inputLines1 (${inputLines1.length})`);
|
|
418
559
|
inputLines1.forEach((line, idx) => console.log(`[2/4] [${idx + 1}] line: ${JSON.stringify(line)}`));
|
|
419
560
|
}
|
|
420
561
|
inputLines1.forEach((line) => {
|
|
562
|
+
const lineTokens = [];
|
|
421
563
|
line.forEach((cell) => {
|
|
422
|
-
const lineCells = [];
|
|
423
564
|
const lineWords = String(cell.text).split(" ");
|
|
424
565
|
lineWords.forEach((word, idx) => {
|
|
425
566
|
const cellProps = { ...cell.options };
|
|
426
567
|
if (cellProps?.breakLine) cellProps.breakLine = idx + 1 === lineWords.length;
|
|
427
|
-
|
|
568
|
+
lineTokens.push({
|
|
428
569
|
_type: "tablecell",
|
|
429
570
|
text: word + (idx + 1 < lineWords.length ? " " : ""),
|
|
430
571
|
options: cellProps
|
|
431
572
|
});
|
|
432
573
|
});
|
|
433
|
-
inputLines2.push(lineCells);
|
|
434
574
|
});
|
|
575
|
+
inputLines2.push(lineTokens);
|
|
435
576
|
});
|
|
436
577
|
if (verbose) {
|
|
437
578
|
console.log(`[3/4] inputLines2 (${inputLines2.length})`);
|
|
@@ -539,6 +680,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
539
680
|
numCols += Number(cellOpts?.colspan ? cellOpts.colspan : 1);
|
|
540
681
|
});
|
|
541
682
|
if (tableProps.verbose) console.log(`| numCols ......................................... = ${numCols}`);
|
|
683
|
+
const colSpanDepths = new Array(numCols).fill(0);
|
|
542
684
|
if (!tablePropW && tableProps.colW) {
|
|
543
685
|
tableCalcW = Array.isArray(tableProps.colW) ? tableProps.colW.reduce((p, n) => p + n) * EMU : tableProps.colW * numCols || 0;
|
|
544
686
|
if (tableProps.verbose) console.log(`| tableCalcW ...................................... = ${tableCalcW / EMU}`);
|
|
@@ -559,6 +701,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
559
701
|
}
|
|
560
702
|
let newTableRowSlide = { rows: [] };
|
|
561
703
|
tableRows.forEach((row, iRow) => {
|
|
704
|
+
const hasActiveRowSpan = colSpanDepths.some((d) => d > 0);
|
|
562
705
|
const rowCellLines = [];
|
|
563
706
|
let maxCellMarTopEmu = 0;
|
|
564
707
|
let maxCellMarBtmEmu = 0;
|
|
@@ -655,7 +798,7 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
655
798
|
rowCellLines.forEach((cell) => {
|
|
656
799
|
if (cell._lineHeight >= emuLineMaxH) emuLineMaxH = cell._lineHeight;
|
|
657
800
|
});
|
|
658
|
-
if (emuTabCurrH + emuLineMaxH > emuSlideTabH) {
|
|
801
|
+
if (emuTabCurrH + emuLineMaxH > emuSlideTabH && !hasActiveRowSpan) {
|
|
659
802
|
if (tableProps.verbose) {
|
|
660
803
|
console.log("\n|-----------------------------------------------------------------------|");
|
|
661
804
|
console.log(`|-- NEW SLIDE CREATED (currTabH+currLineH > maxH) => ${(emuTabCurrH / EMU).toFixed(2)} + ${(srcCell._lineHeight / EMU).toFixed(2)} > ${emuSlideTabH / EMU}`);
|
|
@@ -699,6 +842,16 @@ function getSlidesForTableRows(tableRows = [], tableProps = {}, presLayout, mast
|
|
|
699
842
|
if (rowCellLines.map((cell) => cell._lines.length).reduce((prev, next) => prev + next) === 0) isDone = true;
|
|
700
843
|
}
|
|
701
844
|
if (currTableRow.length > 0) newTableRowSlide.rows.push(currTableRow);
|
|
845
|
+
const occupiedBefore = [...colSpanDepths];
|
|
846
|
+
let colCursor = 0;
|
|
847
|
+
row.forEach((cell) => {
|
|
848
|
+
while (colCursor < numCols && occupiedBefore[colCursor] > 0) colCursor++;
|
|
849
|
+
const cellColspan = cell.options?.colspan ?? 1;
|
|
850
|
+
const cellRowspan = cell.options?.rowspan ?? 1;
|
|
851
|
+
if (cellRowspan > 1) for (let c = 0; c < cellColspan && colCursor + c < numCols; c++) colSpanDepths[colCursor + c] = cellRowspan;
|
|
852
|
+
colCursor += cellColspan;
|
|
853
|
+
});
|
|
854
|
+
for (let c = 0; c < numCols; c++) if (colSpanDepths[c] > 0) colSpanDepths[c]--;
|
|
702
855
|
if (tableProps.verbose) console.log(`- SLIDE [${tableRowSlides.length}]: ROW [${iRow}]: ...COMPLETE ...... emuTabCurrH = ${(emuTabCurrH / EMU).toFixed(2)} ( emuSlideTabH = ${(emuSlideTabH / EMU).toFixed(2)} )`);
|
|
703
856
|
});
|
|
704
857
|
tableRowSlides.push(newTableRowSlide);
|
|
@@ -954,6 +1107,7 @@ function createSlideMaster(props, target) {
|
|
|
954
1107
|
else if ("image" in object) addImageDefinition(tgt, object.image);
|
|
955
1108
|
else if ("line" in object) addShapeDefinition(tgt, "line", object.line);
|
|
956
1109
|
else if ("rect" in object) addShapeDefinition(tgt, "rect", object.rect);
|
|
1110
|
+
else if ("roundRect" in object) addShapeDefinition(tgt, "roundRect", object.roundRect);
|
|
957
1111
|
else if ("text" in object) addTextDefinition(tgt, [{ text: object.text.text }], object.text.options || {}, false);
|
|
958
1112
|
else if ("placeholder" in object) {
|
|
959
1113
|
const placeholder = object.placeholder;
|
|
@@ -1295,6 +1449,7 @@ function addImageDefinition(target, opt) {
|
|
|
1295
1449
|
flipV: opt.flipV || false,
|
|
1296
1450
|
flipH: opt.flipH || false,
|
|
1297
1451
|
transparency: opt.transparency || 0,
|
|
1452
|
+
duotone: opt.duotone,
|
|
1298
1453
|
objectName,
|
|
1299
1454
|
shadow: correctShadowOptions(opt.shadow)
|
|
1300
1455
|
};
|
|
@@ -1344,7 +1499,7 @@ function addImageDefinition(target, opt) {
|
|
|
1344
1499
|
type: "hyperlink",
|
|
1345
1500
|
data: objHyperlink.slide ? "slide" : "dummy",
|
|
1346
1501
|
rId: imageRelId,
|
|
1347
|
-
Target: objHyperlink.url
|
|
1502
|
+
Target: objHyperlink.url ? encodeXmlEntities(objHyperlink.url) : String(objHyperlink.slide)
|
|
1348
1503
|
});
|
|
1349
1504
|
objHyperlink._rId = imageRelId;
|
|
1350
1505
|
newObject.hyperlink = objHyperlink;
|
|
@@ -2102,7 +2257,7 @@ async function createExcelWorksheet(chartObject, zip) {
|
|
|
2102
2257
|
if (chartObject.opts._type === "bubble" || chartObject.opts._type === "bubble3D") strSharedStrings += `<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${intBubbleCols}" uniqueCount="${intBubbleCols}">`;
|
|
2103
2258
|
else if (chartObject.opts._type === "scatter") strSharedStrings += `<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${data.length}" uniqueCount="${data.length}">`;
|
|
2104
2259
|
else if (IS_MULTI_CAT_AXES) {
|
|
2105
|
-
let totCount = data.length;
|
|
2260
|
+
let totCount = data.length + 1;
|
|
2106
2261
|
data[0].labels.forEach((arrLabel) => totCount += arrLabel.filter((label) => label && label !== "").length);
|
|
2107
2262
|
strSharedStrings += `<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${totCount}" uniqueCount="${totCount}">`;
|
|
2108
2263
|
strSharedStrings += "<si><t/></si>";
|
|
@@ -2170,7 +2325,7 @@ async function createExcelWorksheet(chartObject, zip) {
|
|
|
2170
2325
|
strSheetXml += "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\">";
|
|
2171
2326
|
if (chartObject.opts._type === "bubble" || chartObject.opts._type === "bubble3D") strSheetXml += `<dimension ref="A1:${getExcelColName(intBubbleCols)}${data[0].values.length + 1}"/>`;
|
|
2172
2327
|
else if (chartObject.opts._type === "scatter") strSheetXml += `<dimension ref="A1:${getExcelColName(data.length)}${data[0].values.length + 1}"/>`;
|
|
2173
|
-
else strSheetXml += `<dimension ref="A1:${getExcelColName(data.length +
|
|
2328
|
+
else strSheetXml += `<dimension ref="A1:${getExcelColName(data.length + data[0].labels.length)}${data[0].values.length + 1}"/>`;
|
|
2174
2329
|
strSheetXml += "<sheetViews><sheetView tabSelected=\"1\" workbookViewId=\"0\"><selection activeCell=\"B1\" sqref=\"B1\"/></sheetView></sheetViews>";
|
|
2175
2330
|
strSheetXml += "<sheetFormatPr baseColWidth=\"10\" defaultRowHeight=\"16\"/>";
|
|
2176
2331
|
if (chartObject.opts._type === "bubble" || chartObject.opts._type === "bubble3D") {
|
|
@@ -2222,82 +2377,28 @@ async function createExcelWorksheet(chartObject, zip) {
|
|
|
2222
2377
|
strSheetXml += "</row>";
|
|
2223
2378
|
});
|
|
2224
2379
|
} else {
|
|
2225
|
-
strSheetXml += `<row r="1" spans="1:${data.length + data[0].labels.length}">`;
|
|
2226
|
-
for (let idx = 0; idx < data[0].labels.length; idx++) strSheetXml += `<c r="${getExcelColName(idx + 1)}1" t="s"><v>0</v></c>`;
|
|
2227
|
-
for (let idx = data[0].labels.length - 1; idx < data.length + data[0].labels.length - 1; idx++) strSheetXml += `<c r="${getExcelColName(idx + data[0].labels.length)}1" t="s"><v>${idx}</v></c>`;
|
|
2228
|
-
strSheetXml += "</row>";
|
|
2229
|
-
/**
|
|
2230
|
-
* @example INPUT
|
|
2231
|
-
* const LABELS = [
|
|
2232
|
-
* ["Gear", "Berg", "Motr", "Swch", "Plug", "Cord", "Pump", "Leak", "Seal"],
|
|
2233
|
-
* ["Mech", "", "", "Elec", "", "", "Hydr", "", ""],
|
|
2234
|
-
* ];
|
|
2235
|
-
* const arrDataRegions = [
|
|
2236
|
-
* { name: "West", labels: LABELS, values: [11, 8, 3, 0, 11, 3, 0, 0, 0] },
|
|
2237
|
-
* { name: "Ctrl", labels: LABELS, values: [0, 11, 6, 19, 12, 5, 0, 0, 0] },
|
|
2238
|
-
* { name: "East", labels: LABELS, values: [0, 3, 2, 0, 0, 0, 4, 3, 1] },
|
|
2239
|
-
* ];
|
|
2240
|
-
*/
|
|
2241
|
-
/**
|
|
2242
|
-
* @example OUTPUT EXCEL SHEET
|
|
2243
|
-
* |/|---A--|---B--|---C--|---D--|---E--|
|
|
2244
|
-
* |1| | | West | Ctrl | East |
|
|
2245
|
-
* |2| Mech | Gear | ## | ## | ## |
|
|
2246
|
-
* |3| | Brng | ## | ## | ## |
|
|
2247
|
-
* |4| | Motr | ## | ## | ## |
|
|
2248
|
-
* |5| Elec | Swch | ## | ## | ## |
|
|
2249
|
-
* |6| | Plug | ## | ## | ## |
|
|
2250
|
-
* |7| | Cord | ## | ## | ## |
|
|
2251
|
-
* |8| Hydr | Pump | ## | ## | ## |
|
|
2252
|
-
* |9| | Leak | ## | ## | ## |
|
|
2253
|
-
*|10| | Seal | ## | ## | ## |
|
|
2254
|
-
*/
|
|
2255
|
-
/**
|
|
2256
|
-
* @example OUTPUT EXCEL SHEET XML
|
|
2257
|
-
* <row r="1" spans="1:5">
|
|
2258
|
-
* <c r="A1" t="s"><v>0</v></c>
|
|
2259
|
-
* <c r="B1" t="s"><v>0</v></c>
|
|
2260
|
-
* <c r="C1" t="s"><v>1</v></c>
|
|
2261
|
-
* <c r="D1" t="s"><v>2</v></c>
|
|
2262
|
-
* <c r="E1" t="s"><v>3</v></c>
|
|
2263
|
-
* </row>
|
|
2264
|
-
* <row r="2" spans="1:5">
|
|
2265
|
-
* <c r="A2" t="s"><v>4</v></c>
|
|
2266
|
-
* <c r="B2" t="s"><v>7</v></c>
|
|
2267
|
-
* <c r="C2" ><v>###</v></c>
|
|
2268
|
-
* </row>
|
|
2269
|
-
* <row r="3" spans="1:5">
|
|
2270
|
-
* <c r="A3" />
|
|
2271
|
-
* <c r="B3" t="s"><v>8</v></c>
|
|
2272
|
-
* <c r="C3" ><v>###</v></c>
|
|
2273
|
-
* </row>
|
|
2274
|
-
*/
|
|
2275
|
-
/**
|
|
2276
|
-
* @example SHARED-STRINGS
|
|
2277
|
-
* 1=West, 2=Ctrl, 3=East, 4=Mech, 5=Elec, 6=Mydr, 7=Gear, 8=Brng, [...], 15=Seal
|
|
2278
|
-
*/
|
|
2279
|
-
/**
|
|
2280
|
-
* const LABELS = [
|
|
2281
|
-
* ["Gear", "Berg", "Motr", "Swch", "Plug", "Cord", "Pump", "Leak", "Seal"],
|
|
2282
|
-
* ["Mech", "", "", "Elec", "", "", "Hydr", "", ""],
|
|
2283
|
-
* ["2010", "", "", "", "", "", "", "", ""],
|
|
2284
|
-
* ];
|
|
2285
|
-
*/
|
|
2286
2380
|
const TOT_SER = data.length;
|
|
2287
2381
|
const TOT_CAT = data[0].labels[0].length;
|
|
2288
2382
|
const TOT_LVL = data[0].labels.length;
|
|
2383
|
+
const revLabelGroups = data[0].labels.slice().reverse();
|
|
2384
|
+
const ssLabelMap = /* @__PURE__ */ new Map();
|
|
2385
|
+
let ssIdx = TOT_SER + 1;
|
|
2386
|
+
revLabelGroups.forEach((labelsGroup, revLevelIdx) => {
|
|
2387
|
+
labelsGroup.forEach((label, rowIdx) => {
|
|
2388
|
+
if (label && label !== "") ssLabelMap.set(`${revLevelIdx}:${rowIdx}`, ssIdx++);
|
|
2389
|
+
});
|
|
2390
|
+
});
|
|
2391
|
+
strSheetXml += `<row r="1" spans="1:${TOT_SER + TOT_LVL}">`;
|
|
2392
|
+
for (let col = 1; col <= TOT_LVL; col++) strSheetXml += `<c r="${getExcelColName(col)}1" t="s"><v>0</v></c>`;
|
|
2393
|
+
for (let ser = 0; ser < TOT_SER; ser++) strSheetXml += `<c r="${getExcelColName(TOT_LVL + ser + 1)}1" t="s"><v>${ser + 1}</v></c>`;
|
|
2394
|
+
strSheetXml += "</row>";
|
|
2289
2395
|
for (let idx = 0; idx < TOT_CAT; idx++) {
|
|
2290
2396
|
strSheetXml += `<row r="${idx + 2}" spans="1:${TOT_SER + TOT_LVL}">`;
|
|
2291
|
-
let totLabels = TOT_SER;
|
|
2292
|
-
const revLabelGroups = data[0].labels.slice().reverse();
|
|
2293
2397
|
revLabelGroups.forEach((labelsGroup, idy) => {
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
totLabels += totGrpLbls;
|
|
2297
|
-
strSheetXml += `<c r="${getExcelColName(idx + 1 + idy)}${idx + 2}" t="s"><v>${totLabels}</v></c>`;
|
|
2298
|
-
}
|
|
2398
|
+
const colLabel = labelsGroup[idx];
|
|
2399
|
+
if (colLabel && colLabel !== "") strSheetXml += `<c r="${getExcelColName(idy + 1)}${idx + 2}" t="s"><v>${ssLabelMap.get(`${idy}:${idx}`)}</v></c>`;
|
|
2299
2400
|
});
|
|
2300
|
-
for (let idy = 0; idy < TOT_SER; idy++) strSheetXml += `<c r="${getExcelColName(TOT_LVL + idy + 1)}${idx + 2}"><v>${data[idy].values[idx]
|
|
2401
|
+
for (let idy = 0; idy < TOT_SER; idy++) strSheetXml += `<c r="${getExcelColName(TOT_LVL + idy + 1)}${idx + 2}"><v>${data[idy].values[idx] ?? ""}</v></c>`;
|
|
2301
2402
|
strSheetXml += "</row>";
|
|
2302
2403
|
}
|
|
2303
2404
|
}
|
|
@@ -2440,6 +2541,13 @@ function makeXmlCharts(rel) {
|
|
|
2440
2541
|
if (rel.opts.showLegend) {
|
|
2441
2542
|
strXml += "<c:legend>";
|
|
2442
2543
|
strXml += "<c:legendPos val=\"" + rel.opts.legendPos + "\"/>";
|
|
2544
|
+
if (Array.isArray(rel.opts._type)) {
|
|
2545
|
+
let seriesIdx = 0;
|
|
2546
|
+
rel.opts._type.forEach((type) => {
|
|
2547
|
+
if (type.options?.showLegend === false) for (let i = 0; i < type.data.length; i++) strXml += `<c:legendEntry><c:idx val="${seriesIdx + i}"/><c:delete val="1"/></c:legendEntry>`;
|
|
2548
|
+
seriesIdx += type.data.length;
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2443
2551
|
strXml += "<c:overlay val=\"0\"/>";
|
|
2444
2552
|
if (rel.opts.legendFontFace || rel.opts.legendFontSize || rel.opts.legendColor) {
|
|
2445
2553
|
strXml += "<c:txPr>";
|
|
@@ -2515,17 +2623,20 @@ function makeChartType(chartType, data, opts, valAxisId, catAxisId) {
|
|
|
2515
2623
|
strXml += " <c:strCache><c:ptCount val=\"1\"/><c:pt idx=\"0\"><c:v>" + encodeXmlEntities(obj.name) + "</c:v></c:pt></c:strCache>";
|
|
2516
2624
|
strXml += " </c:strRef>";
|
|
2517
2625
|
strXml += " </c:tx>";
|
|
2518
|
-
const
|
|
2626
|
+
const seriesOverride = opts.seriesOptions?.[obj._dataIndex];
|
|
2627
|
+
const seriesColor = seriesOverride?.color ?? (opts.chartColors ? opts.chartColors[colorIndex % opts.chartColors.length] : null);
|
|
2519
2628
|
strXml += " <c:spPr>";
|
|
2520
2629
|
if (seriesColor === "transparent") strXml += "<a:noFill/>";
|
|
2521
2630
|
else if (opts.chartColorsOpacity) strXml += "<a:solidFill>" + createColorElement(seriesColor, `<a:alpha val="${Math.round(opts.chartColorsOpacity * 1e3)}"/>`) + "</a:solidFill>";
|
|
2522
2631
|
else strXml += "<a:solidFill>" + createColorElement(seriesColor) + "</a:solidFill>";
|
|
2523
|
-
if (chartType === "line" || chartType === "radar")
|
|
2524
|
-
|
|
2525
|
-
strXml +=
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2632
|
+
if (chartType === "line" || chartType === "radar") {
|
|
2633
|
+
const effectiveLineSize = seriesOverride?.lineSize ?? opts.lineSize;
|
|
2634
|
+
if (effectiveLineSize === 0) strXml += "<a:ln><a:noFill/></a:ln>";
|
|
2635
|
+
else {
|
|
2636
|
+
strXml += `<a:ln w="${valToPts(effectiveLineSize)}" cap="${createLineCap(opts.lineCap)}"><a:solidFill>${createColorElement(seriesColor)}</a:solidFill>`;
|
|
2637
|
+
strXml += `<a:prstDash val="${opts.lineDashValues?.[colorIndex] ?? opts.lineDash ?? "solid"}"/><a:round/></a:ln>`;
|
|
2638
|
+
}
|
|
2639
|
+
} else if (opts.dataBorder) strXml += `<a:ln w="${valToPts(opts.dataBorder.pt)}" cap="${createLineCap(opts.lineCap)}"><a:solidFill>${createColorElement(opts.dataBorder.color)}</a:solidFill><a:prstDash val="solid"/><a:round/></a:ln>`;
|
|
2529
2640
|
strXml += createShadowElement(opts.shadow, DEF_SHAPE_SHADOW);
|
|
2530
2641
|
strXml += " </c:spPr>";
|
|
2531
2642
|
if (chartType !== "line" && chartType !== "radar") strXml += " <c:invertIfNegative val=\"0\"/>";
|
|
@@ -2544,13 +2655,18 @@ function makeChartType(chartType, data, opts, valAxisId, catAxisId) {
|
|
|
2544
2655
|
strXml += "</c:marker>";
|
|
2545
2656
|
}
|
|
2546
2657
|
if (chartType !== "radar") {
|
|
2658
|
+
const lblColor = seriesOverride?.dataLabelColor ?? opts.dataLabelColor ?? "000000";
|
|
2659
|
+
const lblBold = seriesOverride?.dataLabelFontBold ?? opts.dataLabelFontBold ?? false;
|
|
2660
|
+
const lblItalic = seriesOverride?.dataLabelFontItalic ?? opts.dataLabelFontItalic ?? false;
|
|
2661
|
+
const lblSize = seriesOverride?.dataLabelFontSize ?? opts.dataLabelFontSize ?? 12;
|
|
2662
|
+
const lblFace = seriesOverride?.dataLabelFontFace ?? opts.dataLabelFontFace ?? "Arial";
|
|
2547
2663
|
strXml += "<c:dLbls>";
|
|
2548
2664
|
strXml += `<c:numFmt formatCode="${encodeXmlEntities(opts.dataLabelFormatCode) || "General"}" sourceLinked="0"/>`;
|
|
2549
2665
|
if (opts.dataLabelBkgrdColors) strXml += `<c:spPr><a:solidFill>${createColorElement(seriesColor)}</a:solidFill></c:spPr>`;
|
|
2550
2666
|
strXml += "<c:txPr><a:bodyPr/><a:lstStyle/><a:p><a:pPr>";
|
|
2551
|
-
strXml += `<a:defRPr b="${
|
|
2552
|
-
strXml += `<a:solidFill>${createColorElement(
|
|
2553
|
-
strXml += `<a:latin typeface="${
|
|
2667
|
+
strXml += `<a:defRPr b="${lblBold ? 1 : 0}" i="${lblItalic ? 1 : 0}" strike="noStrike" sz="${Math.round(lblSize * 100)}" u="none">`;
|
|
2668
|
+
strXml += `<a:solidFill>${createColorElement(lblColor)}</a:solidFill>`;
|
|
2669
|
+
strXml += `<a:latin typeface="${lblFace}"/>`;
|
|
2554
2670
|
strXml += "</a:defRPr></a:pPr></a:p></c:txPr>";
|
|
2555
2671
|
if (opts.dataLabelPosition) strXml += `<c:dLblPos val="${opts.dataLabelPosition}"/>`;
|
|
2556
2672
|
strXml += "<c:showLegendKey val=\"0\"/>";
|
|
@@ -3524,6 +3640,15 @@ const ImageSizingXml = {
|
|
|
3524
3640
|
const r = imgSize.w - (boxDim.x + boxDim.w);
|
|
3525
3641
|
const t = boxDim.y;
|
|
3526
3642
|
const b = imgSize.h - (boxDim.y + boxDim.h);
|
|
3643
|
+
if (l < 0 || r < 0 || t < 0 || b < 0) {
|
|
3644
|
+
const over = [
|
|
3645
|
+
l < 0 && `x (${l < 0 ? -l : 0} past left edge)`,
|
|
3646
|
+
r < 0 && `x+w (${-r} past right edge)`,
|
|
3647
|
+
t < 0 && `y (${-t} past top edge)`,
|
|
3648
|
+
b < 0 && `y+h (${-b} past bottom edge)`
|
|
3649
|
+
].filter(Boolean).join(", ");
|
|
3650
|
+
throw new Error(`addImage sizing.type 'crop': crop window overflows image bounds — ${over}. Ensure x≥0, y≥0, x+w≤w, y+h≤h.`);
|
|
3651
|
+
}
|
|
3527
3652
|
return `<a:srcRect l="${Math.round(1e5 * (l / imgSize.w))}" r="${Math.round(1e5 * (r / imgSize.w))}" t="${Math.round(1e5 * (t / imgSize.h))}" b="${Math.round(1e5 * (b / imgSize.h))}"/><a:stretch/>`;
|
|
3528
3653
|
}
|
|
3529
3654
|
};
|
|
@@ -3536,10 +3661,16 @@ const ImageSizingXml = {
|
|
|
3536
3661
|
* @param {number} cy - shape height (EMU), used to scale `rectRadius`
|
|
3537
3662
|
* @return {string} `<a:prstGeom>` XML
|
|
3538
3663
|
*/
|
|
3664
|
+
const RECT_RADIUS_ADJ1_SHAPES = new Set(["round2SameRect", "round2DiagRect"]);
|
|
3539
3665
|
function genXmlPresetGeom(shapeName, options, cx, cy) {
|
|
3540
3666
|
let strXml = `<a:prstGeom prst="${shapeName}"><a:avLst>`;
|
|
3541
|
-
if (options.rectRadius)
|
|
3542
|
-
|
|
3667
|
+
if (options.rectRadius) {
|
|
3668
|
+
const adjVal = Math.round(options.rectRadius * EMU * 1e5 / Math.min(cx, cy));
|
|
3669
|
+
if (RECT_RADIUS_ADJ1_SHAPES.has(shapeName)) {
|
|
3670
|
+
strXml += `<a:gd name="adj1" fmla="val ${adjVal}"/>`;
|
|
3671
|
+
strXml += "<a:gd name=\"adj2\" fmla=\"val 0\"/>";
|
|
3672
|
+
} else strXml += `<a:gd name="adj" fmla="val ${adjVal}"/>`;
|
|
3673
|
+
} else if (options.angleRange) {
|
|
3543
3674
|
for (let i = 0; i < 2; i++) {
|
|
3544
3675
|
const angle = options.angleRange[i];
|
|
3545
3676
|
strXml += `<a:gd name="adj${i + 1}" fmla="val ${convertRotationDegrees(angle)}" />`;
|
|
@@ -3660,7 +3791,11 @@ function slideObjectToXml(slide) {
|
|
|
3660
3791
|
strXml = `<p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id="${intTableNum * slide._slideNum + 1}" name="${slideItemObj.options.objectName}" descr="${encodeXmlEntities(slideItemObj.options.altText || "")}"/>`;
|
|
3661
3792
|
strXml += "<p:cNvGraphicFramePr><a:graphicFrameLocks noGrp=\"1\"/></p:cNvGraphicFramePr> <p:nvPr><p:extLst><p:ext uri=\"{D42A27DB-BD31-4B8C-83A1-F6EECF244321}\"><p14:modId xmlns:p14=\"http://schemas.microsoft.com/office/powerpoint/2010/main\" val=\"1579011935\"/></p:ext></p:extLst></p:nvPr></p:nvGraphicFramePr>";
|
|
3662
3793
|
strXml += `<p:xfrm><a:off x="${x || (x === 0 ? 0 : EMU)}" y="${y || (y === 0 ? 0 : EMU)}"/><a:ext cx="${cx || (cx === 0 ? 0 : EMU)}" cy="${cy || EMU}"/></p:xfrm>`;
|
|
3663
|
-
|
|
3794
|
+
{
|
|
3795
|
+
const tblPrAttrs = (objTabOpts.hasHeader ? " firstRow=\"1\"" : "") + (objTabOpts.hasFooter ? " lastRow=\"1\"" : "") + (objTabOpts.hasBandedRows ? " bandRow=\"1\"" : "") + (objTabOpts.hasBandedColumns ? " bandCol=\"1\"" : "") + (objTabOpts.hasFirstColumn ? " firstCol=\"1\"" : "") + (objTabOpts.hasLastColumn ? " lastCol=\"1\"" : "");
|
|
3796
|
+
const tblPr = objTabOpts.tableStyle ? `<a:tblPr${tblPrAttrs}><a:tableStyleId>${objTabOpts.tableStyle}</a:tableStyleId></a:tblPr>` : `<a:tblPr${tblPrAttrs}/>`;
|
|
3797
|
+
strXml += `<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table"><a:tbl>${tblPr}`;
|
|
3798
|
+
}
|
|
3664
3799
|
if (Array.isArray(objTabOpts.colW)) {
|
|
3665
3800
|
strXml += "<a:tblGrid>";
|
|
3666
3801
|
for (let col = 0; col < intColCnt; col++) {
|
|
@@ -3883,6 +4018,7 @@ function slideObjectToXml(slide) {
|
|
|
3883
4018
|
if ((slide._relsMedia || []).find((rel) => rel.rId === slideItemObj.imageRid)?.extn === "svg") {
|
|
3884
4019
|
strSlideXml += `<a:blip r:embed="rId${slideItemObj.imageRid - 1}">`;
|
|
3885
4020
|
strSlideXml += slideItemObj.options.transparency ? ` <a:alphaModFix amt="${Math.round((100 - slideItemObj.options.transparency) * 1e3)}"/>` : "";
|
|
4021
|
+
strSlideXml += slideItemObj.options.duotone ? `<a:duotone>${createColorElement(slideItemObj.options.duotone.shadow)}${createColorElement(slideItemObj.options.duotone.highlight)}</a:duotone>` : "";
|
|
3886
4022
|
strSlideXml += " <a:extLst>";
|
|
3887
4023
|
strSlideXml += " <a:ext uri=\"{96DAC541-7B7A-43D3-8B79-37D633B846F1}\">";
|
|
3888
4024
|
strSlideXml += ` <asvg:svgBlip xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main" r:embed="rId${slideItemObj.imageRid}"/>`;
|
|
@@ -3892,6 +4028,7 @@ function slideObjectToXml(slide) {
|
|
|
3892
4028
|
} else {
|
|
3893
4029
|
strSlideXml += `<a:blip r:embed="rId${slideItemObj.imageRid}">`;
|
|
3894
4030
|
strSlideXml += slideItemObj.options.transparency ? `<a:alphaModFix amt="${Math.round((100 - slideItemObj.options.transparency) * 1e3)}"/>` : "";
|
|
4031
|
+
strSlideXml += slideItemObj.options.duotone ? `<a:duotone>${createColorElement(slideItemObj.options.duotone.shadow)}${createColorElement(slideItemObj.options.duotone.highlight)}</a:duotone>` : "";
|
|
3895
4032
|
strSlideXml += "</a:blip>";
|
|
3896
4033
|
}
|
|
3897
4034
|
if (sizing?.type) {
|
|
@@ -3899,10 +4036,17 @@ function slideObjectToXml(slide) {
|
|
|
3899
4036
|
const boxH = sizing.h ? getSmartParseNumber(sizing.h, "Y", slide._presLayout) : cy;
|
|
3900
4037
|
const boxX = getSmartParseNumber(sizing.x || 0, "X", slide._presLayout);
|
|
3901
4038
|
const boxY = getSmartParseNumber(sizing.y || 0, "Y", slide._presLayout);
|
|
3902
|
-
|
|
4039
|
+
let cropSize = {
|
|
3903
4040
|
w: imgWidth,
|
|
3904
4041
|
h: imgHeight
|
|
3905
|
-
}
|
|
4042
|
+
};
|
|
4043
|
+
if (sizing.type === "cover" || sizing.type === "contain") {
|
|
4044
|
+
const relData = (slide._relsMedia || []).find((rel) => rel.rId === slideItemObj.imageRid)?.data;
|
|
4045
|
+
const natural = typeof relData === "string" ? getImageSizeFromBase64(relData) : null;
|
|
4046
|
+
if (natural) cropSize = natural;
|
|
4047
|
+
else console.warn(`Warning: sizing '${sizing.type}' could not measure natural dimensions for image "${slideItemObj.options.objectName}"; falling back to displayed aspect ratio (crop may be inexact). Provide a raster image (PNG/JPEG/GIF/BMP/WebP) to enable an aspect-correct crop.`);
|
|
4048
|
+
}
|
|
4049
|
+
strSlideXml += ImageSizingXml[sizing.type](cropSize, {
|
|
3906
4050
|
w: boxW,
|
|
3907
4051
|
h: boxH,
|
|
3908
4052
|
x: boxX,
|
|
@@ -4298,14 +4442,19 @@ function genXmlTextBody(slideObj) {
|
|
|
4298
4442
|
itext.options = itext.options || opts || {};
|
|
4299
4443
|
if (idx === 0 && itext.options && !itext.options.bullet && opts.bullet) itext.options.bullet = opts.bullet;
|
|
4300
4444
|
if (typeof itext.text === "string" || typeof itext.text === "number") itext.text = itext.text.toString().replace(/\r*\n/g, "\r\n");
|
|
4301
|
-
if (itext.text.includes("\r\n") && itext.text.match(/\n$/g) === null)
|
|
4302
|
-
itext.
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4445
|
+
if (itext.text.includes("\r\n") && itext.text.match(/\n$/g) === null) {
|
|
4446
|
+
const lines = itext.text.split("\r\n");
|
|
4447
|
+
lines.forEach((line, lineIdx) => {
|
|
4448
|
+
const isLast = lineIdx === lines.length - 1;
|
|
4449
|
+
arrTextObjects.push({
|
|
4450
|
+
text: line,
|
|
4451
|
+
options: {
|
|
4452
|
+
...itext.options,
|
|
4453
|
+
breakLine: isLast ? itext.options.breakLine : true
|
|
4454
|
+
}
|
|
4455
|
+
});
|
|
4306
4456
|
});
|
|
4307
|
-
});
|
|
4308
|
-
else arrTextObjects.push(itext);
|
|
4457
|
+
} else arrTextObjects.push(itext);
|
|
4309
4458
|
});
|
|
4310
4459
|
const arrLines = [];
|
|
4311
4460
|
let arrTexts = [];
|
|
@@ -4407,7 +4556,7 @@ function genXmlPlaceholder(placeholderObj) {
|
|
|
4407
4556
|
* @param {PresSlideInternal} masterSlide - master slide
|
|
4408
4557
|
* @returns XML
|
|
4409
4558
|
*/
|
|
4410
|
-
function makeXmlContTypes(slides, slideLayouts, masterSlide) {
|
|
4559
|
+
function makeXmlContTypes(slides, slideLayouts, masterSlide, hasCustomProps) {
|
|
4411
4560
|
let strXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n";
|
|
4412
4561
|
strXml += "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
|
|
4413
4562
|
strXml += "<Default Extension=\"xml\" ContentType=\"application/xml\"/>";
|
|
@@ -4457,6 +4606,7 @@ function makeXmlContTypes(slides, slideLayouts, masterSlide) {
|
|
|
4457
4606
|
});
|
|
4458
4607
|
strXml += " <Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>";
|
|
4459
4608
|
strXml += " <Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>";
|
|
4609
|
+
if (hasCustomProps) strXml += " <Override PartName=\"/docProps/custom.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.custom-properties+xml\"/>";
|
|
4460
4610
|
strXml += "</Types>";
|
|
4461
4611
|
return strXml;
|
|
4462
4612
|
}
|
|
@@ -4464,13 +4614,15 @@ function makeXmlContTypes(slides, slideLayouts, masterSlide) {
|
|
|
4464
4614
|
* Creates `_rels/.rels`
|
|
4465
4615
|
* @returns XML
|
|
4466
4616
|
*/
|
|
4467
|
-
function makeXmlRootRels() {
|
|
4468
|
-
|
|
4617
|
+
function makeXmlRootRels(hasCustomProps) {
|
|
4618
|
+
let xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
|
|
4469
4619
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
4470
4620
|
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
|
|
4471
4621
|
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
|
|
4472
|
-
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"
|
|
4473
|
-
|
|
4622
|
+
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="ppt/presentation.xml"/>`;
|
|
4623
|
+
if (hasCustomProps) xml += "\n <Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties\" Target=\"docProps/custom.xml\"/>";
|
|
4624
|
+
xml += "\n </Relationships>";
|
|
4625
|
+
return xml;
|
|
4474
4626
|
}
|
|
4475
4627
|
/**
|
|
4476
4628
|
* Creates `docProps/app.xml`
|
|
@@ -4536,6 +4688,23 @@ function makeXmlCore(title, subject, author, revision) {
|
|
|
4536
4688
|
<dcterms:modified xsi:type="dcterms:W3CDTF">${(/* @__PURE__ */ new Date()).toISOString().replace(/\.\d\d\dZ/, "Z")}</dcterms:modified>
|
|
4537
4689
|
</cp:coreProperties>`;
|
|
4538
4690
|
}
|
|
4691
|
+
const CUSTOM_PROPS_FMTID = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";
|
|
4692
|
+
/**
|
|
4693
|
+
* Creates `docProps/custom.xml`
|
|
4694
|
+
* @param props - custom property name/value pairs
|
|
4695
|
+
* @returns XML
|
|
4696
|
+
*/
|
|
4697
|
+
function makeXmlCustomProperties(props) {
|
|
4698
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
|
|
4699
|
+
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">${props.map(({ name, value }, idx) => {
|
|
4700
|
+
let valueXml;
|
|
4701
|
+
if (typeof value === "boolean") valueXml = `<vt:bool>${value}</vt:bool>`;
|
|
4702
|
+
else if (value instanceof Date) valueXml = `<vt:filetime>${value.toISOString().replace(/\.\d{3}Z$/, "Z")}</vt:filetime>`;
|
|
4703
|
+
else if (typeof value === "number") valueXml = Number.isInteger(value) ? `<vt:i4>${value}</vt:i4>` : `<vt:r8>${value}</vt:r8>`;
|
|
4704
|
+
else valueXml = `<vt:lpwstr>${encodeXmlEntities(String(value))}</vt:lpwstr>`;
|
|
4705
|
+
return `<property fmtid="${CUSTOM_PROPS_FMTID}" pid="${idx + 2}" name="${encodeXmlEntities(name)}">${valueXml}</property>`;
|
|
4706
|
+
}).join("")}</Properties>`;
|
|
4707
|
+
}
|
|
4539
4708
|
/**
|
|
4540
4709
|
* Creates `ppt/_rels/presentation.xml.rels`
|
|
4541
4710
|
* @param {PresSlideInternal[]} slides - Presenation Slides
|
|
@@ -4712,7 +4881,7 @@ function makeXmlTheme(pres) {
|
|
|
4712
4881
|
*/
|
|
4713
4882
|
function makeXmlPresentation(pres) {
|
|
4714
4883
|
let strXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
|
|
4715
|
-
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" ${pres.rtlMode ? "rtl=\"1\"" : ""} saveSubsetFonts="1" autoCompressPictures="0">`;
|
|
4884
|
+
<p:presentation xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" ${pres.rtlMode ? "rtl=\"1\"" : ""} saveSubsetFonts="1" autoCompressPictures="0"${pres.firstSlideNum !== 1 ? ` firstSlideNum="${pres.firstSlideNum}"` : ""}>`;
|
|
4716
4885
|
strXml += "<p:sldMasterIdLst><p:sldMasterId id=\"2147483648\" r:id=\"rId1\"/></p:sldMasterIdLst>";
|
|
4717
4886
|
strXml += `<p:notesMasterIdLst><p:notesMasterId r:id="rId${pres.slides.length + 2}"/></p:notesMasterIdLst>`;
|
|
4718
4887
|
strXml += "<p:sldIdLst>";
|
|
@@ -4751,9 +4920,96 @@ function makeXmlPresProps() {
|
|
|
4751
4920
|
* @see: http://openxmldeveloper.org/discussions/formats/f/13/p/2398/8107.aspx
|
|
4752
4921
|
* @return {string} XML
|
|
4753
4922
|
*/
|
|
4754
|
-
function makeXmlTableStyles() {
|
|
4755
|
-
|
|
4756
|
-
<a:tblStyleLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" def="{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"
|
|
4923
|
+
function makeXmlTableStyles(tableStyles = []) {
|
|
4924
|
+
const open = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
|
|
4925
|
+
<a:tblStyleLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" def="{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"`;
|
|
4926
|
+
if (!tableStyles || tableStyles.length === 0) return `${open}/>`;
|
|
4927
|
+
let strXml = `${open}>`;
|
|
4928
|
+
tableStyles.forEach(({ guid, def }) => {
|
|
4929
|
+
strXml += `<a:tblStyle styleId="${guid}" styleName="${encodeXmlEntities(def.name)}">`;
|
|
4930
|
+
[
|
|
4931
|
+
["wholeTbl", def.wholeTbl],
|
|
4932
|
+
["band1H", def.band1H],
|
|
4933
|
+
["band2H", def.band2H],
|
|
4934
|
+
["band1V", def.band1V],
|
|
4935
|
+
["band2V", def.band2V],
|
|
4936
|
+
["lastCol", def.lastCol],
|
|
4937
|
+
["firstCol", def.firstCol],
|
|
4938
|
+
["lastRow", def.lastRow],
|
|
4939
|
+
["firstRow", def.firstRow]
|
|
4940
|
+
].forEach(([name, region]) => {
|
|
4941
|
+
if (region) strXml += genXmlTableStyleRegion(name, region);
|
|
4942
|
+
});
|
|
4943
|
+
strXml += "</a:tblStyle>";
|
|
4944
|
+
});
|
|
4945
|
+
strXml += "</a:tblStyleLst>";
|
|
4946
|
+
return strXml;
|
|
4947
|
+
}
|
|
4948
|
+
/**
|
|
4949
|
+
* Build one `CT_TablePartStyle` region (e.g. `firstRow`, `band1H`) for a custom table style.
|
|
4950
|
+
* Emits `tcTxStyle` (text) before `tcStyle` (cell fill/borders) per the schema sequence.
|
|
4951
|
+
* @param {string} name - region element name
|
|
4952
|
+
* @param {TableStyleRegionProps} region - region styling
|
|
4953
|
+
* @return {string} XML
|
|
4954
|
+
*/
|
|
4955
|
+
function genXmlTableStyleRegion(name, region) {
|
|
4956
|
+
let xml = `<a:${name}>`;
|
|
4957
|
+
if (region.bold !== void 0 || region.italic !== void 0 || region.color) {
|
|
4958
|
+
const b = region.bold ? " b=\"on\"" : "";
|
|
4959
|
+
const i = region.italic ? " i=\"on\"" : "";
|
|
4960
|
+
xml += `<a:tcTxStyle${b}${i}><a:fontRef idx="minor"/>`;
|
|
4961
|
+
xml += region.color ? createColorElement(region.color) : "";
|
|
4962
|
+
xml += "</a:tcTxStyle>";
|
|
4963
|
+
}
|
|
4964
|
+
if (region.border !== void 0 || region.fill !== void 0) {
|
|
4965
|
+
xml += "<a:tcStyle>";
|
|
4966
|
+
if (region.border !== void 0) xml += genXmlTableStyleBorders(region.border);
|
|
4967
|
+
if (region.fill !== void 0) xml += `<a:fill><a:solidFill>${createColorElement(region.fill)}</a:solidFill></a:fill>`;
|
|
4968
|
+
xml += "</a:tcStyle>";
|
|
4969
|
+
}
|
|
4970
|
+
xml += `</a:${name}>`;
|
|
4971
|
+
return xml;
|
|
4972
|
+
}
|
|
4973
|
+
/**
|
|
4974
|
+
* Build the `tcBdr` border block for a custom table style region.
|
|
4975
|
+
* A single `BorderProps` styles all four sides plus the interior grid lines; a
|
|
4976
|
+
* TRBL array styles only the four outer sides. Sides are emitted in schema order.
|
|
4977
|
+
* @param {BorderProps | BorderProps[]} border - border definition
|
|
4978
|
+
* @return {string} XML
|
|
4979
|
+
*/
|
|
4980
|
+
function genXmlTableStyleBorders(border) {
|
|
4981
|
+
let sides;
|
|
4982
|
+
if (Array.isArray(border)) {
|
|
4983
|
+
const [top, right, bottom, left] = border;
|
|
4984
|
+
sides = [
|
|
4985
|
+
["left", left],
|
|
4986
|
+
["right", right],
|
|
4987
|
+
["top", top],
|
|
4988
|
+
["bottom", bottom]
|
|
4989
|
+
];
|
|
4990
|
+
} else sides = [
|
|
4991
|
+
["left", border],
|
|
4992
|
+
["right", border],
|
|
4993
|
+
["top", border],
|
|
4994
|
+
["bottom", border],
|
|
4995
|
+
["insideH", border],
|
|
4996
|
+
["insideV", border]
|
|
4997
|
+
];
|
|
4998
|
+
let xml = "<a:tcBdr>";
|
|
4999
|
+
sides.forEach(([side, b]) => {
|
|
5000
|
+
if (!b) return;
|
|
5001
|
+
xml += `<a:${side}>`;
|
|
5002
|
+
if (b.type === "none") xml += "<a:ln><a:noFill/></a:ln>";
|
|
5003
|
+
else {
|
|
5004
|
+
xml += `<a:ln w="${valToPts(b.pt ?? 1)}" cap="flat" cmpd="sng" algn="ctr">`;
|
|
5005
|
+
xml += `<a:solidFill>${createColorElement(b.color ?? "666666")}</a:solidFill>`;
|
|
5006
|
+
xml += `<a:prstDash val="${b.type === "dash" ? "sysDash" : "solid"}"/>`;
|
|
5007
|
+
xml += "</a:ln>";
|
|
5008
|
+
}
|
|
5009
|
+
xml += `</a:${side}>`;
|
|
5010
|
+
});
|
|
5011
|
+
xml += "</a:tcBdr>";
|
|
5012
|
+
return xml;
|
|
4757
5013
|
}
|
|
4758
5014
|
/**
|
|
4759
5015
|
* Creates `ppt/viewProps.xml`
|
|
@@ -4823,7 +5079,7 @@ function makeXmlViewProps() {
|
|
|
4823
5079
|
* @see https://docs.microsoft.com/en-us/office/open-xml/structure-of-a-presentationml-document
|
|
4824
5080
|
* @see https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2010/hh273476(v=office.14)
|
|
4825
5081
|
*/
|
|
4826
|
-
const VERSION = "5.
|
|
5082
|
+
const VERSION = "5.2.0";
|
|
4827
5083
|
function standardLayoutToPresLayout(layout) {
|
|
4828
5084
|
return {
|
|
4829
5085
|
name: layout.name,
|
|
@@ -4924,6 +5180,14 @@ var PptxGenJS = class {
|
|
|
4924
5180
|
get title() {
|
|
4925
5181
|
return this._title;
|
|
4926
5182
|
}
|
|
5183
|
+
/** Slide number shown on the first slide (maps to firstSlideNum in presentation.xml) */
|
|
5184
|
+
_firstSlideNum;
|
|
5185
|
+
set firstSlideNum(value) {
|
|
5186
|
+
this._firstSlideNum = value;
|
|
5187
|
+
}
|
|
5188
|
+
get firstSlideNum() {
|
|
5189
|
+
return this._firstSlideNum;
|
|
5190
|
+
}
|
|
4927
5191
|
/**
|
|
4928
5192
|
* Whether Right-to-Left (RTL) mode is enabled
|
|
4929
5193
|
* @type {boolean}
|
|
@@ -4950,6 +5214,9 @@ var PptxGenJS = class {
|
|
|
4950
5214
|
get sections() {
|
|
4951
5215
|
return this._sections;
|
|
4952
5216
|
}
|
|
5217
|
+
/** custom document properties stored in docProps/custom.xml */
|
|
5218
|
+
_customProperties;
|
|
5219
|
+
_tableStyles;
|
|
4953
5220
|
/** slide layout definition objects, used for generating slide layout files */
|
|
4954
5221
|
_slideLayouts;
|
|
4955
5222
|
get slideLayouts() {
|
|
@@ -4959,6 +5226,7 @@ var PptxGenJS = class {
|
|
|
4959
5226
|
return {
|
|
4960
5227
|
author: this.author,
|
|
4961
5228
|
company: this.company,
|
|
5229
|
+
firstSlideNum: this.firstSlideNum,
|
|
4962
5230
|
layout: this.layout,
|
|
4963
5231
|
masterSlide: this._masterSlide,
|
|
4964
5232
|
presLayout: this.presLayout,
|
|
@@ -5043,6 +5311,7 @@ var PptxGenJS = class {
|
|
|
5043
5311
|
width: this.LAYOUTS[DEF_PRES_LAYOUT].width,
|
|
5044
5312
|
height: this.LAYOUTS[DEF_PRES_LAYOUT].height
|
|
5045
5313
|
};
|
|
5314
|
+
this._firstSlideNum = 1;
|
|
5046
5315
|
this._rtlMode = false;
|
|
5047
5316
|
this._slideLayouts = [{
|
|
5048
5317
|
_margin: DEF_SLIDE_MARGIN_IN,
|
|
@@ -5058,6 +5327,8 @@ var PptxGenJS = class {
|
|
|
5058
5327
|
}];
|
|
5059
5328
|
this._slides = [];
|
|
5060
5329
|
this._sections = [];
|
|
5330
|
+
this._customProperties = [];
|
|
5331
|
+
this._tableStyles = [];
|
|
5061
5332
|
this._masterSlide = {
|
|
5062
5333
|
addChart: null,
|
|
5063
5334
|
addImage: null,
|
|
@@ -5086,7 +5357,8 @@ var PptxGenJS = class {
|
|
|
5086
5357
|
*/
|
|
5087
5358
|
addNewSlide = (options) => {
|
|
5088
5359
|
const nextOptions = options || {};
|
|
5089
|
-
|
|
5360
|
+
const lastSlide = this._slides[this._slides.length - 1];
|
|
5361
|
+
nextOptions.sectionTitle = this._sections.find((sect) => sect._slides.some((s) => s._slideNum === lastSlide._slideNum))?.title ?? null;
|
|
5090
5362
|
return this.addSlide(nextOptions);
|
|
5091
5363
|
};
|
|
5092
5364
|
/**
|
|
@@ -5156,16 +5428,18 @@ var PptxGenJS = class {
|
|
|
5156
5428
|
zip.folder("ppt/theme");
|
|
5157
5429
|
zip.folder("ppt/notesMasters").folder("_rels");
|
|
5158
5430
|
zip.folder("ppt/notesSlides").folder("_rels");
|
|
5159
|
-
|
|
5160
|
-
zip.file("
|
|
5431
|
+
const hasCustomProps = this._customProperties.length > 0;
|
|
5432
|
+
zip.file("[Content_Types].xml", makeXmlContTypes(this._slides, this._slideLayouts, this._masterSlide, hasCustomProps));
|
|
5433
|
+
zip.file("_rels/.rels", makeXmlRootRels(hasCustomProps));
|
|
5161
5434
|
zip.file("docProps/app.xml", makeXmlApp(this._slides, this.company));
|
|
5162
5435
|
zip.file("docProps/core.xml", makeXmlCore(this.title, this.subject, this.author, this.revision));
|
|
5436
|
+
if (hasCustomProps) zip.file("docProps/custom.xml", makeXmlCustomProperties(this._customProperties));
|
|
5163
5437
|
zip.file("ppt/_rels/presentation.xml.rels", makeXmlPresentationRels(this._slides));
|
|
5164
5438
|
zip.file("ppt/theme/theme1.xml", makeXmlTheme(this.internalPresentation));
|
|
5165
5439
|
zip.file("ppt/theme/theme2.xml", makeXmlTheme(this.internalPresentation));
|
|
5166
5440
|
zip.file("ppt/presentation.xml", makeXmlPresentation(this.internalPresentation));
|
|
5167
5441
|
zip.file("ppt/presProps.xml", makeXmlPresProps());
|
|
5168
|
-
zip.file("ppt/tableStyles.xml", makeXmlTableStyles());
|
|
5442
|
+
zip.file("ppt/tableStyles.xml", makeXmlTableStyles(this._tableStyles));
|
|
5169
5443
|
zip.file("ppt/viewProps.xml", makeXmlViewProps());
|
|
5170
5444
|
this._slideLayouts.forEach((layout, idx) => {
|
|
5171
5445
|
zip.file(`ppt/slideLayouts/slideLayout${idx + 1}.xml`, makeXmlLayout(layout));
|
|
@@ -5245,6 +5519,19 @@ var PptxGenJS = class {
|
|
|
5245
5519
|
return await this._runtime.writeFile(fileName, data);
|
|
5246
5520
|
}
|
|
5247
5521
|
/**
|
|
5522
|
+
* Set a custom document property stored in `docProps/custom.xml`.
|
|
5523
|
+
* Calling with the same name replaces the existing value.
|
|
5524
|
+
* @param name - property name
|
|
5525
|
+
* @param value - string, integer/float number, boolean, or Date
|
|
5526
|
+
*/
|
|
5527
|
+
setCustomProperty(name, value) {
|
|
5528
|
+
this._customProperties = this._customProperties.filter((p) => p.name !== name);
|
|
5529
|
+
this._customProperties.push({
|
|
5530
|
+
name,
|
|
5531
|
+
value
|
|
5532
|
+
});
|
|
5533
|
+
}
|
|
5534
|
+
/**
|
|
5248
5535
|
* Add a new Section to Presentation
|
|
5249
5536
|
* @param {ISectionProps} section - section properties
|
|
5250
5537
|
* @example pptx.addSection({ title:'Charts' });
|
|
@@ -5353,6 +5640,31 @@ var PptxGenJS = class {
|
|
|
5353
5640
|
if (newLayout._slideNumberProps && !this._masterSlide._slideNumberProps) this._masterSlide._slideNumberProps = newLayout._slideNumberProps;
|
|
5354
5641
|
}
|
|
5355
5642
|
/**
|
|
5643
|
+
* Register a reusable custom table style and return its GUID.
|
|
5644
|
+
* The style is written to `ppt/tableStyles.xml` and is editable in PowerPoint's
|
|
5645
|
+
* Table Styles gallery. Pass the returned GUID as `TableProps.tableStyle`, and use
|
|
5646
|
+
* the `has*` flags (`hasHeader`, `hasBandedRows`, …) to activate the matching regions.
|
|
5647
|
+
* @param {TableStyleProps} props - custom table style definition (requires `name`)
|
|
5648
|
+
* @returns {string} braced GUID to use as `tableStyle`
|
|
5649
|
+
* @example
|
|
5650
|
+
* const brand = pptx.defineTableStyle({
|
|
5651
|
+
* name: 'Brand Banded',
|
|
5652
|
+
* firstRow: { fill:'1A2B3C', color:'FFFFFF', bold:true },
|
|
5653
|
+
* band1H: { fill:'EAF1F8' },
|
|
5654
|
+
* })
|
|
5655
|
+
* slide.addTable(rows, { tableStyle: brand, hasHeader:true, hasBandedRows:true })
|
|
5656
|
+
*/
|
|
5657
|
+
defineTableStyle(props) {
|
|
5658
|
+
if (!props || typeof props !== "object") throw new Error("defineTableStyle() requires a `{ name, ... }` object argument");
|
|
5659
|
+
if (!props.name || typeof props.name !== "string") throw new Error("defineTableStyle() requires a non-empty `name`");
|
|
5660
|
+
const guid = `{${getUuid("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx").toUpperCase()}}`;
|
|
5661
|
+
this._tableStyles.push({
|
|
5662
|
+
guid,
|
|
5663
|
+
def: props
|
|
5664
|
+
});
|
|
5665
|
+
return guid;
|
|
5666
|
+
}
|
|
5667
|
+
/**
|
|
5356
5668
|
* Reproduces an HTML table as a PowerPoint table - including column widths, style, etc. - creates 1 or more slides as needed
|
|
5357
5669
|
* @param {string} eleId - table HTML element ID
|
|
5358
5670
|
* @param {TableToSlidesProps} options - generation options
|
|
@@ -5364,4 +5676,4 @@ var PptxGenJS = class {
|
|
|
5364
5676
|
//#endregion
|
|
5365
5677
|
export { PptxGenJS as t };
|
|
5366
5678
|
|
|
5367
|
-
//# sourceMappingURL=pptxgen
|
|
5679
|
+
//# sourceMappingURL=pptxgen--5RWzhb4.js.map
|