Skip to main content

ShapesMut

Struct ShapesMut 

Source
pub struct ShapesMut<'a> { /* private fields */ }
Expand description

可变形状视图。

通过 slide.shapes_mut() 获取,是 add_* / remove 唯一入口。

Implementations§

Source§

impl<'a> ShapesMut<'a>

Source

pub fn len(&self) -> usize

形状数量。

Source

pub fn is_empty(&self) -> bool

是否为空。

Source

pub fn iter(&self) -> impl Iterator<Item = ShapeKind> + '_

遍历(只读克隆)。

Source

pub fn get(&self, idx: usize) -> Option<ShapeKind>

按索引取(克隆)。

Source

pub fn remove(&mut self, idx: usize) -> Option<ShapeKind>

按索引移除一个形状。

返回被移除形状的高阶克隆(None 表示 idx 越界)。 移除后,后续 shape 的索引会前移

Source

pub fn add_placeholder_from_layout( &mut self, ph_idx: u32, layout: &SlideLayoutRef, ) -> Result<AutoShape>

从版式占位符定义创建一个新的 slide 占位符(TODO-007)。

对标 python-pptx “从模板创建 slide 后填充占位符“的工作流。

本方法会:

  1. 在 layout 的 shapes 中查找 ph_idx 匹配的占位符;
  2. 克隆该 layout 占位符作为 slide 占位符的初始状态(继承位置/尺寸/格式);
  3. 分配新的 shape id,清空文本内容(等待调用方填充);
  4. 追加到 slide 的 shapes 末尾。
§参数
  • ph_idx:要创建的占位符 idx(对应 <p:ph idx="N"/>);
  • layout:所属 Presentation 中的版式引用。
§返回
  • Ok(AutoShape):创建成功,返回占位符的高阶视图;
  • Err(Error::Other):layout 中未找到 ph_idx 匹配的占位符。
Source

pub fn add_textbox<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, left: L, top: T, width: W, height: H, ) -> Result<TextBox>

添加一个文本框。

文本内容留空,需要后续 text_frame_mut().set_text(...)。 位置/尺寸参数接受任意实现 EmuExt 的类型(Inches / Cm / Emu / …)。

Source

pub fn add_textbox_with_text<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, left: L, top: T, width: W, height: H, text: &str, ) -> Result<TextBox>

添加一个文本框,并直接写入文本(一步完成,避免 clone-sp 与 sp 失同步)。

add_textbox + 后续 set_text 略快,且不易写错。

Source

pub fn add_picture<P: AsRef<Path>, L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, path: P, left: L, top: T, width: W, height: H, ) -> Result<Picture>

从本地路径添加一张图片。

自动推断 Content-Type 与扩展名(png / jpg / gif / bmp / svg 等)。

内部会自动:

  • 分配全局唯一的 rIdImgN 关系 id;
  • 注册 /ppt/media/imageN.<ext> part(保存时被写入 zip);
  • slideN.xml.rels 中添加 Image 关系。
Source

pub fn add_picture_to_placeholder<P: AsRef<Path>>( &mut self, ph_idx: u32, path: P, layout: &SlideLayoutRef, ) -> Result<Picture>

添加一张图片并标记为占位符填充(TODO-007 高阶 API)。

add_picture 的区别:

  • 本方法创建的 <p:pic> 会带 <p:ph type="pic" idx="N"/> 标记, PowerPoint 会把它识别为“占位符填充“而非自由图片;
  • 位置 / 尺寸自动从版式占位符继承layoutph_idx == ph_idx 的占位符), 调用方无需手动指定 left/top/width/height;
  • 若版式中找不到匹配的占位符,回退到 left=0, top=0, width=9144000, height=6858000 (默认 10“ × 7.5“),并仍然写出占位符标记。
§参数
  • ph_idx:占位符 idx(对应版式中 <p:ph idx="N"/> 的 N);
  • path:图片文件路径;
  • layout:当前 slide 关联的版式引用(用于继承位置/尺寸)。
