Skip to main content

Slide

Struct Slide 

Source
pub struct Slide {
    pub shapes: Vec<Shape>,
    pub notes: Option<TextBody>,
    pub comments: Vec<SlideComment>,
    pub background: Option<Fill>,
    pub hidden: bool,
    pub name: Option<String>,
    pub hide_master_graphics: bool,
}
Expand description

A single slide: an ordered list of shapes (<p:spTree>’s children), plus optional speaker notes.

Fields§

§shapes: Vec<Shape>§notes: Option<TextBody>

This slide’s speaker notes (ppt/notesSlides/notesSlideN.xml’s own “body” placeholder text), if any. None (the default) means no notes part is written for this slide at all — real PowerPoint packages commonly have no notes for most slides, so this stays a genuinely optional, per-slide part rather than always-present boilerplate (mirrors word-ooxml’s header/footer, styles.xml, etc. — every optional part in this workspace follows the same “only written when actually set” convention). See Presentation’s writer for the fixed notes-master/notes-slide boilerplate this produces around the text itself.

§comments: Vec<SlideComment>

This slide’s comments (ppt/comments/commentN.xml), if any — a genuinely optional part, only written when non-empty, same “only written when actually set” convention as notes. See SlideComment’s own doc comment for the caveat that this feature isn’t grounded on a real fixture.

§background: Option<Fill>

<p:cSld>/<p:bg>/<p:bgPr> — this slide’s own background fill, overriding whatever the slide layout/master would otherwise show through. None (the default) omits <p:bg> entirely — the slide simply inherits its background from the layout/master chain, same “no override” default every other optional field in this crate uses. Only the direct fill choice (<p:bgPr>, EG_FillProperties) is modeled — <p:bgRef> (a reference into the theme’s own background style list) is not. Grounded against a real fixture (ppt/slides/slide2.xml), which confirmed <p:bg> as <p:cSld>’s very first child, directly wrapping <p:bgPr> before any fill.

§hidden: bool

<p:sld show="0"> (CT_Slide’s own show attribute) — hides this slide from the normal slide-show sequence (it’s still present in the deck, just skipped when presenting; PowerPoint’s own “Hide Slide” toggle). false (the default) omits the attribute, matching the schema’s own default of a shown slide. Grounded against a real fixture.

§name: Option<String>

<p:sld name="."> — an optional display name for this slide (distinct from its title placeholder’s own text), shown e.g. in PowerPoint’s Slide Navigator/Outline view. None omits the attribute entirely. Not grounded on a fixture — no corpus .pptx file examined actually sets it — modeled directly from CT_Slide’s schema anyway, the same posture already used for e.g. crate::model::SlideComment/crate::model::Connector.

§hide_master_graphics: bool

<p:sld showMasterSp="0"> (CT_Slide’s own showMasterSp attribute, inverted here) — hides this slide’s inherited slide- master placeholder graphics/decorations (e.g. a logo or footer bar drawn directly on the master, not through a placeholder this slide overrides). The schema’s own default is showMasterSp="1" (shown) when the attribute is omitted — this field is named/stored inverted (false = shown, matching every other boolean “override” field in this crate, e.g. hidden) so that Slide::new’s all-false default already matches real PowerPoint’s own default behavior, and the attribute is only ever written (as "0") when explicitly hidden. Grounded against real fixtures.

Implementations§

Source§

impl Slide

Source

pub fn new() -> Slide

Creates an empty slide (no shapes, no notes, no comments, no background override, shown, unnamed, showing inherited master graphics).

