# PPTX API 设计
### 1. 统一的文档结构
```rust
// PPTX 构建器实现统一接口
pub struct PptxBuilder {
document: Document,
}
impl DocumentBuilder<Document> for PptxBuilder {
fn new() -> Self {
Self { document: Document::new() }
}
fn save<P: AsRef<Path>>(self, path: P) -> Result<()> {
self.document.save_as_pptx(path)
}
fn build(self) -> Result<Document> {
Ok(self.document)
}
}
// 简化的幻灯片构建
impl PptxBuilder {
pub fn slide<F>(mut self, builder: F) -> Self
where F: FnOnce(SlideBuilder) -> SlideBuilder
{
let slide = builder(SlideBuilder::new()).build();
self.document.add_slide(slide);
self
}
pub fn theme(mut self, theme: Theme) -> Self {
self.document.set_theme(theme);
self
}
}
// 预定义布局和样式
pub struct Layouts;
impl Layouts {
pub fn title_slide() -> SlideLayout { SlideLayout::Title }
pub fn content() -> SlideLayout { SlideLayout::Content }
pub fn two_content() -> SlideLayout { SlideLayout::TwoContent }
pub fn blank() -> SlideLayout { SlideLayout::Blank }
}
pub struct Position {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
impl Position {
pub fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
Self { x, y, width, height }
}
pub fn center(width: f32, height: f32) -> Self {
Self::new((720.0 - width) / 2.0, (540.0 - height) / 2.0, width, height)
}
}
```
### 2. 简化的幻灯片构建
```rust
// 幻灯片构建器
pub struct SlideBuilder {
slide: Slide,
}
impl SlideBuilder {
pub fn new() -> Self {
Self { slide: Slide::new() }
}
pub fn layout(mut self, layout: SlideLayout) -> Self {
self.slide.set_layout(layout);
self
}
pub fn title(mut self, text: &str) -> Self {
self.slide.add_title(text);
self
}
pub fn text(mut self, content: &str, position: Position) -> Self {
self.slide.add_text_box(content, position);
self
}
pub fn image<P: AsRef<Path>>(mut self, path: P, position: Position) -> Self {
self.slide.add_image(path, position);
self
}
pub fn table(mut self, data: Vec<Vec<&str>>, position: Position) -> Self {
self.slide.add_table(data, position);
self
}
pub fn chart<F>(mut self, position: Position, builder: F) -> Self
where F: FnOnce(ChartBuilder) -> ChartBuilder
{
let chart = builder(ChartBuilder::new()).build();
self.slide.add_chart(chart, position);
self
}
pub fn build(self) -> Slide {
self.slide
}
}
// 图表构建器
pub struct ChartBuilder {
chart: Chart,
}
impl ChartBuilder {
pub fn new() -> Self {
Self { chart: Chart::new() }
}
pub fn chart_type(mut self, chart_type: ChartType) -> Self {
self.chart.set_type(chart_type);
self
}
pub fn data(mut self, data: Vec<(String, f64)>) -> Self {
self.chart.set_data(data);
self
}
pub fn build(self) -> Chart {
self.chart
}
}
```
### 3. 错误处理
```rust
#[derive(Debug, thiserror::Error)]
pub enum PptxError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Invalid presentation structure: {0}")]
Structure(String),
#[error("Invalid image format: {0}")]
ImageFormat(String),
#[error("Unsupported feature: {0}")]
Unsupported(String)
}
```
### 4. 关键特征定义
```rust
pub trait SlideElement {
fn to_xml(&self) -> Result<String, PptxError>;
fn get_bounds(&self) -> Transform2D;
}
pub trait Animation {
fn get_timing(&self) -> Timing;
fn get_effect(&self) -> Effect;
}
pub trait MediaContent {
fn get_media_type(&self) -> MediaType;
fn get_data(&self) -> Result<Vec<u8>, PptxError>;
}
```
### 3. 统一的使用示例
```rust
// 简洁的演示文稿创建
fn create_presentation() -> Result<()> {
PptxBuilder::new()
// 标题页
.slide(|slide| slide
.layout(Layouts::title_slide())
.title("产品发布会")
.text("2024年新产品介绍", Position::center(400.0, 100.0))
)
// 内容页
.slide(|slide| slide
.layout(Layouts::content())
.title("产品特性")
.text("• 高性能\n• 易使用\n• 安全可靠",
Position::new(100.0, 200.0, 300.0, 200.0))
.image("product.png", Position::new(450.0, 200.0, 200.0, 150.0))
)
// 数据图表页
.slide(|slide| slide
.title("销售数据")
.chart(Position::center(500.0, 300.0), |chart| chart
.chart_type(ChartType::Column)
.data(vec![
("Q1".to_string(), 100.0),
("Q2".to_string(), 150.0),
("Q3".to_string(), 200.0),
("Q4".to_string(), 180.0),
])
)
)
// 表格页
.slide(|slide| slide
.title("产品对比")
.table(vec![
vec!["功能", "基础版", "专业版", "企业版"],
vec!["用户数", "10", "100", "无限制"],
vec!["存储", "1GB", "10GB", "100GB"],
vec!["支持", "邮件", "电话", "专属客服"],
], Position::center(600.0, 250.0))
)
.save("product_presentation.pptx")
}
// 快速创建简单演示文稿
fn quick_presentation() -> Result<()> {
PptxBuilder::new()
.slide(|s| s.title("欢迎"))
.slide(|s| s.title("内容").text("主要内容", Position::center(400.0, 200.0)))
.slide(|s| s.title("谢谢"))
.save("quick_presentation.pptx")
}
```
### 关键设计优势:
1. **统一接口**:与其他Office格式使用相同的构建器模式
2. **类型安全**:编译时检查确保API使用正确
3. **简洁易用**:减少样板代码,提高开发效率
4. **灵活布局**:支持预定义布局和自定义定位
5. **丰富内容**:支持文本、图片、图表、表格等多种内容类型