§返回值
§与 python-pptx 的对应

python-pptx 中 slide.shapes.add_picture(path, ...) 不会自动绑定占位符; 用户需要先 slide.placeholders[idx] 取占位符再 placeholder.insert_picture(path)。 本方法把两步合并为一个原子操作,语义更清晰。

§示例
use pptx_rs::Presentation;

let mut p = Presentation::new().unwrap();
// 先取版式(避免与 slides_mut 的可变借用冲突)
let layout = p.slide_layouts().get(0).cloned().unwrap();
let counter = p.id_counter();
let s = p.slides_mut().add_slide(counter).unwrap();
// 假设版式有 idx=10 的图片占位符
let pic = s.shapes_mut().add_picture_to_placeholder(10, "logo.png", &layout).unwrap();
Source

pub fn add_chart_to_placeholder( &mut self, ph_idx: u32, chart_type: ChartType, data: ChartData, layout: &SlideLayoutRef, ) -> Result<ChartShape>

添加一个图表并绑定到指定占位符(TODO-007 图表占位符类型化填充)。

Self::add_chart 的区别:本方法会从 layout 中查找 ph_idx 对应的 占位符,继承其位置/尺寸,并把生成的 graphicFrame 标记为占位符 (写出 <p:ph type="chart" idx="..."/>)。

§参数
  • ph_idx:占位符索引(对应版式中 <p:ph idx="..."/>)。
  • chart_type:图表类型(柱/条/线/饼)。
  • data:图表数据(类别 + 系列 + 可选标题)。
  • layout:所属 Presentation 中的版式引用。
§返回值
  • 成功:返回 ChartShape(已设置占位符标记 + 继承的位置/尺寸)。
§与 python-pptx 的对应

python-pptx 中通过 slide.placeholders[idx].insert_chart(...) 实现图表占位符填充; 本方法把“取占位符 + 创建图表 + 绑定“合并为一个原子操作。

§示例
let mut data = ChartData::default();
data.categories = vec![ChartCategory::new("Q1"), ChartCategory::new("Q2")];
data.series = vec![ChartSeries::new("Sales", vec![10.0, 20.0])];
// 假设版式有 idx=12 的图表占位符
let chart = s.shapes_mut().add_chart_to_placeholder(
    12, ChartType::Column, data, &layout,
).unwrap();
Source

pub fn add_table_to_placeholder( &mut self, ph_idx: u32, rows: usize, cols: usize, layout: &SlideLayoutRef, ) -> Result<TableShape>

添加一个表格并绑定到指定占位符(TODO-007 表格占位符类型化填充)。

Self::add_table 的区别:本方法会从 layout 中查找 ph_idx 对应的 占位符,继承其位置/尺寸,并把生成的 graphicFrame 标记为占位符 (写出 <p:ph type="tbl" idx="..."/>)。

§参数
  • ph_idx:占位符索引(对应版式中 <p:ph idx="..."/>)。
  • rows / cols:表格行列数。
  • layout:所属 Presentation 中的版式引用。
§返回值
  • 成功:返回 TableShape(已设置占位符标记 + 继承的位置/尺寸)。
§与 python-pptx 的对应

python-pptx 中通过 slide.placeholders[idx].insert_table(rows, cols) 实现表格占位符填充; 本方法把“取占位符 + 创建表格 + 绑定“合并为一个原子操作。

§示例
// 假设版式有 idx=14 的表格占位符
let tbl = s.shapes_mut().add_table_to_placeholder(
    14, 3, 4, &layout,
).unwrap();
Source

pub fn add_shape<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, geometry: PresetGeometry, left: L, top: T, width: W, height: H, ) -> Result<AutoShape>

添加一个自选图形(预设几何)。

几何形如 crate::oxml::simpletypes::PresetGeometry::Rectangle / Ellipse / RightArrow / …,完整列表见 OOXML 规范。

Source