Examples found in repository?
examples/hello_world_pptx.rs (line 32)
14fn main() -> office_toolkit::Result<()> {
15    let path = output_path("hello_world.pptx");
16
17    let text_box = AutoShape::new(2, "Hello box")
18        .with_properties(
19            ShapeProperties::new().with_transform(
20                Transform2D::new()
21                    .with_offset(838_200, 1_365_250)
22                    .with_extent(7_772_400, 1_200_150),
23            ),
24        )
25        .with_text_body(
26            TextBody::new()
27                .with_paragraph(TextParagraph::new().with_run(TextRun::text("Hello, world!"))),
28        );
29
30    // `Presentation` and `Slide` both come from `office_toolkit::prelude`.
31    let presentation =
32        Presentation::new().with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)));
33    presentation.save_to_file(&path)?;
34    println!("Wrote {}", path.display());
35
36    // Read the file back to confirm it is a valid .pptx.
37    let reopened = Presentation::open_file(&path)?;
38    println!("Slide count: {}", reopened.slides.len());
39
40    Ok(())
41}
More examples
Hide additional examples
examples/pptx_notes_and_comments.rs (line 29)
12fn main() -> office_toolkit::Result<()> {
13    let path = output_path("pptx_notes_and_comments.pptx");
14
15    let title = |text: &str| {
16        AutoShape::new(2, "Title")
17            .with_properties(
18                ShapeProperties::new().with_transform(
19                    Transform2D::new()
20                        .with_offset(838_200, 838_200)
21                        .with_extent(8_000_000, 1_000_000),
22                ),
23            )
24            .with_text_body(
25                TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26            )
27    };
28
29    let notes_slide = Slide::new()
30        .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31        .with_notes(
32            TextBody::new().with_paragraph(
33                TextParagraph::new()
34                    .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35            ),
36        );
37
38    let commented_slide = Slide::new()
39        .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40        .with_comment(
41            SlideComment::new(
42                "Reviewer",
43                "RV",
44                "2026-07-21T10:00:00",
45                "This claim needs a source.",
46            )
47            .with_position(1_000_000, 2_000_000),
48        )
49        .with_comment(
50            SlideComment::new(
51                "Editor",
52                "ED",
53                "2026-07-21T11:30:00",
54                "Looks good otherwise.",
55            )
56            .with_position(3_000_000, 2_000_000),
57        );
58
59    let presentation = Presentation::new()
60        .with_slide(notes_slide)
61        .with_slide(commented_slide);
62
63    presentation.save_to_file(&path)?;
64    println!("Wrote {}", path.display());
65    Ok(())
66}
examples/pptx_media.rs (line 70)
20fn main() -> office_toolkit::Result<()> {
21    let path = output_path("pptx_media.pptx");
22    let image_bytes = std::fs::read(image_fixture_path())?;
23
24    let embedded_picture = Picture::new(
25        2,
26        "Embedded picture",
27        image_bytes.clone(),
28        PictureFormat::Png,
29        3_000_000,
30        2_000_000,
31    )
32    .with_offset(838_200, 838_200)
33    .with_description("Project test image");
34
35    let linked_picture = Picture::new(
36        2,
37        "Externally linked picture",
38        image_bytes,
39        PictureFormat::Png,
40        3_000_000,
41        2_000_000,
42    )
43    .with_offset(838_200, 838_200)
44    .with_external_link("https://example.com/original-image.png");
45
46    // Placeholder bytes — a real .pptx would carry a genuine video file
47    // here. This example only demonstrates the model/writer plumbing.
48    let poster_image = vec![0x89, 0x50, 0x4E, 0x47]; // fake, just enough bytes to have *some* data
49    let media = SlideMedia::new(
50        2,
51        "Video clip",
52        vec![0u8; 16],
53        MediaFormat::Mp4,
54        4_000_000,
55        2_250_000,
56    )
57    .with_offset(838_200, 838_200)
58    .with_poster_image(poster_image, PictureFormat::Png);
59
60    let chart = SlideChart::new(
61        2,
62        "Quarterly revenue",
63        sample_chart_space(),
64        6_000_000,
65        3_500_000,
66    )
67    .with_offset(838_200, 838_200);
68
69    let presentation = Presentation::new()
70        .with_slide(Slide::new().with_shape(Shape::Picture(embedded_picture)))
71        .with_slide(Slide::new().with_shape(Shape::Picture(linked_picture)))
72        .with_slide(Slide::new().with_shape(Shape::Media(media)))
73        .with_slide(Slide::new().with_shape(Shape::Chart(Box::new(chart))));
74
75    presentation.save_to_file(&path)?;
76    println!("Wrote {}", path.display());
77    Ok(())
78}
examples/pptx_tables.rs (line 92)
16fn main() -> office_toolkit::Result<()> {
17    let path = output_path("pptx_tables.pptx");
18
19    let plain_table = SlideTable::new(2, "Plain table", 5_000_000, 1_500_000)
20        .with_offset(838_200, 838_200)
21        .with_column_widths(vec![2_500_000, 2_500_000])
22        .with_row(
23            TableRow::new(500_000)
24                .with_cell(cell("Name"))
25                .with_cell(cell("Score")),
26        )
27        .with_row(
28            TableRow::new(500_000)
29                .with_cell(cell("Alice"))
30                .with_cell(cell("92")),
31        )
32        .with_row(
33            TableRow::new(500_000)
34                .with_cell(cell("Bob"))
35                .with_cell(cell("87")),
36        );
37
38    let merged_table = SlideTable::new(2, "Merged cells", 5_000_000, 1_000_000)
39        .with_offset(838_200, 838_200)
40        .with_column_widths(vec![1_667_000, 1_667_000, 1_666_000])
41        .with_row(
42            TableRow::new(500_000)
43                .with_cell(cell("Spanning header").with_horizontal_span(3))
44                .with_cell(TableCell::horizontally_merged())
45                .with_cell(TableCell::horizontally_merged()),
46        )
47        .with_row(
48            TableRow::new(500_000)
49                .with_cell(cell("A"))
50                .with_cell(cell("B"))
51                .with_cell(cell("C")),
52        );
53
54    let styled_table = SlideTable::new(2, "Styled table", 5_000_000, 1_500_000)
55        .with_offset(838_200, 838_200)
56        .with_style_id("{66BB4812-77A1-49B3-BDF9-0CCEB564D7B5}")
57        .with_style_first_row(true)
58        .with_style_band_rows(true)
59        .with_column_widths(vec![2_500_000, 2_500_000])
60        .with_row(
61            TableRow::new(500_000)
62                .with_cell(cell("Header A"))
63                .with_cell(cell("Header B")),
64        )
65        .with_row(
66            TableRow::new(500_000)
67                .with_cell(cell("1"))
68                .with_cell(cell("2")),
69        )
70        .with_row(
71            TableRow::new(500_000)
72                .with_cell(cell("3"))
73                .with_cell(cell("4")),
74        );
75
76    let presentation = Presentation::new()
77        .with_table_style(
78            SlideTableStyle::new(
79                "{66BB4812-77A1-49B3-BDF9-0CCEB564D7B5}",
80                "Custom Table Style",
81            )
82            .with_first_row(
83                TableStylePart::new()
84                    .with_fill(Fill::Solid(Color::Rgb("2E74B5".to_string())))
85                    .with_bold(true)
86                    .with_text_color(Color::Rgb("FFFFFF".to_string())),
87            )
88            .with_band1_horizontal(
89                TableStylePart::new().with_fill(Fill::Solid(Color::Rgb("F2F2F2".to_string()))),
90            ),
91        )
92        .with_slide(Slide::new().with_shape(Shape::Table(plain_table)))
93        .with_slide(Slide::new().with_shape(Shape::Table(merged_table)))
94        .with_slide(Slide::new().with_shape(Shape::Table(styled_table)));
95
96    presentation.save_to_file(&path)?;
97    println!("Wrote {}", path.display());
98    Ok(())
99}
examples/pptx_shapes_and_placeholders.rs (line 84)
14fn main() -> office_toolkit::Result<()> {
15    let path = output_path("pptx_shapes_and_placeholders.pptx");
16
17    let plain_shape = AutoShape::new(2, "Plain autoshape")
18        .with_properties(
19            ShapeProperties::new().with_transform(
20                Transform2D::new()
21                    .with_offset(838_200, 838_200)
22                    .with_extent(5_000_000, 1_000_000),
23            ),
24        )
25        .with_text_body(
26            TextBody::new()
27                .with_paragraph(TextParagraph::new().with_run(TextRun::text("A plain autoshape."))),
28        );
29
30    let text_box = AutoShape::new(2, "Text box")
31        .with_text_box(true)
32        .with_properties(
33            ShapeProperties::new().with_transform(
34                Transform2D::new()
35                    .with_offset(838_200, 838_200)
36                    .with_extent(5_000_000, 1_000_000),
37            ),
38        )
39        .with_text_body(TextBody::new().with_paragraph(
40            TextParagraph::new().with_run(TextRun::text("A genuine text box (txBox=\"1\").")),
41        ));
42
43    let title = AutoShape::new(2, "Title placeholder")
44        .with_placeholder(Placeholder::new(PlaceholderKind::CenterTitle))
45        .with_properties(
46            ShapeProperties::new().with_transform(
47                Transform2D::new()
48                    .with_offset(838_200, 838_200)
49                    .with_extent(10_515_600, 1_325_563),
50            ),
51        )
52        .with_text_body(
53            TextBody::new()
54                .with_paragraph(TextParagraph::new().with_run(TextRun::text("Title placeholder"))),
55        );
56    let subtitle =
57        AutoShape::new(3, "Subtitle placeholder")
58            .with_placeholder(Placeholder::new(PlaceholderKind::SubTitle).with_index(1))
59            .with_properties(
60                ShapeProperties::new().with_transform(
61                    Transform2D::new()
62                        .with_offset(838_200, 2_400_000)
63                        .with_extent(10_515_600, 800_000),
64                ),
65            )
66            .with_text_body(TextBody::new().with_paragraph(
67                TextParagraph::new().with_run(TextRun::text("Subtitle placeholder")),
68            ));
69
70    let hyperlinked_shape = AutoShape::new(2, "Hyperlinked shape")
71        .with_hyperlink("https://www.rust-lang.org")
72        .with_properties(
73            ShapeProperties::new().with_transform(
74                Transform2D::new()
75                    .with_offset(838_200, 838_200)
76                    .with_extent(5_000_000, 1_000_000),
77            ),
78        )
79        .with_text_body(TextBody::new().with_paragraph(
80            TextParagraph::new().with_run(TextRun::text("Click this shape to open a link.")),
81        ));
82
83    let presentation = Presentation::new()
84        .with_slide(Slide::new().with_shape(Shape::AutoShape(plain_shape)))
85        .with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)))
86        .with_slide(
87            Slide::new()
88                .with_shape(Shape::AutoShape(title))
89                .with_shape(Shape::AutoShape(subtitle)),
90        )
91        .with_slide(Slide::new().with_shape(Shape::AutoShape(hyperlinked_shape)));
92
93    presentation.save_to_file(&path)?;
94    println!("Wrote {}", path.display());
95    Ok(())
96}
examples/pptx_theme_and_metadata.rs (line 82)
19fn main() -> office_toolkit::Result<()> {
20    // A custom theme and an embedded font. `Theme`/`ColorScheme`/
21    // `FontScheme` have no `with_*` builders in this crate — only
22    // `office_default()` or plain struct literals.
23    let custom_theme = Theme {
24        name: "Custom Brand".to_string(),
25        colors: ColorScheme {
26            dark1: "1B1B1B".to_string(),
27            light1: "FFFFFF".to_string(),
28            dark2: "0A2540".to_string(),
29            light2: "F5F5F5".to_string(),
30            accent1: "0A2540".to_string(),
31            accent2: "E8622C".to_string(),
32            accent3: "2E86AB".to_string(),
33            accent4: "6FB98F".to_string(),
34            accent5: "F4A259".to_string(),
35            accent6: "8E4585".to_string(),
36            hyperlink: "1155CC".to_string(),
37            followed_hyperlink: "6B3FA0".to_string(),
38        },
39        fonts: FontScheme {
40            major_latin: "Georgia".to_string(),
41            minor_latin: "Verdana".to_string(),
42        },
43    };
44
45    // Placeholder bytes — a real .pptx would carry genuine TrueType/
46    // OpenType font data here.
47    let embedded_font = EmbeddedFont::new("Custom Sans")
48        .with_regular(vec![0u8; 16])
49        .with_bold(vec![0u8; 16]);
50
51    // A slide with no shapes at all renders as a blank page — nothing shows
52    // the custom theme actually took effect. `drawing::Color` has no
53    // scheme-relative variant yet (`<a:schemeClr>` isn't modeled, see that
54    // enum's own doc comment), so this can't reference the theme's accent1
55    // symbolically; it uses the same literal hex values the theme itself
56    // was built from, purely so the slide visibly matches the palette above.
57    let title_shape = AutoShape::new(2, "Title")
58        .with_properties(
59            ShapeProperties::new()
60                .with_transform(
61                    Transform2D::new()
62                        .with_offset(838_200, 838_200)
63                        .with_extent(6_000_000, 1_500_000),
64                )
65                .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.accent1.clone()))),
66        )
67        .with_text_body(
68            TextBody::new().with_paragraph(
69                TextParagraph::new().with_run(TextRun::text_with_properties(
70                    "Custom Brand theme — Georgia / Verdana, accent1 = #0A2540",
71                    TextRunProperties::new()
72                        .with_font_family(custom_theme.fonts.major_latin.clone())
73                        .with_font_size_points(24.0)
74                        .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.light1.clone()))),
75                )),
76            ),
77        );
78
79    let themed_presentation = Presentation::new()
80        .with_theme(custom_theme)
81        .with_embedded_font(embedded_font)
82        .with_slide(Slide::new().with_shape(Shape::AutoShape(title_shape)));
83    let theme_path = output_path("pptx_theme.pptx");
84    themed_presentation.save_to_file(&theme_path)?;
85    println!("Wrote {}", theme_path.display());
86
87    // Document metadata (docProps/core.xml, app.xml, and custom.xml).
88    let properties = DocumentProperties::new()
89        .with_title("Metadata example")
90        .with_author("Example Author")
91        .with_subject("Presentation-level features")
92        .with_custom_property(
93            "ProjectCode",
94            CustomPropertyValue::Text("PPTX-META".to_string()),
95        );
96    // Same reasoning as `title_shape` above: an empty slide would render
97    // blank, so a text shape spells out where the metadata actually lives.
98    let metadata_shape = AutoShape::new(2, "Note")
99        .with_properties(ShapeProperties::new().with_transform(Transform2D::new().with_offset(838_200, 838_200).with_extent(7_000_000, 1_000_000)))
100        .with_text_body(TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(
101            "This presentation's metadata is in File > Info (title, author, subject, and a custom \"ProjectCode\" property) — not on this slide.",
102        ))));
103    let metadata_presentation = Presentation::new()
104        .with_properties(properties)
105        .with_slide(Slide::new().with_shape(Shape::AutoShape(metadata_shape)));
106    let metadata_path = output_path("pptx_metadata.pptx");
107    metadata_presentation.save_to_file(&metadata_path)?;
108    println!("Wrote {}", metadata_path.display());
109
110    Ok(())
111}
Source

