@silurus/ooxml 0.1.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.
@@ -0,0 +1,1172 @@
1
+ declare interface ArrowEnd {
2
+ /** OOXML type: "none" | "triangle" | "stealth" | "diamond" | "oval" | "arrow" */
3
+ type: string;
4
+ /** Width multiplier: "sm" | "med" | "lg" */
5
+ w: string;
6
+ /** Length multiplier: "sm" | "med" | "lg" */
7
+ len: string;
8
+ }
9
+
10
+ declare type BodyElement = {
11
+ type: 'paragraph';
12
+ } & DocParagraph | {
13
+ type: 'table';
14
+ } & DocTable | {
15
+ type: 'pageBreak';
16
+ };
17
+
18
+ declare interface Border {
19
+ left: BorderEdge | null;
20
+ right: BorderEdge | null;
21
+ top: BorderEdge | null;
22
+ bottom: BorderEdge | null;
23
+ diagonalUp?: BorderEdge | null;
24
+ diagonalDown?: BorderEdge | null;
25
+ }
26
+
27
+ declare interface BorderEdge {
28
+ style: string;
29
+ color: string | null;
30
+ }
31
+
32
+ declare interface BorderSpec {
33
+ width: number;
34
+ color: string | null;
35
+ style: string;
36
+ }
37
+
38
+ declare type Bullet = {
39
+ type: 'none';
40
+ } | {
41
+ type: 'inherit';
42
+ } | {
43
+ type: 'char';
44
+ char: string;
45
+ color: string | null;
46
+ sizePct: number | null;
47
+ fontFamily: string | null;
48
+ } | {
49
+ type: 'autoNum';
50
+ numType: string;
51
+ startAt: number | null;
52
+ };
53
+
54
+ declare interface Cell {
55
+ col: number;
56
+ row: number;
57
+ colRef: string;
58
+ value: CellValue;
59
+ styleIndex: number;
60
+ }
61
+
62
+ declare interface CellBorders {
63
+ top: BorderSpec | null;
64
+ bottom: BorderSpec | null;
65
+ left: BorderSpec | null;
66
+ right: BorderSpec | null;
67
+ }
68
+
69
+ declare interface CellRange {
70
+ top: number;
71
+ left: number;
72
+ bottom: number;
73
+ right: number;
74
+ }
75
+
76
+ declare type CellValue = {
77
+ type: 'empty';
78
+ } | {
79
+ type: 'text';
80
+ text: string;
81
+ runs?: Run[];
82
+ } | {
83
+ type: 'number';
84
+ number: number;
85
+ } | {
86
+ type: 'bool';
87
+ bool: boolean;
88
+ } | {
89
+ type: 'error';
90
+ error: string;
91
+ };
92
+
93
+ declare interface CellXf {
94
+ fontId: number;
95
+ fillId: number;
96
+ borderId: number;
97
+ numFmtId: number;
98
+ alignH: string | null;
99
+ alignV: string | null;
100
+ wrapText: boolean;
101
+ /** Indentation level (each level ≈ 3 characters, ECMA-376 §18.8.44) */
102
+ indent?: number;
103
+ /** Text rotation: 1–90 = counter-clockwise °, 91–180 = (val−90)° clockwise, 255 = stacked */
104
+ textRotation?: number;
105
+ shrinkToFit?: boolean;
106
+ }
107
+
108
+ declare type CfRule = {
109
+ type: 'cellIs';
110
+ operator: string;
111
+ formulas: string[];
112
+ dxfId: number | null;
113
+ priority: number;
114
+ } | {
115
+ type: 'expression';
116
+ formula: string;
117
+ dxfId: number | null;
118
+ priority: number;
119
+ } | {
120
+ type: 'colorScale';
121
+ stops: CfStop[];
122
+ priority: number;
123
+ } | {
124
+ type: 'dataBar';
125
+ color: string;
126
+ min: CfValue;
127
+ max: CfValue;
128
+ priority: number;
129
+ } | {
130
+ type: 'top10';
131
+ top: boolean;
132
+ percent: boolean;
133
+ rank: number;
134
+ dxfId: number | null;
135
+ priority: number;
136
+ } | {
137
+ type: 'aboveAverage';
138
+ aboveAverage: boolean;
139
+ dxfId: number | null;
140
+ priority: number;
141
+ } | {
142
+ type: 'iconSet';
143
+ iconSet: string;
144
+ cfvos: CfValue[];
145
+ reverse: boolean;
146
+ priority: number;
147
+ } | {
148
+ type: 'other';
149
+ kind: string;
150
+ priority: number;
151
+ };
152
+
153
+ declare interface CfStop {
154
+ kind: string;
155
+ value: string | null;
156
+ color: string;
157
+ }
158
+
159
+ declare interface CfValue {
160
+ kind: string;
161
+ value: string | null;
162
+ }
163
+
164
+ declare interface ChartAnchor {
165
+ fromCol: number;
166
+ fromColOff: number;
167
+ fromRow: number;
168
+ fromRowOff: number;
169
+ toCol: number;
170
+ toColOff: number;
171
+ toRow: number;
172
+ toRowOff: number;
173
+ chart: ChartData;
174
+ }
175
+
176
+ /**
177
+ * XLSX parser's raw chart output. Retains parser-native `barDir` + `grouping`
178
+ * which the renderer combines into a canonical `ChartModel.chartType` (e.g.
179
+ * `clusteredBarH`, `stackedBarPct`) at render time.
180
+ */
181
+ declare interface ChartData {
182
+ /** Primary chart type: "bar"|"line"|"area"|"pie"|"doughnut"|"radar"|"scatter" */
183
+ chartType: string;
184
+ /** "col" (vertical bars) | "row" (horizontal bars) */
185
+ barDir: string;
186
+ /** "clustered"|"stacked"|"standard"|"percentStacked" */
187
+ grouping: string;
188
+ title: string | null;
189
+ categories: string[];
190
+ series: XlsxChartSeries[];
191
+ /** Whether data labels are enabled (c:dLbls showVal/showPercent). */
192
+ showDataLabels?: boolean;
193
+ /** Category axis title (c:catAx/c:title). */
194
+ catAxisTitle?: string | null;
195
+ /** Value axis title (c:valAx/c:title). */
196
+ valAxisTitle?: string | null;
197
+ }
198
+
199
+ /**
200
+ * PPTX chart element. The Rust parser emits ChartModel fields flat at the
201
+ * top level, alongside the element position (x/y/width/height in EMU).
202
+ * Pass this straight to `renderChart` from `@silurus/ooxml-core`.
203
+ */
204
+ declare interface ChartElement {
205
+ type: 'chart';
206
+ x: number;
207
+ y: number;
208
+ width: number;
209
+ height: number;
210
+ chartType: string;
211
+ title: string | null;
212
+ categories: string[];
213
+ series: ChartSeries[];
214
+ valMax: number | null;
215
+ valMin: number | null;
216
+ subtotalIndices: number[];
217
+ showDataLabels: boolean;
218
+ catAxisHidden: boolean;
219
+ valAxisHidden: boolean;
220
+ plotAreaBg: string | null;
221
+ }
222
+
223
+ declare interface ChartSeries {
224
+ name: string;
225
+ /** Hex without '#'. null = fall back to palette. */
226
+ color: string | null;
227
+ /** Numeric values; null = missing data point. */
228
+ values: (number | null)[];
229
+ /**
230
+ * Per-data-point colors (pie / doughnut). Hex without '#'. null inside the
231
+ * array = use palette for that slice. Omit entirely for non-pie series.
232
+ */
233
+ dataPointColors?: (string | null)[] | null;
234
+ /**
235
+ * Mixed chart: per-series chart type override. Currently only "line" (XLSX)
236
+ * is honoured; other values are treated as the chart's primary type.
237
+ */
238
+ seriesType?: string | null;
239
+ /**
240
+ * Scatter-only X values (as strings). When null the series uses
241
+ * `ChartModel.categories` as X.
242
+ */
243
+ categories?: string[] | null;
244
+ }
245
+
246
+ declare interface ConditionalFormat {
247
+ sqref: CellRange[];
248
+ rules: CfRule[];
249
+ }
250
+
251
+ declare interface DocParagraph {
252
+ alignment: 'left' | 'center' | 'right' | 'justify';
253
+ indentLeft: number;
254
+ indentRight: number;
255
+ indentFirst: number;
256
+ spaceBefore: number;
257
+ spaceAfter: number;
258
+ lineSpacing: LineSpacing | null;
259
+ numbering: NumberingInfo | null;
260
+ tabStops: TabStop_2[];
261
+ runs: DocRun[];
262
+ /** Paragraph background hex color (w:shd fill) */
263
+ shading?: string | null;
264
+ /** Force a page break before this paragraph (w:pageBreakBefore) */
265
+ pageBreakBefore?: boolean;
266
+ /** Suppress spacing between adjacent same-style paragraphs (w:contextualSpacing) */
267
+ contextualSpacing?: boolean;
268
+ /** Paragraph borders (w:pBdr) */
269
+ borders?: ParagraphBorders | null;
270
+ /** Style ID of the applied paragraph style */
271
+ styleId?: string | null;
272
+ /** Default font size (pt) inherited from style + direct pPr/rPr. Falls back to 10pt. */
273
+ defaultFontSize?: number;
274
+ }
275
+
276
+ declare type DocRun = {
277
+ type: 'text';
278
+ } & TextRun_2 | {
279
+ type: 'image';
280
+ } & ImageRun | {
281
+ type: 'break';
282
+ breakType: 'line' | 'page' | 'column';
283
+ } | {
284
+ type: 'field';
285
+ } & FieldRun;
286
+
287
+ declare interface DocTable {
288
+ colWidths: number[];
289
+ rows: DocTableRow[];
290
+ borders: TableBorders;
291
+ cellMarginTop: number;
292
+ cellMarginBottom: number;
293
+ cellMarginLeft: number;
294
+ cellMarginRight: number;
295
+ }
296
+
297
+ declare interface DocTableCell {
298
+ content: DocParagraph[];
299
+ colSpan: number;
300
+ vMerge: boolean | null;
301
+ borders: CellBorders;
302
+ background: string | null;
303
+ vAlign: 'top' | 'center' | 'bottom';
304
+ widthPt: number | null;
305
+ }
306
+
307
+ declare interface DocTableRow {
308
+ cells: DocTableCell[];
309
+ rowHeight: number | null;
310
+ isHeader: boolean;
311
+ }
312
+
313
+ declare interface Document_2 {
314
+ section: SectionProps;
315
+ body: BodyElement[];
316
+ headers: HeadersFooters;
317
+ footers: HeadersFooters;
318
+ }
319
+
320
+ export declare namespace docx {
321
+ export {
322
+ DocxDocument,
323
+ DocxViewer,
324
+ Document_2 as Document,
325
+ SectionProps,
326
+ DocParagraph,
327
+ DocRun,
328
+ TextRun_2 as TextRun,
329
+ ImageRun,
330
+ RenderPageOptions
331
+ }
332
+ }
333
+
334
+ declare class DocxDocument {
335
+ private _document;
336
+ private _pages;
337
+ private _worker;
338
+ private constructor();
339
+ static load(source: string | ArrayBuffer): Promise<DocxDocument>;
340
+ private _parse;
341
+ destroy(): void;
342
+ get pageCount(): number;
343
+ get document(): Document_2;
344
+ private _getPages;
345
+ renderPage(target: HTMLCanvasElement | OffscreenCanvas, pageIndex: number, opts?: RenderPageOptions): Promise<void>;
346
+ }
347
+
348
+ declare class DocxViewer {
349
+ private _doc;
350
+ private _currentPage;
351
+ private _canvas;
352
+ private _opts;
353
+ constructor(canvas: HTMLCanvasElement, opts?: DocxViewerOptions);
354
+ load(source: string | ArrayBuffer): Promise<void>;
355
+ get pageCount(): number;
356
+ get currentPage(): number;
357
+ goToPage(index: number): void;
358
+ nextPage(): void;
359
+ prevPage(): void;
360
+ private _render;
361
+ }
362
+
363
+ declare interface DocxViewerOptions extends RenderPageOptions {
364
+ container?: HTMLElement;
365
+ }
366
+
367
+ declare interface Dxf {
368
+ font: Font | null;
369
+ fill: Fill_2 | null;
370
+ border: Border | null;
371
+ }
372
+
373
+ declare interface FieldRun {
374
+ /** "page" | "numPages" | "other" */
375
+ fieldType: string;
376
+ instruction: string;
377
+ fallbackText: string;
378
+ bold: boolean;
379
+ italic: boolean;
380
+ underline: boolean;
381
+ strikethrough: boolean;
382
+ fontSize: number;
383
+ color: string | null;
384
+ fontFamily: string | null;
385
+ background: string | null;
386
+ vertAlign: 'super' | 'sub' | null;
387
+ allCaps?: boolean;
388
+ smallCaps?: boolean;
389
+ doubleStrikethrough?: boolean;
390
+ highlight?: string | null;
391
+ }
392
+
393
+ declare type Fill = SolidFill | NoFill | GradientFill;
394
+
395
+ declare interface Fill_2 {
396
+ patternType: string;
397
+ fgColor: string | null;
398
+ bgColor: string | null;
399
+ }
400
+
401
+ declare interface Font {
402
+ bold: boolean;
403
+ italic: boolean;
404
+ underline: boolean;
405
+ strike: boolean;
406
+ size: number;
407
+ color: string | null;
408
+ name: string | null;
409
+ }
410
+
411
+ declare interface GradientFill {
412
+ fillType: 'gradient';
413
+ stops: GradientStop[];
414
+ /** degrees: 0 = left→right, 90 = top→bottom */
415
+ angle: number;
416
+ /** 'linear' | 'radial' */
417
+ gradType: string;
418
+ }
419
+
420
+ declare interface GradientStop {
421
+ position: number;
422
+ color: string;
423
+ }
424
+
425
+ declare interface HeaderFooter {
426
+ body: BodyElement[];
427
+ }
428
+
429
+ declare interface HeadersFooters {
430
+ default: HeaderFooter | null;
431
+ first: HeaderFooter | null;
432
+ even: HeaderFooter | null;
433
+ }
434
+
435
+ declare interface Hyperlink {
436
+ col: number;
437
+ row: number;
438
+ url: string | null;
439
+ }
440
+
441
+ /**
442
+ * Image anchored to a rectangle of cells (EMU offsets within the anchor cells).
443
+ * 914400 EMU = 1 inch, 9525 EMU = 1 px @ 96 DPI.
444
+ */
445
+ declare interface ImageAnchor {
446
+ fromCol: number;
447
+ fromColOff: number;
448
+ fromRow: number;
449
+ fromRowOff: number;
450
+ toCol: number;
451
+ toColOff: number;
452
+ toRow: number;
453
+ toRowOff: number;
454
+ /** Data URL (data:image/png;base64,...) */
455
+ dataUrl: string;
456
+ }
457
+
458
+ declare interface ImageRun {
459
+ dataUrl: string;
460
+ widthPt: number;
461
+ heightPt: number;
462
+ /** true = wp:anchor (absolute positioned), false/undefined = wp:inline (flows with text) */
463
+ anchor?: boolean;
464
+ /** X offset in pt (anchor only) */
465
+ anchorXPt?: number;
466
+ /** Y offset in pt (anchor only) */
467
+ anchorYPt?: number;
468
+ /**
469
+ * If true, anchorXPt is relative to the left margin — add section.marginLeft to get page X.
470
+ * If false/absent, anchorXPt is already page-absolute.
471
+ */
472
+ anchorXFromMargin?: boolean;
473
+ /**
474
+ * If true, anchorYPt is relative to the paragraph's top Y in the renderer.
475
+ * If false/absent, anchorYPt is already page-absolute.
476
+ */
477
+ anchorYFromPara?: boolean;
478
+ /**
479
+ * When set, the renderer replaces all pixels of this hex color (e.g. "FFFFFF") with full
480
+ * transparency. Implements a:clrChange (make-background-transparent).
481
+ */
482
+ colorReplaceFrom?: string;
483
+ /**
484
+ * Wrap mode for anchor images:
485
+ * "square" | "topAndBottom" | "none" | "tight" | "through"
486
+ * Inline images and undetermined cases leave this undefined.
487
+ * MVP renders "tight" and "through" as "square".
488
+ */
489
+ wrapMode?: string;
490
+ /** Padding top (pt). Anchor-only. */
491
+ distTop?: number;
492
+ /** Padding bottom (pt). Anchor-only. */
493
+ distBottom?: number;
494
+ /** Padding left (pt). Anchor-only. */
495
+ distLeft?: number;
496
+ /** Padding right (pt). Anchor-only. */
497
+ distRight?: number;
498
+ /** wrapText attribute: "bothSides" | "left" | "right" | "largest". */
499
+ wrapSide?: string;
500
+ }
501
+
502
+ declare interface LineBreak {
503
+ type: 'break';
504
+ }
505
+
506
+ declare interface LineSpacing {
507
+ value: number;
508
+ rule: 'auto' | 'exact' | 'atLeast';
509
+ }
510
+
511
+ declare interface MergeCell {
512
+ top: number;
513
+ left: number;
514
+ bottom: number;
515
+ right: number;
516
+ }
517
+
518
+ declare interface NoFill {
519
+ fillType: 'none';
520
+ }
521
+
522
+ declare interface NumberingInfo {
523
+ numId: number;
524
+ level: number;
525
+ format: string;
526
+ text: string;
527
+ indentLeft: number;
528
+ tab: number;
529
+ }
530
+
531
+ declare interface NumFmt {
532
+ numFmtId: number;
533
+ formatCode: string;
534
+ }
535
+
536
+ declare interface ParaBorderEdge {
537
+ style: string;
538
+ color: string | null;
539
+ /** pt (sz / 8) */
540
+ width: number;
541
+ /** pt spacing between border and text */
542
+ space: number;
543
+ }
544
+
545
+ declare interface Paragraph {
546
+ /** Alignment: "l" | "ctr" | "r" | "just" */
547
+ alignment: string;
548
+ /** Left margin in EMU */
549
+ marL: number;
550
+ /** Right margin in EMU */
551
+ marR: number;
552
+ /** First-line indent in EMU (negative = hanging indent) */
553
+ indent: number;
554
+ spaceBefore: number | null;
555
+ spaceAfter: number | null;
556
+ spaceLine: SpaceLine | null;
557
+ /** List nesting level (0–8) */
558
+ lvl: number;
559
+ bullet: Bullet;
560
+ defFontSize: number | null;
561
+ defColor: string | null;
562
+ defBold: boolean | null;
563
+ defItalic: boolean | null;
564
+ defFontFamily: string | null;
565
+ /** Tab stops from pPr > tabLst */
566
+ tabStops: TabStop[];
567
+ runs: TextRun[];
568
+ }
569
+
570
+ declare interface ParagraphBorders {
571
+ top: ParaBorderEdge | null;
572
+ bottom: ParaBorderEdge | null;
573
+ left: ParaBorderEdge | null;
574
+ right: ParaBorderEdge | null;
575
+ between: ParaBorderEdge | null;
576
+ }
577
+
578
+ declare interface ParsedWorkbook {
579
+ workbook: Workbook;
580
+ styles: Styles;
581
+ sharedStrings: SharedString[];
582
+ }
583
+
584
+ declare type PathCmd = {
585
+ cmd: 'moveTo';
586
+ x: number;
587
+ y: number;
588
+ } | {
589
+ cmd: 'lineTo';
590
+ x: number;
591
+ y: number;
592
+ } | {
593
+ cmd: 'cubicBezTo';
594
+ x1: number;
595
+ y1: number;
596
+ x2: number;
597
+ y2: number;
598
+ x: number;
599
+ y: number;
600
+ } | {
601
+ cmd: 'arcTo';
602
+ wr: number;
603
+ hr: number;
604
+ stAng: number;
605
+ swAng: number;
606
+ } | {
607
+ cmd: 'close';
608
+ };
609
+
610
+ declare interface PictureElement {
611
+ type: 'picture';
612
+ x: number;
613
+ y: number;
614
+ width: number;
615
+ height: number;
616
+ rotation: number;
617
+ flipH: boolean;
618
+ flipV: boolean;
619
+ /** Data URL, e.g. "data:image/png;base64,..." */
620
+ dataUrl: string;
621
+ /** OOXML adj value (0–100000) for roundRect clip, null = plain rectangle */
622
+ clipAdjust: number | null;
623
+ /**
624
+ * ECMA-376 a:srcRect — source image crop as fractions (0..1) of the source
625
+ * width/height. Omitted when the image is not cropped.
626
+ */
627
+ srcRect?: {
628
+ l?: number;
629
+ t?: number;
630
+ r?: number;
631
+ b?: number;
632
+ };
633
+ }
634
+
635
+ export declare namespace pptx {
636
+ export {
637
+ PptxViewer,
638
+ PptxViewerOptions,
639
+ PptxPresentation,
640
+ RenderSlideOptions,
641
+ renderSlide,
642
+ RenderOptions,
643
+ Presentation,
644
+ Slide,
645
+ SlideElement,
646
+ ShapeElement,
647
+ PictureElement,
648
+ Fill,
649
+ SolidFill,
650
+ NoFill,
651
+ Stroke,
652
+ TextBody,
653
+ Paragraph,
654
+ TextRun,
655
+ TextRunData,
656
+ LineBreak
657
+ }
658
+ }
659
+
660
+ /**
661
+ * Headless PPTX rendering engine.
662
+ *
663
+ * Parses `.pptx` archives in a background worker (WASM) but renders slides
664
+ * synchronously on the main thread, so the canvas shares the document's
665
+ * `FontFaceSet` — avoiding subtle wrap differences between system fallback
666
+ * fonts and theme-declared webfonts (e.g. Nunito Sans).
667
+ *
668
+ * Construct via the static `load` factory. A single instance can drive any
669
+ * number of canvases (scroll view, thumbnail grid, master-detail, etc.).
670
+ *
671
+ * @example
672
+ * const pres = await PptxPresentation.load(buffer);
673
+ * await pres.renderSlide(canvas, 0, { width: 960 });
674
+ */
675
+ declare class PptxPresentation {
676
+ private readonly _worker;
677
+ private _presentation;
678
+ private _pendingParseCallbacks;
679
+ private _nextId;
680
+ private _workerReady;
681
+ private _workerReadyCallbacks;
682
+ private constructor();
683
+ /** Parse a PPTX from URL or ArrayBuffer. */
684
+ static load(source: string | ArrayBuffer): Promise<PptxPresentation>;
685
+ private _waitForWorker;
686
+ private _parse;
687
+ /** Total number of slides in the loaded presentation. */
688
+ get slideCount(): number;
689
+ /** Slide width in EMU. */
690
+ get slideWidth(): number;
691
+ /** Slide height in EMU. */
692
+ get slideHeight(): number;
693
+ /** Render a slide onto the given canvas. */
694
+ renderSlide(canvas: HTMLCanvasElement, slideIndex: number, opts?: RenderSlideOptions): Promise<void>;
695
+ /** Terminate the worker and release all resources. */
696
+ destroy(): void;
697
+ }
698
+
699
+ /**
700
+ * Opinionated single-canvas PPTX viewer.
701
+ *
702
+ * Creates a <canvas> element, appends it to the provided container, and manages
703
+ * slide navigation.
704
+ *
705
+ * For custom layouts (multi-canvas, thumbnails, scroll view) use PptxPresentation directly.
706
+ */
707
+ declare class PptxViewer {
708
+ private readonly canvas;
709
+ private engine;
710
+ private readonly opts;
711
+ private currentSlide;
712
+ constructor(container: HTMLElement, opts?: PptxViewerOptions);
713
+ /** Load a PPTX from URL or ArrayBuffer and render the first slide. */
714
+ load(source: string | ArrayBuffer): Promise<void>;
715
+ /** Navigate to a specific slide (0-indexed). */
716
+ goToSlide(index: number): Promise<void>;
717
+ nextSlide(): Promise<void>;
718
+ prevSlide(): Promise<void>;
719
+ get slideIndex(): number;
720
+ get slideCount(): number;
721
+ /** The underlying <canvas> element. */
722
+ get canvasElement(): HTMLCanvasElement;
723
+ private renderCurrentSlide;
724
+ /** Clean up the viewer and terminate the background worker. */
725
+ destroy(): void;
726
+ }
727
+
728
+ declare interface PptxViewerOptions extends RenderOptions {
729
+ /** Called when a slide finishes rendering */
730
+ onSlideChange?: (index: number, total: number) => void;
731
+ /** Called on parse or render errors */
732
+ onError?: (err: Error) => void;
733
+ }
734
+
735
+ declare interface Presentation {
736
+ slideWidth: number;
737
+ slideHeight: number;
738
+ slides: Slide[];
739
+ /** Theme dk1 color (e.g. "383838"). Used as fallback text color when no explicit color is set. */
740
+ defaultTextColor: string | null;
741
+ /** Theme major (heading) font family name (e.g. "Aptos Display", "Nunito Sans"). Null if not set. */
742
+ majorFont: string | null;
743
+ /** Theme minor (body) font family name (e.g. "Aptos", "Nunito Sans"). Null if not set. */
744
+ minorFont: string | null;
745
+ }
746
+
747
+ declare interface RenderOptions {
748
+ width?: number;
749
+ defaultTextColor?: string | null;
750
+ dpr?: number;
751
+ majorFont?: string | null;
752
+ minorFont?: string | null;
753
+ }
754
+
755
+ declare interface RenderPageOptions {
756
+ /** Canvas CSS width in px; height is auto-computed from page aspect ratio */
757
+ width?: number;
758
+ dpr?: number;
759
+ defaultTextColor?: string;
760
+ }
761
+
762
+ /**
763
+ * Render a single slide onto a <canvas> element.
764
+ * Returns the canvas for convenience.
765
+ */
766
+ declare function renderSlide(canvas: HTMLCanvasElement | OffscreenCanvas, slide: Slide, slideWidth: number, slideHeight: number, opts?: RenderOptions): Promise<HTMLCanvasElement | OffscreenCanvas>;
767
+
768
+ /** Options for rendering a single slide onto a canvas. */
769
+ declare interface RenderSlideOptions {
770
+ /** Display width in CSS pixels. Defaults to canvas.offsetWidth or 960. */
771
+ width?: number;
772
+ /** Device pixel ratio. Defaults to window.devicePixelRatio or 1. */
773
+ dpr?: number;
774
+ }
775
+
776
+ declare interface RenderViewportOptions {
777
+ width?: number;
778
+ height?: number;
779
+ dpr?: number;
780
+ defaultFontFamily?: string;
781
+ defaultFontSize?: number;
782
+ scrollOffsetX?: number;
783
+ scrollOffsetY?: number;
784
+ freezeRows?: number;
785
+ freezeCols?: number;
786
+ /** Scale factor applied to all cell/header dimensions (default 1). */
787
+ cellScale?: number;
788
+ /** Pre-loaded Image elements keyed by their dataUrl (for ImageAnchor rendering). */
789
+ loadedImages?: Map<string, HTMLImageElement>;
790
+ }
791
+
792
+ declare interface Row {
793
+ index: number;
794
+ height: number | null;
795
+ cells: Cell[];
796
+ }
797
+
798
+ declare interface Run {
799
+ text: string;
800
+ font?: RunFont;
801
+ }
802
+
803
+ declare interface RunFont {
804
+ bold: boolean;
805
+ italic: boolean;
806
+ underline: boolean;
807
+ strike: boolean;
808
+ size?: number;
809
+ color?: string | null;
810
+ name?: string | null;
811
+ }
812
+
813
+ declare interface SectionProps {
814
+ pageWidth: number;
815
+ pageHeight: number;
816
+ marginTop: number;
817
+ marginRight: number;
818
+ marginBottom: number;
819
+ marginLeft: number;
820
+ headerDistance: number;
821
+ footerDistance: number;
822
+ titlePage: boolean;
823
+ evenAndOddHeaders: boolean;
824
+ }
825
+
826
+ declare interface Shadow {
827
+ color: string;
828
+ alpha: number;
829
+ blur: number;
830
+ dist: number;
831
+ /** degrees clockwise from East */
832
+ dir: number;
833
+ }
834
+
835
+ declare interface ShapeElement {
836
+ type: 'shape';
837
+ x: number;
838
+ y: number;
839
+ width: number;
840
+ height: number;
841
+ /** Rotation in degrees, clockwise */
842
+ rotation: number;
843
+ /** Horizontal mirror (a:xfrm flipH) */
844
+ flipH: boolean;
845
+ /** Vertical mirror (a:xfrm flipV) */
846
+ flipV: boolean;
847
+ /** OOXML preset name or "custGeom" when custom paths are used */
848
+ geometry: string;
849
+ fill: Fill | null;
850
+ stroke: Stroke | null;
851
+ textBody: TextBody | null;
852
+ /** Default text color from p:style > fontRef (hex). Used when run/para has no explicit color. */
853
+ defaultTextColor: string | null;
854
+ /** Custom geometry sub-paths (set only when geometry === "custGeom").
855
+ * Outer array: one entry per <a:path>; inner: path commands with coords in [0,1]. */
856
+ custGeom: PathCmd[][] | null;
857
+ /** First adjustment value from prstGeom avLst (e.g. trapezoid inset). Range 0–100000. */
858
+ adj: number | null;
859
+ /** Second adjustment value from prstGeom avLst (e.g. arrow head width). Range 0–100000. */
860
+ adj2: number | null;
861
+ /** Third adjustment value from prstGeom avLst (e.g. callout tip x). Range 0–100000. */
862
+ adj3: number | null;
863
+ /** Fourth adjustment value from prstGeom avLst (e.g. callout tip y). Range 0–100000. */
864
+ adj4: number | null;
865
+ /** Drop shadow from effectLst > outerShdw (null if not present). */
866
+ shadow: Shadow | null;
867
+ }
868
+
869
+ declare interface SharedString {
870
+ text: string;
871
+ runs?: Run[];
872
+ }
873
+
874
+ declare interface SheetMeta {
875
+ name: string;
876
+ sheetId: number;
877
+ rId: string;
878
+ }
879
+
880
+ declare interface Slide {
881
+ index: number;
882
+ /** 1-based slide number (index + 1); used to render slidenum fields */
883
+ slideNumber: number;
884
+ background: Fill | null;
885
+ elements: SlideElement[];
886
+ }
887
+
888
+ declare type SlideElement = ShapeElement | PictureElement | TableElement | ChartElement;
889
+
890
+ declare interface SolidFill {
891
+ fillType: 'solid';
892
+ color: string;
893
+ }
894
+
895
+ declare type SpaceLine = {
896
+ type: 'pct';
897
+ val: number;
898
+ } | {
899
+ type: 'pts';
900
+ val: number;
901
+ };
902
+
903
+ declare interface Stroke {
904
+ color: string;
905
+ /** Width in EMU */
906
+ width: number;
907
+ /** OOXML prstDash value: "dash", "dot", "dashDot", "lgDash", "lgDashDot", etc. */
908
+ dashStyle?: string;
909
+ /** Arrow head at the start of the line */
910
+ headEnd?: ArrowEnd;
911
+ /** Arrow head at the end of the line */
912
+ tailEnd?: ArrowEnd;
913
+ }
914
+
915
+ declare interface Styles {
916
+ fonts: Font[];
917
+ fills: Fill_2[];
918
+ borders: Border[];
919
+ cellXfs: CellXf[];
920
+ numFmts: NumFmt[];
921
+ dxfs: Dxf[];
922
+ }
923
+
924
+ declare interface TableBorders {
925
+ top: BorderSpec | null;
926
+ bottom: BorderSpec | null;
927
+ left: BorderSpec | null;
928
+ right: BorderSpec | null;
929
+ insideH: BorderSpec | null;
930
+ insideV: BorderSpec | null;
931
+ }
932
+
933
+ declare interface TableCell {
934
+ textBody: TextBody | null;
935
+ fill: Fill | null;
936
+ borderL: Stroke | null;
937
+ borderR: Stroke | null;
938
+ borderT: Stroke | null;
939
+ borderB: Stroke | null;
940
+ /** Diagonal from top-left to bottom-right */
941
+ diagonalTL?: Stroke | null;
942
+ /** Diagonal from top-right to bottom-left */
943
+ diagonalTR?: Stroke | null;
944
+ /** Column span */
945
+ gridSpan: number;
946
+ /** Row span */
947
+ rowSpan: number;
948
+ /** Horizontal merge continuation */
949
+ hMerge: boolean;
950
+ /** Vertical merge continuation */
951
+ vMerge: boolean;
952
+ }
953
+
954
+ declare interface TableElement {
955
+ type: 'table';
956
+ x: number;
957
+ y: number;
958
+ width: number;
959
+ height: number;
960
+ /** Column widths in EMU */
961
+ cols: number[];
962
+ rows: TableRow[];
963
+ }
964
+
965
+ declare interface TableRow {
966
+ /** Row height in EMU */
967
+ height: number;
968
+ cells: TableCell[];
969
+ }
970
+
971
+ declare interface TabStop {
972
+ /** Position in EMU from the left edge of the text area (after lIns) */
973
+ pos: number;
974
+ /** Alignment: "l" | "r" | "ctr" | "dec" */
975
+ algn: string;
976
+ }
977
+
978
+ declare interface TabStop_2 {
979
+ /** tab stop position in pt (from the left of paragraph content area) */
980
+ pos: number;
981
+ alignment: 'left' | 'center' | 'right' | 'decimal' | 'bar' | 'clear';
982
+ leader: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
983
+ }
984
+
985
+ declare interface TextBody {
986
+ /** Vertical anchor: "t" | "ctr" | "b" */
987
+ verticalAnchor: string;
988
+ paragraphs: Paragraph[];
989
+ /** Default pt size from lstStyle (overrides renderer default when present) */
990
+ defaultFontSize: number | null;
991
+ /** Inherited bold from layout/master defRPr (null = not set, use false as final default) */
992
+ defaultBold: boolean | null;
993
+ /** Inherited italic from layout/master defRPr (null = not set, use false as final default) */
994
+ defaultItalic: boolean | null;
995
+ /** Text insets in EMU (defaults: lIns=rIns=91440, tIns=bIns=45720) */
996
+ lIns: number;
997
+ rIns: number;
998
+ tIns: number;
999
+ bIns: number;
1000
+ /** "square" = wrap, "none" = no wrap */
1001
+ wrap: string;
1002
+ /** Text direction: "horz" | "vert" | "vert270" | "eaVert" etc. */
1003
+ vert: string;
1004
+ /** Auto-fit: "sp" = shape grows to fit text, "norm" = font shrinks, "none" = no fit */
1005
+ autoFit: string;
1006
+ }
1007
+
1008
+ declare type TextRun = TextRunData | LineBreak;
1009
+
1010
+ declare interface TextRun_2 {
1011
+ text: string;
1012
+ bold: boolean;
1013
+ italic: boolean;
1014
+ underline: boolean;
1015
+ strikethrough: boolean;
1016
+ fontSize: number;
1017
+ color: string | null;
1018
+ fontFamily: string | null;
1019
+ isLink: boolean;
1020
+ background: string | null;
1021
+ vertAlign: 'super' | 'sub' | null;
1022
+ /** Target URL for hyperlinks (resolved from relationships.xml) */
1023
+ hyperlink: string | null;
1024
+ allCaps?: boolean;
1025
+ smallCaps?: boolean;
1026
+ doubleStrikethrough?: boolean;
1027
+ highlight?: string | null;
1028
+ }
1029
+
1030
+ declare interface TextRunData {
1031
+ type: 'text';
1032
+ text: string;
1033
+ /** null = not set, inherit from paragraph/body defaults */
1034
+ bold: boolean | null;
1035
+ /** null = not set, inherit from paragraph/body defaults */
1036
+ italic: boolean | null;
1037
+ underline: boolean;
1038
+ /** true when rPr strike = "sngStrike" or "dblStrike" */
1039
+ strikethrough: boolean;
1040
+ /** Font size in points */
1041
+ fontSize: number | null;
1042
+ color: string | null;
1043
+ fontFamily: string | null;
1044
+ /** Baseline shift in thousandths of a point. Positive = superscript, negative = subscript. */
1045
+ baseline?: number;
1046
+ /** Set for OOXML field runs (e.g. "slidenum"). When set, renderer replaces text with field value. */
1047
+ fieldType?: string;
1048
+ }
1049
+
1050
+ declare interface ViewportRange {
1051
+ row: number;
1052
+ col: number;
1053
+ rows: number;
1054
+ cols: number;
1055
+ }
1056
+
1057
+ declare interface Workbook {
1058
+ sheets: SheetMeta[];
1059
+ }
1060
+
1061
+ declare interface Worksheet {
1062
+ name: string;
1063
+ rows: Row[];
1064
+ colWidths: Record<number, number>;
1065
+ rowHeights: Record<number, number>;
1066
+ defaultColWidth: number;
1067
+ defaultRowHeight: number;
1068
+ mergeCells: MergeCell[];
1069
+ freezeRows: number;
1070
+ freezeCols: number;
1071
+ conditionalFormats: ConditionalFormat[];
1072
+ images: ImageAnchor[];
1073
+ charts: ChartAnchor[];
1074
+ /** Whether to display zero values (ECMA-376 §18.3.1.94). Defaults to true. */
1075
+ showZeros?: boolean;
1076
+ /** Sheet tab color (ECMA-376 §18.3.1.79). */
1077
+ tabColor?: string | null;
1078
+ /** AutoFilter header range (ECMA-376 §18.3.1.2). */
1079
+ autoFilter?: CellRange | null;
1080
+ /** Hyperlinks in this worksheet (ECMA-376 §18.3.1.47). */
1081
+ hyperlinks?: Hyperlink[];
1082
+ }
1083
+
1084
+ export declare namespace xlsx {
1085
+ export {
1086
+ XlsxWorkbook,
1087
+ XlsxViewer,
1088
+ XlsxViewerOptions,
1089
+ Workbook,
1090
+ SheetMeta,
1091
+ Worksheet,
1092
+ Row,
1093
+ Cell,
1094
+ CellValue,
1095
+ Styles,
1096
+ Font,
1097
+ Fill_2 as Fill,
1098
+ Border,
1099
+ BorderEdge,
1100
+ CellXf,
1101
+ NumFmt,
1102
+ MergeCell,
1103
+ ParsedWorkbook,
1104
+ ViewportRange,
1105
+ RenderViewportOptions
1106
+ }
1107
+ }
1108
+
1109
+ /**
1110
+ * XLSX parser's raw chart series (includes XLSX-only `seriesType` for mixed
1111
+ * charts). Adapted to `ChartSeries` from @silurus/ooxml-core before rendering.
1112
+ */
1113
+ declare interface XlsxChartSeries {
1114
+ name: string;
1115
+ /** Chart sub-type for this series (allows mixed charts). */
1116
+ seriesType: string;
1117
+ categories: string[];
1118
+ values: (number | null)[];
1119
+ /** Explicit fill color hex (from c:spPr). Undefined = use palette. */
1120
+ color?: string | null;
1121
+ }
1122
+
1123
+ declare class XlsxViewer {
1124
+ private wb;
1125
+ private canvas;
1126
+ private canvasArea;
1127
+ private scrollHost;
1128
+ private spacer;
1129
+ private tabBar;
1130
+ private tabs;
1131
+ private currentSheet;
1132
+ private currentWorksheet;
1133
+ private opts;
1134
+ private resizeObserver;
1135
+ constructor(container: HTMLElement, opts?: XlsxViewerOptions);
1136
+ load(source: string | ArrayBuffer): Promise<void>;
1137
+ showSheet(index: number): Promise<void>;
1138
+ private buildTabs;
1139
+ private updateTabActive;
1140
+ private tabStyle;
1141
+ private updateSpacerSize;
1142
+ private renderCurrentSheet;
1143
+ get sheetNames(): string[];
1144
+ destroy(): void;
1145
+ }
1146
+
1147
+ declare interface XlsxViewerOptions {
1148
+ /** Scale factor for cell/header dimensions (default 1). 0.5 = half size. */
1149
+ cellScale?: number;
1150
+ onReady?: (sheetNames: string[]) => void;
1151
+ onSheetChange?: (index: number, name: string) => void;
1152
+ onError?: (err: Error) => void;
1153
+ }
1154
+
1155
+ declare class XlsxWorkbook {
1156
+ private worker;
1157
+ private parsedWorkbook;
1158
+ private sheetCache;
1159
+ /** Cache of loaded images keyed by their data URL. Shared across sheets. */
1160
+ private imageCache;
1161
+ private rawData;
1162
+ constructor();
1163
+ load(source: string | ArrayBuffer): Promise<void>;
1164
+ get sheetNames(): string[];
1165
+ get sheetCount(): number;
1166
+ getWorksheet(sheetIndex: number): Promise<Worksheet>;
1167
+ renderViewport(target: HTMLCanvasElement | OffscreenCanvas, sheetIndex: number, viewport: ViewportRange, opts?: RenderViewportOptions): Promise<void>;
1168
+ destroy(): void;
1169
+ private sendMessage;
1170
+ }
1171
+
1172
+ export { }