pub fn add_connector<BX: EmuExt, BY: EmuExt, EX: EmuExt, EY: EmuExt>( &mut self, connector_type: MsoConnectorType, begin_x: BX, begin_y: BY, end_x: EX, end_y: EY, ) -> Result<Connector>

添加一个连接器

§参数
  • connector_type:连接器几何(MSO_CONNECTOR_TYPE,默认 MsoConnectorType::Straight);
  • begin_x / begin_y:起点 EMU 坐标;
  • end_x / end_y:终点 EMU 坐标;
§与 python-pptx 的对应

对应 SlideShapes.add_connector(connector_type, begin_x, begin_y, end_x, end_y)。 在 pptx-rs 中所有长度参数都实现 EmuExt,可直接传 Inches(...)

§修订历史

早期签名采用 4 参版(仅 begin_x, begin_y, end_x, end_y),后被改写为 (begin_x, _begin_y_ignored, end_x, _end_y_ignored),但实现却把 y 强制为 0, 导致连接器始终在 y=0 —— 现已恢复为 4 参版本并正确使用 y 坐标。

Source

pub fn add_connector_geom<BL: EmuExt, BT: EmuExt, EL: EmuExt, ET: EmuExt>( &mut self, connector_type: MsoConnectorType, begin_x: BL, begin_y: BT, end_x: EL, end_y: ET, ) -> Result<Connector>

👎Deprecated since 0.1.0:

已与 add_connector 合并;请改用 add_connector(connector_type, begin_x, begin_y, end_x, end_y)

添加一个连接器(完整 4 端点 + 类型版本)。

真正对齐 python-pptx add_connector(connector_type, begin_x, begin_y, end_x, end_y)

§弃用说明

此方法自 0.1.x 起已与 Self::add_connector 合并——后者已恢复 4 端点签名。 保留仅为兼容既有调用方;新代码请直接使用 Self::add_connector

Source

pub fn add_freeform( &mut self, freeform: Freeform, left: Emu, top: Emu, width: Emu, height: Emu, ) -> Result<Freeform>

添加一个自由形(已完成 crate::shape::freeform::FreeformBuilder 流程)。

§当前实现

0.1.0 的 Freeform::build 内部退化为 AutoShape + 矩形 prstGeom—— 真正的 a:custGeom 描述(折线/曲线/闭合)将在 0.2.0 接入。 因此当前 add_freeform 在视觉上与 add_shape(Rectangle, ...) 一致, 但 Freeformpoints() 仍可被读取。

Source

pub fn move_to_front(&mut self, idx: usize)

把 idx 处的形状移到末尾(z-order 顶层)。

Source

pub fn move_to_back(&mut self, idx: usize)

把 idx 处的形状移到首位置(z-order 底层)。

Source

pub fn move_up(&mut self, idx: usize)

把 idx 处的形状向上移动一级(z-order 提升)。

对标 python-pptx 中通过 XML 操作调整形状顺序的能力。 若 idx 已是顶层(最后一个)或越界,则为 no-op。

Source

pub fn move_down(&mut self, idx: usize)

把 idx 处的形状向下移动一级(z-order 降低)。

对标 python-pptx 中通过 XML 操作调整形状顺序的能力。 若 idx 已是底层(第一个)或越界,则为 no-op。

Source

pub fn index(&self, kind: &ShapeKind) -> Option<usize>

找某个 ShapeKind 的索引(克隆比较)。

等价 python-pptx 中 SlideShapes.index(shape)

Source

pub fn add_group<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, left: L, top: T, width: W, height: H, ) -> Result<Group>

添加一个组合(后续通过 Group::children_mut 加入子形状)。

Source

pub fn add_table<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, rows: usize, cols: usize, left: L, top: T, width: W, height: H, ) -> Result<TableShape>

添加一个等分表格。

行高 = height / rows,列宽 = width / cols。如需不等分请改用 TableShape::set_row_height / set_col_width

Source

pub fn add_chart<L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt>( &mut self, chart_type: ChartType, data: ChartData, left: L, top: T, width: W, height: H, ) -> Result<ChartShape>

添加一个图表(TODO-004 基础图表支持)。

