pub struct Presentation { /* private fields */ }Expand description
演示文稿(内存模型)。
§字段语义
slides/slide_layouts/slide_masters:三类“主-版-页“集合;width/height:画布尺寸,序列化为<p:sldSz cx="..." cy="..."/>;id_counter:共享 ID 计数器(每张 slide / 每个 shape 都会next_shape_id);- 媒体(图片等 blob)按 slide 存储——参见
Slide::register_media。 保存时由to_opc_package遍历self.slides聚合写入 zip;同一 partname 只写一次。
Implementations§
Source§impl Presentation
impl Presentation
Sourcepub fn new() -> Result<Self>
pub fn new() -> Result<Self>
新建一个完全空白的演示文稿。
内部会做两件事:
- 把
id_counter初始化为2(保留1给“隐藏占位“用途,与 Office 一致); - 调用
Presentation::ensure_default_master_and_layout创建 1 个 默认母版 + 1 个空白版式,保证保存出的.pptx在 PowerPoint 中能正常打开。
§错误
当前实现不会失败;保留 Result 是为后续扩展(例如从模板加载 master)留口。
Sourcepub fn open(path: impl AsRef<Path>) -> Result<Self>
pub fn open(path: impl AsRef<Path>) -> Result<Self>
打开一个已存在的 .pptx 文件并解析为内存模型。
等价于 Presentation::load,提供“短名 + 详细名“两个入口。
§错误
crate::Error::Io:文件不存在或权限不足;crate::Error::Zip:zip 损坏;crate::Error::Xml:内部 XML 无法解析(注意:当前 read 路径尚未完整实现, 实际只解析[Content_Types].xml,其它 part 暂未还原到 oxml 模型)。
Sourcepub fn load(path: &Path) -> Result<Self>
pub fn load(path: &Path) -> Result<Self>
加载 .pptx 的详细入口(与 Presentation::open 等价)。
Sourcepub fn load_bytes(bytes: &[u8]) -> Result<Self>
pub fn load_bytes(bytes: &[u8]) -> Result<Self>
从内存中的 zip 字节流加载。
与 Presentation::load 的区别:本方法不触发磁盘 IO,可用于:
- Web 服务接收
multipart/form-data上传后的字节流; - 单元测试中 fixture 来自
include_bytes!的场景; - 通过
std::io::Cursor包装任意Read来源。
§错误
crate::Error::Io:ZipArchive::new失败;crate::Error::Xml:[Content_Types].xml解析失败。
Sourcepub fn slides_mut(&mut self) -> &mut Slides
pub fn slides_mut(&mut self) -> &mut Slides
可变幻灯片集合。
Sourcepub fn id_counter(&self) -> Rc<Cell<u32>>
pub fn id_counter(&self) -> Rc<Cell<u32>>
取出共享的 id_counter 克隆。
Slides::add_slide 接受这个计数器,从而保证跨 slide 的 shape id 不冲突。
Sourcepub fn slide_layouts(&self) -> &SlideLayouts
pub fn slide_layouts(&self) -> &SlideLayouts
不可变版式集合。
Sourcepub fn slide_layouts_mut(&mut self) -> &mut SlideLayouts
pub fn slide_layouts_mut(&mut self) -> &mut SlideLayouts
可变版式集合。
Sourcepub fn layout_for_slide(&self, slide_idx: usize) -> Option<SlideLayoutRef>
pub fn layout_for_slide(&self, slide_idx: usize) -> Option<SlideLayoutRef>
按 slide 索引取该 slide 所引用的版式(TODO-007)。
对标 python-pptx slide.slide_layout。本方法通过匹配
slide.layout_rid() 与 SlideLayoutRef.rid() 查找。
§参数
slide_idx:slide 在slides集合中的索引。
§返回
Some(SlideLayoutRef):找到匹配的版式(克隆,因SlideLayoutRef是Clone);None:索引越界,或未找到 rid 匹配的版式。
§示例
use pptx_rs::Presentation;
let mut p = Presentation::new().unwrap();
let counter = p.id_counter();
let _ = p.slides_mut().add_slide(counter).unwrap();
// 获取第 0 张 slide 所引用的版式
if let Some(layout) = p.layout_for_slide(0) {
println!("版式名: {}", layout.name());
}Sourcepub fn slides_using_layout(&self, layout_rid: &str) -> Vec<usize>
pub fn slides_using_layout(&self, layout_rid: &str) -> Vec<usize>
Sourcepub fn slide_masters(&self) -> &SlideMasters
pub fn slide_masters(&self) -> &SlideMasters
不可变母版集合。
Sourcepub fn slide_masters_mut(&mut self) -> &mut SlideMasters
pub fn slide_masters_mut(&mut self) -> &mut SlideMasters
可变母版集合。
Sourcepub fn slide_width(&self) -> Emu
pub fn slide_width(&self) -> Emu
当前画布宽度(EMU)。
Sourcepub fn slide_height(&self) -> Emu
pub fn slide_height(&self) -> Emu
当前画布高度(EMU)。
Sourcepub fn set_slide_size(&mut self, width: Emu, height: Emu)
pub fn set_slide_size(&mut self, width: Emu, height: Emu)
显式设置画布尺寸。
注意此方法不触发任何 Slide 内部 shape 的重新布局;shape 仍按各自的
EMU 坐标保存,调用方需自行决定是否缩放。
Sourcepub fn core_properties(&self) -> &CoreProperties
pub fn core_properties(&self) -> &CoreProperties
取文档核心属性(不可变引用)。
对标 pypdf PdfReader.metadata / python-pptx Presentation.core_properties。
Sourcepub fn core_properties_mut(&mut self) -> &mut CoreProperties
pub fn core_properties_mut(&mut self) -> &mut CoreProperties
取文档核心属性(可变引用)。
对标 pypdf PdfWriter.add_metadata(infos)。
修改后会在 save / to_bytes 时序列化到 docProps/core.xml 和 docProps/app.xml。
Sourcepub fn custom_properties(&self) -> &CustomProperties
pub fn custom_properties(&self) -> &CustomProperties
取自定义文档属性(不可变引用)。
对标 python-pptx Presentation.custom_properties(v1.0+)。
Sourcepub fn custom_properties_mut(&mut self) -> &mut CustomProperties
pub fn custom_properties_mut(&mut self) -> &mut CustomProperties
取自定义文档属性(可变引用)。
修改后会在 save / to_bytes 时序列化到 docProps/custom.xml。
§示例
use pptx_rs::Presentation;
use pptx_rs::presentation::CustomPropertyValue;
let mut p = Presentation::new().unwrap();
p.custom_properties_mut().set("Project", CustomPropertyValue::Text("Demo".to_string()));
p.custom_properties_mut().set("Version", CustomPropertyValue::Int(42));取评论作者列表(不可变引用)。
评论作者在 save / to_bytes 时序列化到 /ppt/commentAuthors.xml。
取评论作者列表(可变引用)。
修改后会在 save / to_bytes 时序列化到 /ppt/commentAuthors.xml。
§示例
use pptx_rs::Presentation;
let mut p = Presentation::new().unwrap();
let author_id = p.comment_authors_mut().get_or_insert_id("张三", "ZS");Sourcepub fn sections(&self) -> &SectionList
pub fn sections(&self) -> &SectionList
取章节分组列表(不可变引用,TODO-039)。
章节分组对应 PowerPoint 大纲视图中的“节“功能,在 presentation.xml
的 <p:extLst> 内以 <p14:sectionLst> 扩展元素持久化。
§与 python-pptx 的对应
python-pptx 截至 v1.0 仍未提供 section API,本方法是 pptx-rs 的扩展。
Sourcepub fn sections_mut(&mut self) -> &mut SectionList
pub fn sections_mut(&mut self) -> &mut SectionList
取章节分组列表(可变引用,TODO-039)。
修改后会在 save / to_bytes 时序列化到 presentation.xml 的
<p:extLst><p:ext uri="{521415D9-36F7-43E2-AB2F-B90AF26B5E64}">
内的 <p14:sectionLst>。
§示例
use pptx_rs::Presentation;
use pptx_rs::oxml::section::Section;
let mut p = Presentation::new().unwrap();
// 假设已添加 2 张 slide,它们的 sld_id 分别为 256 / 257
let mut s1 = Section::new("引言");
s1.push(256);
s1.push(257);
p.sections_mut().push(s1);Sourcepub fn notes_masters(&self) -> &NotesMasters
pub fn notes_masters(&self) -> &NotesMasters
取备注母版集合(不可变引用,TODO-045)。
备注母版是所有备注页的“模板“——定义了备注页的默认占位符与文本样式。 一个演示文稿通常只有 0 或 1 个备注母版。
§与 python-pptx 的对应
pptx.Presentation.notes_master←→presentation.notes_masters().first();- python-pptx 仅暴露单个
notes_master属性,本库用集合表达以兼容多母版场景。
§示例
use pptx_rs::Presentation;
let p = Presentation::new().unwrap();
// 空白文档无备注母版
assert!(p.notes_masters().is_empty());Sourcepub fn notes_masters_mut(&mut self) -> &mut NotesMasters
pub fn notes_masters_mut(&mut self) -> &mut NotesMasters
取备注母版集合(可变引用,TODO-045)。
主要用于在内存中修改已解析出的备注母版形状(写路径暂未实现持久化)。
Sourcepub fn notes_master(&self) -> Option<&NotesMasterRef>
pub fn notes_master(&self) -> Option<&NotesMasterRef>
便捷方法:取第一个备注母版(python-pptx presentation.notes_master 风格)。
None 表示该演示文稿无备注母版。
Sourcepub fn set_metadata(
&mut self,
title: Option<&str>,
creator: Option<&str>,
subject: Option<&str>,
keywords: Option<&str>,
)
pub fn set_metadata( &mut self, title: Option<&str>, creator: Option<&str>, subject: Option<&str>, keywords: Option<&str>, )
一次性设置多个核心属性(便捷方法)。
对标 pypdf PdfWriter.add_metadata(infos) 的“批量设置“语义。
传入 None 的字段不会覆盖已有值。
§示例
use pptx_rs::Presentation;
let mut p = Presentation::new().unwrap();
p.set_metadata(
Some("My Presentation"), // title
Some("Author Name"), // creator
None, // subject (keep existing)
None, // keywords
);Sourcepub fn num_slides(&self) -> usize
pub fn num_slides(&self) -> usize
幻灯片总数。
对标 pypdf PdfReader.num_pages / python-pptx len(prs.slides)。
Sourcepub fn add_watermark(
&mut self,
text: &str,
font_size_pt: Option<f64>,
color: Option<RGBColor>,
rotation_deg: Option<i32>,
alpha: Option<i32>,
font_name: Option<&str>,
) -> Result<()>
pub fn add_watermark( &mut self, text: &str, font_size_pt: Option<f64>, color: Option<RGBColor>, rotation_deg: Option<i32>, alpha: Option<i32>, font_name: Option<&str>, ) -> Result<()>
给所有 slide 添加文本水印。
对标 pypdf PageObject.merge_page(watermark_page) 的水印注入模式。
§实现原理
在每张 slide 上添加一个旋转 + 半透明的文本框(p:sp + cNvSpPr txBox="1"),
位于 slide 中心,字体大小可配置。文本框的 z-order 被推到最顶层
(即最后添加的形状),确保水印覆盖在内容之上。
§参数
text:水印文本(如 “CONFIDENTIAL” / “DRAFT”);font_size_pt:字体大小(磅),默认 36;color:水印颜色,默认灰色RGBColor(0xC0, 0xC0, 0xC0);rotation_deg:旋转角度(度),默认 -30(逆时针 30°);alpha:不透明度(0-100000),默认 30_000(30% 不透明 / 70% 透明);font_name:字体名称,默认 “Calibri”。
§与 pypdf 的差异
- pypdf 用“页面合并“(
merge_page)实现水印——把水印 PDF 页叠加到目标页; - 本方法用“形状注入“——直接在 slide XML 中插入一个旋转文本框。 两种方式在视觉上等价,但 OOXML 不支持“页面合并“语义。
Sourcepub fn add_image_watermark(
&mut self,
image_bytes: &[u8],
ext: &str,
alpha: Option<i32>,
left: Option<Emu>,
top: Option<Emu>,
width: Option<Emu>,
height: Option<Emu>,
) -> Result<()>
pub fn add_image_watermark( &mut self, image_bytes: &[u8], ext: &str, alpha: Option<i32>, left: Option<Emu>, top: Option<Emu>, width: Option<Emu>, height: Option<Emu>, ) -> Result<()>
给所有 slide 添加图片水印。
对标 pypdf PageObject.merge_page(watermark_page) 的水印注入模式。
§实现原理
在每张 slide 上添加一个半透明的图片形状(p:pic + a:alphaModFix),
位于 slide 中心,大小可配置。图片的 z-order 被推到最顶层
(即最后添加的形状),确保水印覆盖在内容之上。
§参数
image_bytes:图片二进制数据(PNG / JPG / BMP 等);ext:图片扩展名(如"png"/"jpg",不含前导.);alpha:不透明度(0-100000),默认 30_000(30% 不透明 / 70% 透明);left:水印左上角 x 坐标(EMU),默认居中偏左 1/4 画布宽度;top:水印左上角 y 坐标(EMU),默认居中偏上 1/4 画布高度;width:水印宽度(EMU),默认画布宽度的一半;height:水印高度(EMU),默认画布高度的一半。
§与文本水印的差异
- 文本水印(
add_watermark)用旋转文本框实现,适合“CONFIDENTIAL“等文字; - 图片水印用半透明图片实现,适合公司 logo / 自定义图案等场景。
§错误
crate::Error::Encryption:图片字节为空。
Sourcepub fn set_write_protection(&mut self, password: &str) -> Result<()>
pub fn set_write_protection(&mut self, password: &str) -> Result<()>
设置修改密码保护(打开时可只读浏览,修改需密码)。
对标 PowerPoint “保护演示文稿 → 限制访问” 功能。
§算法
使用 SHA-512 + 随机 salt + 100 000 次迭代,符合 MS-OFFCRYPTO §2.4.2.4。
保护信息注入到 presentation.xml 的 <p:modifyVerifier> 元素中。
§参数
password:修改密码(不能为空)。
§错误
crate::Error::Encryption:密码为空。
Sourcepub fn verify_write_protection(&self, password: &str) -> Result<bool>
pub fn verify_write_protection(&self, password: &str) -> Result<bool>
Sourcepub fn remove_write_protection(&mut self)
pub fn remove_write_protection(&mut self)
移除修改密码保护。
Sourcepub fn is_write_protected(&self) -> bool
pub fn is_write_protected(&self) -> bool
检查是否设置了修改密码保护。
Sourcepub fn save_encrypted(
&self,
path: impl AsRef<Path>,
password: &str,
) -> Result<()>
pub fn save_encrypted( &self, path: impl AsRef<Path>, password: &str, ) -> Result<()>
保存为加密的 .pptx 文件(打开文件需密码)。
对标 PowerPoint “保护演示文稿 → 用密码进行加密” 功能。 使用 ECMA-376 Agile Encryption(AES-256-CBC + SHA-512)。
§参数
path:输出文件路径;password:加密密码。
§错误
crate::Error::Encryption:加密过程失败。crate::Error::Io:文件写入失败。
Sourcepub fn to_encrypted_bytes(&self, password: &str) -> Result<Vec<u8>>
pub fn to_encrypted_bytes(&self, password: &str) -> Result<Vec<u8>>
序列化为加密的字节流(打开需密码)。
等价于“保存到内存“的加密版本,适用于网络传输等场景。
Sourcepub fn open_encrypted(path: impl AsRef<Path>, password: &str) -> Result<Self>
pub fn open_encrypted(path: impl AsRef<Path>, password: &str) -> Result<Self>
打开加密的 .pptx 文件。
§参数
path:文件路径;password:解密密码。
§错误
crate::Error::Encryption:密码错误或加密格式损坏;crate::Error::Io:文件读取失败。
Sourcepub fn load_encrypted_bytes(bytes: &[u8], password: &str) -> Result<Self>
pub fn load_encrypted_bytes(bytes: &[u8], password: &str) -> Result<Self>
从加密的字节流加载。
Sourcepub fn is_encrypted_file(path: impl AsRef<Path>) -> Result<bool>
pub fn is_encrypted_file(path: impl AsRef<Path>) -> Result<bool>
检查文件是否为加密的 OOXML 文档。
加密文档的特征:ZIP 中包含 EncryptionInfo 条目。
Sourcepub fn is_encrypted_bytes(bytes: &[u8]) -> bool
pub fn is_encrypted_bytes(bytes: &[u8]) -> bool
检查字节流是否为加密的 OOXML 文档。
Trait Implementations§
Source§impl Debug for Presentation
impl Debug for Presentation
Source§impl Default for Presentation
impl Default for Presentation
Source§fn default() -> Self
fn default() -> Self
Default 等价于 Presentation::new。
Default trait 签名无法返回 Result,因此此处使用 expect。
安全性保证:Presentation::new() 当前实现不会返回 Err(仅做
字段初始化),如果未来 new() 可能失败,应移除 Default impl
并改为关联常量或工厂方法。