pub fn with_shape(self, shape: Shape) -> Slide

Appends a shape.

Examples found in repository?
examples/hello_world_pptx.rs (line 32)
14fn main() -> office_toolkit::Result<()> {
15    let path = output_path("hello_world.pptx");
16
17    let text_box = AutoShape::new(2, "Hello box")
18        .with_properties(
19            ShapeProperties::new().with_transform(
20                Transform2D::new()
21                    .with_offset(838_200, 1_365_250)
22                    .with_extent(7_772_400, 1_200_150),
23            ),
24        )
25        .with_text_body(
26            TextBody::new()
27                .with_paragraph(TextParagraph::new().with_run(TextRun::text("Hello, world!"))),
28        );
29
30    // `Presentation` and `Slide` both come from `office_toolkit::prelude`.
31    let presentation =
32        Presentation::new().with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)));
33    presentation.save_to_file(&path)?;
34    println!("Wrote {}", path.display());
35
36    // Read the file back to confirm it is a valid .pptx.
37    let reopened = Presentation::open_file(&path)?;
38    println!("Slide count: {}", reopened.slides.len());
39
40    Ok(())
41}
More examples
Hide additional examples
examples/pptx_notes_and_comments.rs (line 30)
12fn main() -> office_toolkit::Result<()> {
13    let path = output_path("pptx_notes_and_comments.pptx");
14
15    let title = |text: &str| {
16        AutoShape::new(2, "Title")
17            .with_properties(
18                ShapeProperties::new().with_transform(
19                    Transform2D::new()
20                        .with_offset(838_200, 838_200)
21                        .with_extent(8_000_000, 1_000_000),
22                ),
23            )
24            .with_text_body(
25                TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26            )
27    };
28
29    let notes_slide = Slide::new()
30        .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31        .with_notes(
32            TextBody::new().with_paragraph(
33                TextParagraph::new()
34                    .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35            ),
36        );
37
38    let commented_slide = Slide::new()
39        .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40        .with_comment(
41            SlideComment::new(
42                "Reviewer",
43                "RV",
44                "2026-07-21T10:00:00",
45                "This claim needs a source.",
46            )
47            .with_position(1_000_000, 2_000_000),
48        )
49        .with_comment(
50            SlideComment::new(
51                "Editor",
52                "ED",
53                "2026-07-21T11:30:00",
54                "Looks good otherwise.",
55            )
56            .with_position(3_000_000, 2_000_000),
57        );
58
59    let presentation = Presentation::new()
60        .with_slide(notes_slide)
61        .with_slide(commented_slide);
62
63    presentation.save_to_file(&path)?;
64    println!("Wrote {}", path.display());
65    Ok(())
66}
examples/pptx_media.rs (line 70)
20fn main() -> office_toolkit::Result<()> {
21    let path = output_path("pptx_media.pptx");
22    let image_bytes = std::fs::read(image_fixture_path())?;
23
24    let embedded_picture = Picture::new(
25        2,
26        "Embedded picture",
27        image_bytes.clone(),
28        PictureFormat::Png,
29        3_000_000,
30        2_000_000,
31    )
32    .with_offset(838_200, 838_200)
33    .with_description("Project test image");
34
35    let linked_picture = Picture::new(
36        2,
37        "Externally linked picture",
38        image_bytes,
39        PictureFormat::Png,
40        3_000_000,
41        2_000_000,
42    )
43    .with_offset(838_200, 838_200)
44    .with_external_link("https://example.com/original-image.png");
45
46    // Placeholder bytes — a real .pptx would carry a genuine video file
47    // here. This example only demonstrates the model/writer plumbing.
48    let poster_image = vec![0x89, 0x50, 0x4E, 0x47]; // fake, just enough bytes to have *some* data
49    let media = SlideMedia::new(
50        2,
51        "Video clip",
52        vec![0u8; 16],
53        MediaFormat::Mp4,
54        4_000_000,
55        2_250_000,
56    )
57    .with_offset(838_200, 838_200)
58    .with_poster_image(poster_image, PictureFormat::Png);
59
60    let chart = SlideChart::new(
61        2,
62        "Quarterly revenue",
63        sample_chart_space(),
64        6_000_000,
65        3_500_000,
66    )
67    .with_offset(838_200, 838_200);
68
69    let presentation = Presentation::new()
70        .with_slide(Slide::new().with_shape(Shape::Picture(embedded_picture)))
71        .with_slide(Slide::new().with_shape(Shape::Picture(linked_picture)))
72        .with_slide(Slide::new().with_shape(Shape::Media(media)))
73        .with_slide(Slide::new().with_shape(Shape::Chart(Box::new(chart))));
74
75    presentation.save_to_file(&path)?;
76    println!("Wrote {}", path.display());
77    Ok(())
78}
examples/pptx_tables.rs (line 92)
16fn main() -> office_toolkit::Result<()> {
17    let path = output_path("pptx_tables.pptx");
18
19    let plain_table = SlideTable::new(2, "Plain table", 5_000_000, 1_500_000)
20        .with_offset(838_200, 838_200)
21        .with_column_widths(vec![2_500_000, 2_500_000])
22        .with_row(
23            TableRow::new(500_000)
24                .with_cell(cell("Name"))
25                .with_cell(cell("Score")),
26        )
27        .with_row(
28            TableRow::new(500_000)
29                .with_cell(cell("Alice"))
30                .with_cell(cell("92")),
31        )
32        .with_row(
33            TableRow::new(500_000)
34                .with_cell(cell("Bob"))
35                .with_cell(cell("87")),
36        );
37
38    let merged_table = SlideTable::new(2, "Merged cells", 5_000_000, 1_000_000)
39        .with_offset(838_200, 838_200)
40        .with_column_widths(vec![1_667_000, 1_667_000, 1_666_000])
41        .with_row(
42            TableRow::new(500_000)
43                .with_cell(cell("Spanning header").with_horizontal_span(3))
44                .with_cell(TableCell::horizontally_merged())
45                .with_cell(TableCell::horizontally_merged()),
46        )
47        .with_row(
48            TableRow::new(500_000)
49                .with_cell(cell("A"))
50                .with_cell(cell("B"))
51                .with_cell(cell("C")),
52        );
53
54    let styled_table = SlideTable::new(2, "Styled table", 5_000_000, 1_500_000)
55        .with_offset(838_200, 838_200)
56        .with_style_id("{66BB4812-77A1-49B3-BDF9-0CCEB564D7B5}")
57        .with_style_first_row(true)
58        .with_style_band_rows(true)
59        .with_column_widths(vec![2_500_000, 2_500_000])
60        .with_row(
61            TableRow::new(500_000)
62                .with_cell(cell("Header A"))
63                .with_cell(cell("Header B")),
64        )
65        .with_row(
66            TableRow::new(500_000)
67                .with_cell(cell("1"))
68                .with_cell(cell("2")),
69        )
70        .with_row(
71            TableRow::new(500_000)
72                .with_cell(cell("3"))
73                .with_cell(cell("4")),
74        );
75
76    let presentation = Presentation::new()
77        .with_table_style(
78            SlideTableStyle::new(
79                "{66BB4812-77A1-49B3-BDF9-0CCEB564D7B5}",
80                "Custom Table Style",
81            )
82            .with_first_row(
83                TableStylePart::new()
84                    .with_fill(Fill::Solid(Color::Rgb("2E74B5".to_string())))
85                    .with_bold(true)
86                    .with_text_color(Color::Rgb("FFFFFF".to_string())),
87            )
88            .with_band1_horizontal(
89                TableStylePart::new().with_fill(Fill::Solid(Color::Rgb("F2F2F2".to_string()))),
90            ),
91        )
92        .with_slide(Slide::new().with_shape(Shape::Table(plain_table)))
93        .with_slide(Slide::new().with_shape(Shape::Table(merged_table)))
94        .with_slide(Slide::new().with_shape(Shape::Table(styled_table)));
95
96    presentation.save_to_file(&path)?;
97    println!("Wrote {}", path.display());
98    Ok(())
99}
examples/pptx_shapes_and_placeholders.rs (line 84)
14fn main() -> office_toolkit::Result<()> {
15    let path = output_path("pptx_shapes_and_placeholders.pptx");
16
17    let plain_shape = AutoShape::new(2, "Plain autoshape")
18        .with_properties(
19            ShapeProperties::new().with_transform(
20                Transform2D::new()
21                    .with_offset(838_200, 838_200)
22                    .with_extent(5_000_000, 1_000_000),
23            ),
24        )
25        .with_text_body(
26            TextBody::new()
27                .with_paragraph(TextParagraph::new().with_run(TextRun::text("A plain autoshape."))),
28        );
29
30    let text_box = AutoShape::new(2, "Text box")
31        .with_text_box(true)
32        .with_properties(
33            ShapeProperties::new().with_transform(
34                Transform2D::new()
35                    .with_offset(838_200, 838_200)
36                    .with_extent(5_000_000, 1_000_000),
37            ),
38        )
39        .with_text_body(TextBody::new().with_paragraph(
40            TextParagraph::new().with_run(TextRun::text("A genuine text box (txBox=\"1\").")),
41        ));
42
43    let title = AutoShape::new(2, "Title placeholder")
44        .with_placeholder(Placeholder::new(PlaceholderKind::CenterTitle))
45        .with_properties(
46            ShapeProperties::new().with_transform(
47                Transform2D::new()
48                    .with_offset(838_200, 838_200)
49                    .with_extent(10_515_600, 1_325_563),
50            ),
51        )
52        .with_text_body(
53            TextBody::new()
54                .with_paragraph(TextParagraph::new().with_run(TextRun::text("Title placeholder"))),
55        );
56    let subtitle =
57        AutoShape::new(3, "Subtitle placeholder")
58            .with_placeholder(Placeholder::new(PlaceholderKind::SubTitle).with_index(1))
59            .with_properties(
60                ShapeProperties::new().with_transform(
61                    Transform2D::new()
62                        .with_offset(838_200, 2_400_000)
63                        .with_extent(10_515_600, 800_000),
64                ),
65            )
66            .with_text_body(TextBody::new().with_paragraph(
67                TextParagraph::new().with_run(TextRun::text("Subtitle placeholder")),
68            ));
69
70    let hyperlinked_shape = AutoShape::new(2, "Hyperlinked shape")
71        .with_hyperlink("https://www.rust-lang.org")
72        .with_properties(
73            ShapeProperties::new().with_transform(
74                Transform2D::new()
75                    .with_offset(838_200, 838_200)
76                    .with_extent(5_000_000, 1_000_000),
77            ),
78        )
79        .with_text_body(TextBody::new().with_paragraph(
80            TextParagraph::new().with_run(TextRun::text("Click this shape to open a link.")),
81        ));
82
83    let presentation = Presentation::new()
84        .with_slide(Slide::new().with_shape(Shape::AutoShape(plain_shape)))
85        .with_slide(Slide::new().with_shape(Shape::AutoShape(text_box)))
86        .with_slide(
87            Slide::new()
88                .with_shape(Shape::AutoShape(title))
89                .with_shape(Shape::AutoShape(subtitle)),
90        )
91        .with_slide(Slide::new().with_shape(Shape::AutoShape(hyperlinked_shape)));
92
93    presentation.save_to_file(&path)?;
94    println!("Wrote {}", path.display());
95    Ok(())
96}
examples/pptx_theme_and_metadata.rs (line 82)
19fn main() -> office_toolkit::Result<()> {
20    // A custom theme and an embedded font. `Theme`/`ColorScheme`/
21    // `FontScheme` have no `with_*` builders in this crate — only
22    // `office_default()` or plain struct literals.
23    let custom_theme = Theme {
24        name: "Custom Brand".to_string(),
25        colors: ColorScheme {
26            dark1: "1B1B1B".to_string(),
27            light1: "FFFFFF".to_string(),
28            dark2: "0A2540".to_string(),
29            light2: "F5F5F5".to_string(),
30            accent1: "0A2540".to_string(),
31            accent2: "E8622C".to_string(),
32            accent3: "2E86AB".to_string(),
33            accent4: "6FB98F".to_string(),
34            accent5: "F4A259".to_string(),
35            accent6: "8E4585".to_string(),
36            hyperlink: "1155CC".to_string(),
37            followed_hyperlink: "6B3FA0".to_string(),
38        },
39        fonts: FontScheme {
40            major_latin: "Georgia".to_string(),
41            minor_latin: "Verdana".to_string(),
42        },
43    };
44
45    // Placeholder bytes — a real .pptx would carry genuine TrueType/
46    // OpenType font data here.
47    let embedded_font = EmbeddedFont::new("Custom Sans")
48        .with_regular(vec![0u8; 16])
49        .with_bold(vec![0u8; 16]);
50
51    // A slide with no shapes at all renders as a blank page — nothing shows
52    // the custom theme actually took effect. `drawing::Color` has no
53    // scheme-relative variant yet (`<a:schemeClr>` isn't modeled, see that
54    // enum's own doc comment), so this can't reference the theme's accent1
55    // symbolically; it uses the same literal hex values the theme itself
56    // was built from, purely so the slide visibly matches the palette above.
57    let title_shape = AutoShape::new(2, "Title")
58        .with_properties(
59            ShapeProperties::new()
60                .with_transform(
61                    Transform2D::new()
62                        .with_offset(838_200, 838_200)
63                        .with_extent(6_000_000, 1_500_000),
64                )
65                .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.accent1.clone()))),
66        )
67        .with_text_body(
68            TextBody::new().with_paragraph(
69                TextParagraph::new().with_run(TextRun::text_with_properties(
70                    "Custom Brand theme — Georgia / Verdana, accent1 = #0A2540",
71                    TextRunProperties::new()
72                        .with_font_family(custom_theme.fonts.major_latin.clone())
73                        .with_font_size_points(24.0)
74                        .with_fill(Fill::Solid(Color::Rgb(custom_theme.colors.light1.clone()))),
75                )),
76            ),
77        );
78
79    let themed_presentation = Presentation::new()
80        .with_theme(custom_theme)
81        .with_embedded_font(embedded_font)
82        .with_slide(Slide::new().with_shape(Shape::AutoShape(title_shape)));
83    let theme_path = output_path("pptx_theme.pptx");
84    themed_presentation.save_to_file(&theme_path)?;
85    println!("Wrote {}", theme_path.display());
86
87    // Document metadata (docProps/core.xml, app.xml, and custom.xml).
88    let properties = DocumentProperties::new()
89        .with_title("Metadata example")
90        .with_author("Example Author")
91        .with_subject("Presentation-level features")
92        .with_custom_property(
93            "ProjectCode",
94            CustomPropertyValue::Text("PPTX-META".to_string()),
95        );
96    // Same reasoning as `title_shape` above: an empty slide would render
97    // blank, so a text shape spells out where the metadata actually lives.
98    let metadata_shape = AutoShape::new(2, "Note")
99        .with_properties(ShapeProperties::new().with_transform(Transform2D::new().with_offset(838_200, 838_200).with_extent(7_000_000, 1_000_000)))
100        .with_text_body(TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(
101            "This presentation's metadata is in File > Info (title, author, subject, and a custom \"ProjectCode\" property) — not on this slide.",
102        ))));
103    let metadata_presentation = Presentation::new()
104        .with_properties(properties)
105        .with_slide(Slide::new().with_shape(Shape::AutoShape(metadata_shape)));
106    let metadata_path = output_path("pptx_metadata.pptx");
107    metadata_presentation.save_to_file(&metadata_path)?;
108    println!("Wrote {}", metadata_path.display());
109
110    Ok(())
111}
Source