当前支持 4 种图表类型:柱状图(ChartType::Column)、条形图(ChartType::Bar)、 折线图(ChartType::Line)、饼图(ChartType::Pie)。数据通过 <c:numCache> 内嵌,不依赖嵌入 Excel。

§参数
  • chart_type:图表类型。
  • data:图表数据(类别 + 系列 + 可选标题)。
  • left / top / width / height:图表在 slide 中的位置与尺寸。
§内部行为
  1. 创建一个 ChartShape,设置几何 + id;
  2. 分配一个本 slide 内唯一的关系 id rIdChartN
  3. rIdChartN 同步写入 ChartShape.frame.graphic.Chart.rid, 供 <c:chart r:id="rIdChartN"/> 引用;
  4. 注册 ChartEntry 到本 slide(保存时由 to_opc_package 写出独立的 /ppt/charts/chartN.xml part + slideN.xml.rels 关系);
  5. ChartShape.frame 作为 GraphicFrame 推入 spTree
§示例
let mut data = ChartData::default();
data.categories = vec![ChartCategory::new("Q1"), ChartCategory::new("Q2")];
data.series = vec![ChartSeries::new("Sales", vec![10.0, 20.0])];
data.title = Some("Revenue".to_string());
let _chart = slide.shapes_mut().add_chart(
    ChartType::Column, data,
    Inches(1.0), Inches(2.0), Inches(8.0), Inches(4.0),
).unwrap();
Source

pub fn add_chart_with_excel<L, T, W, H>( &mut self, chart_type: ChartType, data: ChartData, xlsx_blob: Vec<u8>, left: L, top: T, width: W, height: H, ) -> Result<ChartShape>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt,

添加一个带嵌入式 Excel 工作簿的图表(TODO-004 Excel 嵌入)。

Self::add_chart 的区别:本方法额外接受 xlsx_blob 参数(有效的 .xlsx 文件字节流),保存时会在 .pptx 内生成 /ppt/embeddings/Microsoft_Excel_WorksheetN.xlsx part + chart part 的 独立关系文件 _rels/chartN.xml.rels(Type=Package),并在 chart XML 中写入 <c:externalData r:id="rIdXlsxN"/> 引用。PowerPoint 打开图表时 会从该 xlsx part 读取数据源,“编辑数据” 会启动 Excel。

§参数
  • chart_type:图表类型。
  • data:图表数据(类别 + 系列 + 可选标题)。仍会写入 numCache/strCache, 即使 PowerPoint 不打开 xlsx 也能渲染图表。
  • xlsx_blob:有效的 .xlsx 文件字节流(OOXML SpreadsheetML 包格式)。 库不校验内容有效性,PowerPoint 会按 zip + XML 解析。
  • left / top / width / height:图表在 slide 中的位置与尺寸。
§返回值
§内部行为
  1. Self::add_chart 一致地构造 ChartShape + 分配 rIdChartN
  2. 注册 ChartEntryxlsx_blob 字段填入 Some(xlsx_blob.to_vec())
  3. 保存时由 to_opc_package 写出 xlsx part + chart rels + externalData 引用。
§关键约束
  • xlsx 内容应由调用方保证有效:库不解析 xlsx,PowerPoint 打开时 若 xlsx 损坏会报错。
  • xlsx 内数据应与 data 一致:PowerPoint 优先用 numCache 渲染, 但用户“编辑数据“时会以 xlsx 为准。若两者不一致,编辑后图表会变化。
  • xlsx_rid 由 presentation 层自动分配:用户无需手动设置。
§示例
let mut data = ChartData::default();
data.categories = vec![ChartCategory::new("Q1"), ChartCategory::new("Q2")];
data.series = vec![ChartSeries::new("Sales", vec![10.0, 20.0])];
let _chart = slide.shapes_mut().add_chart_with_excel(
    ChartType::Column, data, xlsx_bytes,
    Inches(1.0), Inches(2.0), Inches(8.0), Inches(4.0),
).unwrap();
Source

