pub struct Presentation {
pub slides: Vec<Slide>,
pub slide_width_emu: i64,
pub slide_height_emu: i64,
pub theme: Option<Theme>,
pub properties: DocumentProperties,
pub table_styles: Vec<SlideTableStyle>,
pub embedded_fonts: Vec<EmbeddedFont>,
}Expand description
A .pptx presentation: an ordered list of slides, plus the slide size.
A real PowerPoint package also always carries a slide master, at least one slide layout, and a
theme — but this crate has no customizable model for the slide master/layout (still a single
minimal, fixed pair under the hood; the reader ignores their content entirely, it only resolves
each slide’s own shapes). The theme, however, is customizable (theme) — unlike the
master/layout, a slide master’s theme relationship is mandatory per ECMA-376
but its actual color/font content is the single most visible piece of a deck’s visual identity,
so it gets its own model rather than staying permanently fixed like excel-ooxml’s theme.
Fields§
§slides: Vec<Slide>The slides, in display order.
slide_width_emu: i64<p:sldSz cx=".." cy="..">, in EMUs.
slide_height_emu: i64§theme: Option<Theme>This presentation’s color/font theme. None (the default) still always produces a complete
ppt/theme/theme1.xml — the part itself is mandatory, not optional, unlike e.g.
word-ooxml::Document.theme — just with Office’s own built-in default colors/fonts
(Theme::office_default) rather than a caller-supplied palette.
properties: DocumentPropertiesDocument metadata (docProps/core.xml/app.xml/custom.xml). Ports excel-ooxml’s own
DocumentProperties posture unchanged (same fields, same “each None/empty stays an
omitted, schema-valid element/part” behavior).
table_styles: Vec<SlideTableStyle>Package-wide custom table styles (ppt/tableStyles.xml’s own <a:tblStyle> entries, beyond
the single fixed built-in one this crate always declares as def). Referenced by id from
SlideTable::style_id. An empty Vec (the default) means every table in this
presentation uses the fixed built-in style, unchanged.
embedded_fonts: Vec<EmbeddedFont>TrueType/OpenType fonts embedded directly in the package (ppt/fonts/fontN.fntdata,
<p:embeddedFontLst>). Lets a presentation carry a non-standard font so it renders
correctly even on a machine that doesn’t have that font installed. An empty Vec (the
default) omits <p:embeddedFontLst> entirely and leaves <p:presentation>’s own
embedTrueTypeFonts attribute unset, same “only write what was actually set” convention as
every other optional part in this crate.
Implementations§
Source§impl Presentation
impl Presentation
Sourcepub fn new() -> Presentation
pub fn new() -> Presentation
Creates an empty presentation (no slides), with the default 16:9 widescreen slide size and no custom theme (Office’s own built-in default colors/fonts are used).
Examples found in repository?
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
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}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}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}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}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}Sourcepub fn with_slide(self, slide: Slide) -> Presentation
pub fn with_slide(self, slide: Slide) -> Presentation
Appends a slide.
Examples found in repository?
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
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}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}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}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}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}Sourcepub fn add_slide(&mut self) -> &mut Slide
pub fn add_slide(&mut self) -> &mut Slide
Appends an empty slide and returns a mutable reference to it, to build it up in place
(presentation.add_slide().add_shape(..)). A &mut self counterpart to
Self::with_slide, for building a presentation slide-by-slide in a loop without the
consuming builder’s presentation = presentation.with_slide(..) reassignment on every
iteration.
Sourcepub fn with_slide_size(self, width_emu: i64, height_emu: i64) -> Presentation
pub fn with_slide_size(self, width_emu: i64, height_emu: i64) -> Presentation
Overrides the slide size (default: 16:9 widescreen).
Sourcepub fn with_theme(self, theme: Theme) -> Presentation
pub fn with_theme(self, theme: Theme) -> Presentation
Sets a custom color/font theme, replacing Office’s own built-in default.
Examples found in repository?
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}Sourcepub fn with_properties(self, properties: DocumentProperties) -> Presentation
pub fn with_properties(self, properties: DocumentProperties) -> Presentation
Sets this presentation’s document metadata.
Examples found in repository?
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}Sourcepub fn with_table_style(self, table_style: SlideTableStyle) -> Presentation
pub fn with_table_style(self, table_style: SlideTableStyle) -> Presentation
Appends a custom table style.
Examples found in repository?
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}Sourcepub fn with_embedded_font(self, font: EmbeddedFont) -> Presentation
pub fn with_embedded_font(self, font: EmbeddedFont) -> Presentation
Appends an embedded font.
Examples found in repository?
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§impl Presentation
impl Presentation
Source§impl Presentation
impl Presentation
Sourcepub fn write_to<W>(&self, writer: W) -> Result<W, Error>
pub fn write_to<W>(&self, writer: W) -> Result<W, Error>
Writes this presentation to a seekable byte sink as a valid .pptx package:
[Content_Types].xml, _rels/.rels, ppt/presentation.xml (+ rels), one
ppt/slides/slideN.xml (+ rels) per slide, a single fixed
ppt/slideMasters/slideMaster1.xml (+ rels), ppt/slideLayouts/slideLayout1.xml (+ rels),
ppt/theme/theme1.xml, ppt/presProps.xml, ppt/viewProps.xml, ppt/tableStyles.xml,
docProps/core.xml, docProps/app.xml, plus ppt/media/imageN.*/ ppt/charts/chartN.xml
for any picture/chart shape, plus (only if at least one slide has notes) a single fixed
ppt/notesMasters/notesMaster1.xml and one ppt/notesSlides/notesSlideN.xml per slide that
has notes, plus (only if at least one slide has comments) a single ppt/commentAuthors.xml
and one ppt/comments/commentN.xml per slide that has comments. ppt/theme/theme1.xml’s
content follows self.theme (Office’s own built-in default when unset) — see this module’s
own doc comment for why the slide master/layout pair itself stays fixed.
Trait Implementations§
Source§impl Clone for Presentation
impl Clone for Presentation
Source§fn clone(&self) -> Presentation
fn clone(&self) -> Presentation
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for Presentation
impl Debug for Presentation
Source§impl Default for Presentation
impl Default for Presentation
Source§fn default() -> Presentation
fn default() -> Presentation
Source§impl OpenFile for Presentation
Available on crate feature powerpoint only.
impl OpenFile for Presentation
powerpoint only.Source§impl PartialEq for Presentation
impl PartialEq for Presentation
Source§impl SaveToFile for Presentation
Available on crate feature powerpoint only.
impl SaveToFile for Presentation
powerpoint only.