pub fn add_shape(&mut self, shape: Shape) -> &mut Shape

Appends a shape and returns a mutable reference to it. A &mut self counterpart to Self::with_shape, same rationale as Presentation::add_slide.

Source

pub fn with_hidden(self, hidden: bool) -> Slide

Hides this slide from the normal slide-show sequence (show="0").

Source

pub fn with_name(self, name: impl Into<String>) -> Slide

Sets this slide’s display name (<p:sld name="..">).

Source

pub fn with_notes(self, notes: TextBody) -> Slide

Sets this slide’s speaker notes.

Examples found in repository?
examples/pptx_notes_and_comments.rs (lines 31-36)
12fn main() -> office_toolkit::Result<()> {
13    let path = output_path("pptx_notes_and_comments.pptx");
14
15    let title = |text: &str| {
16        AutoShape::new(2, "Title")
17            .with_properties(
18                ShapeProperties::new().with_transform(
19                    Transform2D::new()
20                        .with_offset(838_200, 838_200)
21                        .with_extent(8_000_000, 1_000_000),
22                ),
23            )
24            .with_text_body(
25                TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26            )
27    };
28
29    let notes_slide = Slide::new()
30        .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31        .with_notes(
32            TextBody::new().with_paragraph(
33                TextParagraph::new()
34                    .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35            ),
36        );
37
38    let commented_slide = Slide::new()
39        .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40        .with_comment(
41            SlideComment::new(
42                "Reviewer",
43                "RV",
44                "2026-07-21T10:00:00",
45                "This claim needs a source.",
46            )
47            .with_position(1_000_000, 2_000_000),
48        )
49        .with_comment(
50            SlideComment::new(
51                "Editor",
52                "ED",
53                "2026-07-21T11:30:00",
54                "Looks good otherwise.",
55            )
56            .with_position(3_000_000, 2_000_000),
57        );
58
59    let presentation = Presentation::new()
60        .with_slide(notes_slide)
61        .with_slide(commented_slide);
62
63    presentation.save_to_file(&path)?;
64    println!("Wrote {}", path.display());
65    Ok(())
66}
Source