pub fn add_ole_object<L, T, W, H, P>( &mut self, path: P, prog_id: &str, name: &str, left: L, top: T, width: W, height: H, ) -> Result<OleObjectShape>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt, P: AsRef<Path>,

在当前幻灯片上嵌入一个 OLE 对象(TODO-043)。

对标 python-pptx 0.6.19+ 的 shapes.add_ole_object()。把指定文件 作为 OLE 复合文档嵌入到 .pptx 中,PowerPoint 双击时会调用对应 OLE 服务器(由 prog_id 决定)打开编辑。

§参数
  • path:OLE 文件路径(如 .xls / .doc / .bin)。 文件内容会以原始字节写入 /ppt/embeddings/oleObjectN.bin
  • prog_id:OLE 程序标识符(如 "Excel.Sheet.12" / "Word.Document.12" / "Package")。PowerPoint 通过 progId 决定双击时调用哪个 OLE 服务器。
  • name:显示名(在 PowerPoint 中作为对象名,如 "Worksheet")。
  • left / top / width / height:OLE 对象在 slide 上的位置与尺寸(EMU)。
§返回值
  • 成功:返回 OleObjectShape 高阶句柄,可继续调整 show_as_icon / set_image_rid(图标图片)等属性。
  • 失败:返回 crate::Error::Io(文件读取失败)。
§内部流程
  1. 读取文件内容为 Vec<u8>
  2. 创建一个 OleObjectShape,设置几何 + id + progId + name;
  3. 分配一个本 slide 内唯一的关系 id rIdOleN
  4. rIdOleN 同步写入 OleObjectShape.frame.graphic.OleObject.rid, 供 <p:oleObj r:id="rIdOleN"/> 引用;
  5. 注册 OleEntry 到本 slide(保存时由 to_opc_package 写出独立的 /ppt/embeddings/oleObjectN.bin part + slideN.xml.rels 关系);
  6. OleObjectShape.frame 作为 GraphicFrame 推入 spTree
§示例
let _ole = slide.shapes_mut().add_ole_object(
    "data.xlsx", "Excel.Sheet.12", "Worksheet",
    Inches(1.0), Inches(2.0), Inches(4.0), Inches(3.0),
).unwrap();
Source

pub fn add_smartart_from_xml<L, T, W, H>( &mut self, data_xml: &str, layout_xml: &str, quick_style_xml: &str, colors_xml: &str, left: L, top: T, width: W, height: H, ) -> Result<SmartArtShape>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt,

在当前幻灯片上创建一个 SmartArt 图形(从 4 份原始 XML 字符串,TODO-037 创建 API)。

这是“逃生舱“入口,适合用户已有 4 份 diagram XML(如从其它 .pptx 复制、或手工构造)的场景。若希望通过结构化模型程序化构建,请使用 Self::add_smartart

§参数
  • data_xml<dgm:dataModel> 完整 XML(对应 /ppt/diagrams/dataN.xml)。
  • layout_xml<dgm:layoutDef> 完整 XML(对应 /ppt/diagrams/layoutN.xml)。
  • quick_style_xml<dgm:styleData> 完整 XML(对应 /ppt/diagrams/quickStylesN.xml)。
  • colors_xml<dgm:colorsDef> 完整 XML(对应 /ppt/diagrams/colorsN.xml)。
  • left / top / width / height:SmartArt 在 slide 上的位置与尺寸(EMU)。
§返回值
  • 成功:返回 SmartArtShape 高阶句柄,可继续调整位置 / 占位符等属性。
  • 失败:返回 crate::Error(目前为不可失败,但保留 Result 以便未来扩展)。
