Apply a theme to a presentation
A presentation theme is stored in a theme part rooted at <a:theme/>. Applying a theme means copying or replacing the target presentation's theme part and keeping relationships valid.
Theme structure
The theme root contains theme elements, optional object defaults, extra color schemes, custom colors, and extensions.
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office">
<a:themeElements>
<a:clrScheme name="Office"/>
<a:fontScheme name="Office"/>
<a:fmtScheme name="Office"/>
</a:themeElements>
</a:theme>
In a PresentationML package, the presentation part usually owns the theme relationship.
The generated Rust root type is ooxmlsdk::schemas::a::Theme. Its main child types correspond to the theme schema:
| XML element | Rust type | Purpose |
|---|---|---|
a:themeElements | ooxmlsdk::schemas::a::ThemeElements | Base color, font, and format schemes |
a:objectDefaults | ooxmlsdk::schemas::a::ObjectDefaults | Object defaults |
a:extraClrSchemeLst | ooxmlsdk::schemas::a::ExtraColorSchemeList | Extra color schemes |
a:custClrLst | ooxmlsdk::schemas::a::CustomColorList | Custom colors |
a:extLst | ooxmlsdk::schemas::a::OfficeStyleSheetExtensionList | Extensibility |
Full presentation theme replacement
The upstream sample does more than copy theme1.xml: it copies a slide master from a source presentation, reuses the target slide master relationship ID, copies the source theme, then relinks every slide to a layout of the same type. If a slide has no matching layout type, the sample uses a default layout such as "Title and Content".
That workflow matters because a presentation theme is normally coupled with slide masters and layouts. Replacing only the theme part can leave slides pointing at layouts whose placeholder geometry, fonts, or colors no longer match the intended design.
Rust workflow
Open the source presentation read-only, open or copy the target package, and use the presentation part's theme accessor to read the theme data. The general package navigation pattern is:
#![allow(unused)] fn main() { use std::io::Cursor; use std::path::Path; use ooxmlsdk::parts::comment_authors_part::CommentAuthorsPart; use ooxmlsdk::parts::presentation_document::PresentationDocument; use ooxmlsdk::parts::presentation_part::PresentationPart; use ooxmlsdk::parts::slide_comments_part::SlideCommentsPart; use ooxmlsdk::parts::slide_part::SlidePart; use ooxmlsdk::sdk::MediaDataPartType; use ooxmlsdk::sdk::{OpenSettings, PackageOpenMode, PresentationDocumentType}; pub fn open_presentation_read_only(path: &Path) -> Result<usize, Box<dyn std::error::Error>> { let document = PresentationDocument::new_from_file_with_settings(path, lazy_settings())?; let presentation_part = document.presentation_part()?; Ok(presentation_part.slide_parts(&document).count()) } }
For a full Rust writer, verify these invariants before saving:
- source theme part exists,
- target theme relationship is added or replaced,
- dependent slide masters and layouts still resolve their theme references,
- the saved package opens in PowerPoint or another strict consumer.
The WordprocessingML theme replacement example in the General section shows the package-level copy-and-replace pattern. PresentationML theme application has a larger package surface because slide masters and layouts are part of the visual result.