pub fn with_comment(self, comment: SlideComment) -> Slide

Appends a comment.

Examples found in repository?
examples/pptx_notes_and_comments.rs (lines 40-48)
12fn main() -> office_toolkit::Result<()> {
13    let path = output_path("pptx_notes_and_comments.pptx");
14
15    let title = |text: &str| {
16        AutoShape::new(2, "Title")
17            .with_properties(
18                ShapeProperties::new().with_transform(
19                    Transform2D::new()
20                        .with_offset(838_200, 838_200)
21                        .with_extent(8_000_000, 1_000_000),
22                ),
23            )
24            .with_text_body(
25                TextBody::new().with_paragraph(TextParagraph::new().with_run(TextRun::text(text))),
26            )
27    };
28
29    let notes_slide = Slide::new()
30        .with_shape(Shape::AutoShape(title("A slide with speaker notes")))
31        .with_notes(
32            TextBody::new().with_paragraph(
33                TextParagraph::new()
34                    .with_run(TextRun::text("Remember to mention the Q3 numbers here.")),
35            ),
36        );
37
38    let commented_slide = Slide::new()
39        .with_shape(Shape::AutoShape(title("A slide with reviewer comments")))
40        .with_comment(
41            SlideComment::new(
42                "Reviewer",
43                "RV",
44                "2026-07-21T10:00:00",
45                "This claim needs a source.",
46            )
47            .with_position(1_000_000, 2_000_000),
48        )
49        .with_comment(
50            SlideComment::new(
51                "Editor",
52                "ED",
53                "2026-07-21T11:30:00",
54                "Looks good otherwise.",
55            )
56            .with_position(3_000_000, 2_000_000),
57        );
58
59    let presentation = Presentation::new()
60        .with_slide(notes_slide)
61        .with_slide(commented_slide);
62
63    presentation.save_to_file(&path)?;
64    println!("Wrote {}", path.display());
65    Ok(())
66}
Source

pub fn with_background(self, background: Fill) -> Slide

Sets this slide’s own background fill, overriding the layout/master.

Source

pub fn with_hide_master_graphics(self, hide: bool) -> Slide

Hides this slide’s inherited slide-master graphics (showMasterSp="0").

Trait Implementations§

Source§

impl Clone for Slide

Source§

fn clone(&self) -> Slide

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Slide

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for Slide

Source§

fn default() -> Slide

Returns the “default value” for a type. Read more
Source§

impl PartialEq for Slide

Source§

fn eq(&self, other: &Slide) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Slide

Auto Trait Implementations§

§

impl Freeze for Slide

§

impl RefUnwindSafe for Slide

§

impl Send for Slide

§

impl Sync for Slide

§

impl Unpin for Slide

§

impl UnsafeUnpin for Slide

§

impl UnwindSafe for Slide

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.