§内部流程
  1. 调用 Slide::allocate_diagram_rids 分配本 slide 内唯一的 4 个关系 id (rIdDgmDataN / rIdDgmLayoutN / rIdDgmQsN / rIdDgmColorsN);
  2. 用 4 个 rid 构造 SmartArtShape(内部通过 crate::oxml::shape::SmartArtRef::from_rids 生成 <a:graphicData><dgm:relIds .../></a:graphicData>);
  3. 调用 Slide::next_diagram_index 取局部索引,构造 4 个 partname 占位 (to_opc_package 阶段会用全局索引重新分配,覆盖此处的占位);
  4. 注册 DiagramEntry 到本 slide(保存时由 to_opc_package 写出 4 个 diagram part + slide rels 的 4 个关系);
  5. 推入 spTree
§关键约束
  • partname 占位:本方法生成的 4 个 partname 仅用于 DiagramEntry 字段 占位,to_opc_package 写出时会用全局索引重新分配(避免多 slide 冲突)。
  • rid 全程不变:4 个 rid 一旦分配就贯穿 slide XML / slideN.xml.rels / diagram parts 引用链,不会被重写。
  • XML 透传:4 份 XML 字符串原样写入 zip part,不做任何解析或重建 (byte-exact round-trip 友好)。
§示例
let data_xml = r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dgm:dataModel xmlns:dgm="http://schemas.openxmlformats.org/drawingml/2006/diagram"
               xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
  <dgm:ptLst><dgm:pt modelId="1" type="doc"/></dgm:ptLst>
</dgm:dataModel>"#;
// ... 其余 3 份 XML 省略
let sa = slide.shapes_mut().add_smartart_from_xml(
    data_xml, layout_xml, quick_style_xml, colors_xml,
    Inches(1.0), Inches(1.0), Inches(8.0), Inches(4.0),
).unwrap();
assert_eq!(sa.shape_type(), "smart_art");
Source

pub fn add_smartart<L, T, W, H>( &mut self, data_model: DataModel, layout_def: LayoutDef, quick_style: QuickStyleDef, colors: ColorsDef, left: L, top: T, width: W, height: H, ) -> Result<SmartArtShape>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt,

在当前幻灯片上创建一个 SmartArt 图形(从结构化模型,TODO-037 创建 API)。

这是高阶友好入口,适合程序化构建 SmartArt。内部调用 4 个结构化模型的 to_xml() 生成 XML 字符串,再委托给 Self::add_smartart_from_xml

§参数
  • data_model:数据模型(<dgm:dataModel>,含 points + connections)。
  • layout_def:布局定义(<dgm:layoutDef>,含 layoutNode 子树)。
  • quick_style:样式定义(<dgm:styleData>,含 styleLbl 列表)。
  • colors:颜色定义(<dgm:colorsDef>,含 styleClrLbl 列表)。
  • left / top / width / height:位置与尺寸(EMU)。
§返回值
  • 成功:返回 SmartArtShape 高阶句柄。
  • 失败:返回 crate::Error(来自 4 个 to_xml() 调用,目前不会失败)。
§示例
use pptx_rs::oxml::diagram::{DataModel, DataModelPoint, LayoutDef, QuickStyleDef, ColorsDef};
let mut dm = DataModel::default();
dm.points.push(DataModelPoint {
    model_id: 1,
    pt_type: Some("doc".into()),
    text: Some("根节点".into()),
    ..Default::default()
});
let sa = slide.shapes_mut().add_smartart(
    dm,
    LayoutDef::default(),
    QuickStyleDef::default(),
    ColorsDef::default(),
    Inches(1.0), Inches(1.0), Inches(8.0), Inches(4.0),
).unwrap();
assert!(sa.dm_rid().starts_with("rIdDgmData"));
Source

pub fn add_video<L, T, W, H, P>( &mut self, video_path: P, poster_path: Option<P>, left: L, top: T, width: W, height: H, ) -> Result<Picture>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt, P: AsRef<Path>,

在当前幻灯片上嵌入一个视频形状(TODO-033)。

对标 python-pptx 0.6.19+ 的 shapes.add_movie()。把指定视频文件 嵌入到 .pptx 中,PowerPoint 双击视频区域时会播放该视频。

§参数
  • video_path:视频文件路径(如 .mp4)。文件内容会以原始字节 写入 /ppt/media/mediaN.mp4
  • poster_path:海报帧图片路径(视频未播放时显示的静态画面,如 .png / .jpg)。 若为 None,PowerPoint 会显示空白占位(推荐传入代表视频首帧的图片)。
  • left / top / width / height:视频形状在 slide 上的位置与尺寸(EMU)。
§返回值
  • 成功:返回 Picture 高阶句柄(已标记为视频形状),可继续调整裁剪 / 填充模式等图片属性。
  • 失败:返回 crate::Error::Io(视频或海报文件读取失败)。
§内部流程
  1. 读取视频文件内容为 Vec<u8>
  2. 读取海报帧图片内容(若 poster_pathNone,用 1x1 透明 PNG 占位);
  3. 手动构造 Picture 并注册海报帧 MediaEntryrIdImgN + imageN.png part);
  4. 分配本 slide 内唯一的视频关系 id rIdVideoN
  5. 调用 pic.set_video(rIdVideoN) 把图片标记为视频形状(写出 <a:videoFile r:link="rIdVideoN"/>);
  6. 注册 VideoEntry 到本 slide(保存时由 to_opc_package 写出独立的 /ppt/media/mediaN.mp4 part + slideN.xml.rels Video 关系)。
§关键约束
  • r:embed vs r:link:海报帧图片用 r:embed(嵌入图片),视频文件用 r:link(外部链接方式);
  • partname 命名:视频文件 /ppt/media/mediaN.mp4,海报帧图片 /ppt/media/imageN.png, 两者命名空间不同但同在 /ppt/media/ 目录下;
  • 关系类型:视频用 .../relationships/video,海报帧用 .../relationships/image
§示例
let _video = slide.shapes_mut().add_video(
    "intro.mp4", Some("poster.png"),
    Inches(1.0), Inches(1.0), Inches(6.0), Inches(4.0),
).unwrap();
Source

pub fn add_audio<L, T, W, H, P>( &mut self, audio_path: P, poster_path: Option<P>, left: L, top: T, width: W, height: H, ) -> Result<Picture>
where L: EmuExt, T: EmuExt, W: EmuExt, H: EmuExt, P: AsRef<Path>,

在当前幻灯片上嵌入一个音频形状(TODO-033)。

对标 python-pptx 0.6.19+ 的 shapes.add_audio()。把指定音频文件 嵌入到 .pptx 中,PowerPoint 双击音频形状时会播放该音频。

§参数
  • audio_path:音频文件路径(如 .mp3)。文件内容会以原始字节 写入 /ppt/media/mediaN.mp3
  • poster_path:海报帧图片路径(音频未播放时显示的图标,如 .png / .jpg)。 若为 None,PowerPoint 会显示默认音频图标(推荐传入代表音频的图标图片)。
  • left / top / width / height:音频形状在 slide 上的位置与尺寸(EMU)。
§返回值
  • 成功:返回 Picture 高阶句柄(已标记为音频形状);
  • 失败:返回 crate::Error::Io(音频或海报文件读取失败)。
§Self::add_video 的差异
  • add_video 写出 <a:videoFile r:link="..."/>,partname 后缀 .mp4
  • add_audio 写出 <a:audioFile r:link="..."/>,partname 后缀 .mp3
  • 关系类型分别为 .../video.../audio
§示例
let _audio = slide.shapes_mut().add_audio(
    "bgm.mp3", Some("speaker.png"),
    Inches(1.0), Inches(1.0), Inches(2.0), Inches(2.0),
).unwrap();

Trait Implementations§

Source§

impl<'a> Debug for ShapesMut<'a>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for ShapesMut<'a>

§

impl<'a> !Send for ShapesMut<'a>

§

impl<'a> !Sync for ShapesMut<'a>

§

impl<'a> !UnwindSafe for ShapesMut<'a>

§

impl<'a> Freeze for ShapesMut<'a>

§

impl<'a> Unpin for ShapesMut<'a>

§

impl<'a> UnsafeUnpin for ShapesMut<'a>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V