# PowerPoint/PPTX 自动化技能包
<!-- autos.skill.namespace: autos.skills.powerPoint -->
<!-- autos.skill.description: PPT/PPTX 任务：优先原生生成、读取与有限编辑；按需使用 Office/WPS COM 制作、嵌入媒体和渲染导出。 -->
<!-- autos.skill.version: 0.10.1 -->
<!-- autos.skill.minAutos: 4.13 -->

## 路线与边界

- **原生优先，不排斥 COM。** 常规 PPTX 生成、读取和有限编辑优先用 `fsys.openXml`，轻量且不依赖 Office。用户已安装 Office/WPS，而某项操作用 COM 更直接可靠时，可以直接使用或混合使用；不必为了坚持原生而绕远路。
- **按任务选入口**：声明式生成用 `fsys.openXml.pptx.builder`；有限编辑用 `fsys.openXml.pptx.editor`；文本、备注、媒体抽取用 `fsys.openXml.pptx`；应用级制作、保真渲染、PDF/图片导出及媒体嵌入可用 Office/WPS COM。
- **混合路线**：原生生成主体 → 用 COM 打开结果 → 补充视频、特殊对象或导出。COM 回存可能重写部件；若要求未修改部件原字节保持，应限于原生 editor 支持的操作。
- 原生不提供旧 `.ppt` 二进制格式、加密文稿、用户母版导入、任意已有图表数据编辑、MP4 嵌入或渲染引擎。MP4 使用下文 COM 示例，不手拼视频 XML；不要把读取媒体误当成支持生成所有媒体类型。
- 使用现有库，不在技能中重复实现 ZIP/XML。修改用户文件前先备份，优先另存；不访问外链、不执行宏或嵌入对象来“验证”原生文稿。

## 原生生成 PPTX

直接导入 builder，不需要参考文稿、Office/WPS、.NET 或读取器。下面是最小生成示例；正式排版可在写入前使用下文 `builder.check`：

```aardio
import fsys.openXml.pptx.builder;
var slides=[{
    notes="由 aardio 原生生成";
    transition={effect="fade";duration=0.7};
    background="F4F7FC";
    shapes=[{
        kind="text";name="Title";
        x=60;y=60;width=840;height=100;
        text="原生 PPTX 与动画";fontSize=36;color="18324F";
        animation={effect="fade";trigger="click";duration=0.6};
    },{
        kind="shape";name="Badge";
        x=60;y=220;width=320;height=180;
        geometry="roundRect";fill="4472C4";
        text="可编辑的幻灯片";color="FFFFFF";align="center";valign="center";
        animation=[
            {effect="fly";direction="left";trigger="after";duration=0.5},
            {effect="spin";angle=90;trigger="click";duration=0.7}
        ];
    }];
}];
var path,err=fsys.openXml.pptx.builder.write("/native.pptx",slides);
if(!path) return null,err;
return path;
```

### 数据、排版与外观

- 坐标、尺寸、字号为 **point**；默认页面 960×540。原生颜色用 `RRGGBB` 字符串，不用 COM 的数值 COLORREF。`write(path,slides,options)` 默认不覆盖；显式 `options.overwrite=true` 才覆盖目标。输入错误带页号和形状名。
- `kind` 可为 `text/shape/image/table/chart`。文本用 `text` 或 `paragraphs/runs`，运行支持局部字体、字号、粗体、斜体、颜色及下划线。生成器不自动缩字或分页。
- `margin` 为 point，可用四边表；`lineSpacing=125` 表示 1.25 倍行距；`spaceBefore/spaceAfter` 为 point，可在段落中覆盖。
- `fontName` 同时用于拉丁、东亚、复杂文种，也可分设 `fontNameLatin/fontNameEa/fontNameCs`；主题字体随 options 设置，`headingFontName` 指定标题主题字体。`lang` 默认 zh-CN；备注默认 12pt，可用 `options.notesFontSize` 设置。
- `fill/background` 支持纯色、`{color="FFFFFF";opacity=0.3}` 或渐变 `{angle=45;stops=[{position=0;color="15314F"},{position=1;color="36798B"}]}`。opacity/position 为 0..1，0 有效；渐变 stops 为 2~32 项，按位置升序。
- 图片 `path/data` 仅本地 PNG/JPEG，不下载外链、不重编码。`fit="contain"` 完整等比适配，`fit="cover"` 等比铺满裁切，默认 `stretch`；`imageAlignX/Y=0..1`，默认 0.5。相同图片去重嵌入。
- 线条 `lineDash` 可为 dash/dot/sysDot/lgDash 等；`lineStart/lineEnd` 可为 triangle/stealth/diamond/oval/arrow 或 `{type,size}`。`geometry="line"` 可直接给 `x,y,x2,y2`。
- text/shape/image 可设简单外阴影 `shadow=true` 或 `{color="000000";opacity=0.2;blur=4;distance=3;angle=45}`。blur/distance 为 point，angle 顺时针、0 向右、90 向下，不随形状旋转；不支持整表、内阴影、透视阴影。
- text/shape 的 `geometry="roundRect";cornerRadius=12` 可设圆角，范围 0 到短边一半，单位 point；省略使用预设圆角，不用于图片裁切。

### 表格

- `rows` 是完整矩形二维数组。`columnWidths/rowHeights` 为 point 数组，合计须等于表格宽/高；`header` 设置首行样式，`bandFill` 设置隔行色，`borderColor/borderWidth` 设置边框。
- 单元格可为简单值或 `{text,paragraphs,fill,color,bold,margin,valign}`。使用 `margin` 与 `valign="top"/"center"/"bottom"` 设置边距、垂直对齐，由库处理 Office/WPS 兼容，不自行叠加文本边距或缩字号补偿。
- `merges=[{row,column,rowSpan,colSpan}]` 指定合并，行列从 1 开始，跨度默认 1，至少覆盖两格。仍须提供完整矩形 rows，覆盖格必须为空；越界、重叠、隐藏非空数据会拒绝。
- 不自动增加行列；内容过多可能由应用撑高表格，应结合预检调整尺寸。已有文稿的填值和合并见“模板与数据”。

### 动画、切换与版式

- 整形状 `animation` 可为单个效果或效果数组。effect 为 `appear/fade/fly/wipe/zoom/spin/grow`；category 为 `entrance/exit/emphasis`，spin/grow 默认 emphasis。trigger 为 `click/with/after`，duration/delay 为秒。不要把 COM 的 MsoAnimEffect 数值当作 XML presetID。
- **逐段落**：`animation.byParagraph=true`；首段用 trigger/delay，后续用 `paragraphTrigger="click"`（默认，可选 with/after）和 `paragraphDelay=0`。每个非空真实段落独立播放，空段略过，软换行不拆段，不按缩进层级合组。`paragraph=N` 可只指定一段（1-based），与 byParagraph 互斥。仅 entrance/exit 的 appear/fade/fly/wipe/zoom 支持按段。
- `transition.effect` 可为 `none/cut/fade/push/wipe/split/morph`；duration、advanceAfter 为秒，advanceOnClick 控制点击翻页。
- **Morph**：`transition={effect="morph";option="byObject";duration=1.4}`，option 可为 byObject/byWord/byChar。包含 fade 回退，但回退不是同等的平滑效果。相邻页希望匹配的对象可使用相同的唯一名称，如 `!!Focus`；不是所有对象和软件版本都能插值。
- `slide.layout="blank"/"title"/"titleContent"/"twoContent"`，默认 blank。`kind="text"` 可设 `placeholder="title"/"subtitle"/"body"`；第二栏正文用 `{type="body";index=2}`。标题默认 index=0，副标题/第一栏正文=1；同页索引唯一。
- 只生成显式提供的形状；占位符省略几何时由标准版式补全，可显式覆盖。正文占位符不是图片/图表通用内容容器，基础版式不等于导入用户母版。生成、版式和预检共用默认几何。

### 页码、链接与编号

- **页码**：`options.slideNumber=true` 或 `{x,y,width,height,fontSize,color,align,margin,prefix,suffix}` 自动添加页码；`slide.slideNumber=false` 隐藏单页，但仍计序。`firstSlideNumber` 默认 1，可为 0。运行 `{field="slideNumber"}` 可放正文或表格，不能同时写 text。输出真实 slidenum 字段和当前页缓存；总页数后缀是静态文字。reader/editor 不重算字段缓存，交由 Office/WPS 刷新。
- **链接**：text/shape/image 或运行可设 `hyperlink="https://..."`、`{url,tooltip}`、`{slide=3}` 或 `{action="first"}`；动作可为 next/previous/first/last/back/end。slide 是本次生成的 1-based 页序，不受 firstSlideNumber 影响。仅点击链接，外链限 http/https/mailto，生成时不访问；不支持程序/宏/文件动作。颜色不自动改变，可显式 color/underline。表格用单元格运行链接，不支持整表链接。
- **编号**：段落 `numbering=true`（arabicPeriod）、类型字符串或 `{type,startAt}`，与 bullet 互斥。支持阿拉伯数字、大小写字母、大小写罗马共 12 种常用格式；level=0..8，marginLeft/hanging 为 point。
- startAt=1..32767 是序列起始基数，后续同层同类型省略时沿用；连续 3/4/5 不要逐段写 startAt=3/4/5。相同 startAt 不强制重启；新列表可用独立文本框或非编号段隔开。预检扣除正文缩进，不模拟长编号字形排版。

### 二维原生图表

- 用 `{kind="chart";name="Chart";x=50;y=60;width=860;height=400;chart={type="column";categories=["A","B"];series=[{name="销量";values=[12,0]}]}}` 创建。type 为 `column/bar/line/pie`；柱/条为二维簇状，折线为等距分类轴；饼图限单系列、非负且至少一项正值。
- 每图包含独立 ChartML 和内嵌 XLSX 的 Data 表，分类、系列、数值引用与缓存一致，可在 Office/WPS 中“编辑数据”。values 与 categories 等长，**0 为真实数值，null 为空点**。
- **稀疏数组用 `table.len/table.eachIndex` 保留全部槽位。** 尾部 null 或全空数组需设 `values@={length=N}`；不要用 `#` 或默认迭代器推断稀疏长度。
- 样式放在 chart 表：title、legend=false/true/bottom/top/left/right、dataLabels=false/true/value/percent（percent 仅饼）、numberFormat、fontName 及 fontNameLatin/fontNameEa/fontNameCs、fontSize（默认 14pt）、color/lang/background。axisMin/axisMax/majorUnit 仅非饼；gapWidth 仅柱/条；marker 仅折线；firstSliceAngle/categoryColors 仅饼。
- 上限 1000 类别、32 系列、10000 数值槽位；数值须有限且在 ±1e100，字符串/false 不充当数值。拒绝未知参数；不支持堆叠、组合、次轴、3D、日期轴、公式、外链及图表元素动画。整图可用普通形状动画，不支持旋转/翻转/阴影/超链接/圆角。
- 原生 reader 不读取图表语义，也没有 getChartData/setChartData；copySlide 可独立复制支持的图表和工作簿。复杂图表或已有图表数据修改可按需用 COM，不必受原生创建子集限制。

### 生成前预检

- 在准备好 slides/options 后、写文件前调用 `fsys.openXml.pptx.builder.check(slides,options)`（或 `pp.checkPptx`）。不启动 Office、不写文件；输入不合法返回 `null,err`，有效报告仍需检查 `report.ok/report.issues`。
- 报告含 ok/issues/counts/errors/warnings/missingFonts；issues 每项含 code/severity/message/slide/shape。code：`overflow` 文字溢出、`tableGrow` 表格可能撑高、`offSlide` 超出页面、`overlap` 两个含文字的形状重叠。文字叠在卡片/图片上不按同类冲突报告。
- 有意重叠可设形状 `checkIgnore=true` 或 `["overlap"]`。offSlide 考虑旋转、表格增高和保守阴影边界；跨行合并不保证应用逐行增高的分配一致。
- 这是保守估算，不是排版引擎或跨应用一致性保证；不测量图表内部轴标签、图例、数据标签。需要确认最终视觉、动画或视频播放时，再用目标 Office/WPS 渲染/放映；结构检查通过不等于播放验收。

## 原生有限编辑

```aardio
import fsys.openXml.pptx.editor;
var doc,err=fsys.openXml.pptx.editor.open("/input.pptx");
if(!doc) return null,err;
var count,err=doc.replaceText("{{Name}}","新名称",{includeNotes=true});
if(count===null){doc.close();return null,err;}
var path,err=doc.save("/edited.pptx");
doc.close();
if(!path) return null,err;
return {path=path;count=count};
```

- `listSlides/listShapes` 按真实页序定位形状 id/名称。文本替换可跨同段相邻运行，继承首命中运行格式；不跨段落、域、软换行。返回次数 **0 合法，失败用 `===null` 判断**。
- `reorderSlides` 要求完整页号排列。`replaceImage(page,idOrName,pathOrData)` 替换同类型 PNG/JPEG 部件，共享该部件的其他图片也会改变，不静默克隆。
- `setAnimations(page,effects,true)` / `setTransition(page,options,true)` 的第三参 true 表示明确完整替换，不合并未知时间轴；默认拒绝已有内容。仅 Transitional 可写动画/切换，复用 builder 的动画实现。
- 默认另存、不覆盖，保护源文件及可识别硬链接别名；未修改部件的解压字节保持，ZIP 容器/元数据可变。拒绝包数字签名，不执行宏；对象限当前线程，必须 close。

### 模板与数据

- **复制页**：`doc.copySlide(page,insertAt)`，默认紧接原页；insertAt 是复制后的 1-based 位置。返回 `{index,id,partName,relationshipId}`。新页、备注、图片及支持的常见图表/内嵌工作簿独立克隆，版式/母版共享。自链接转向副本，其余跳页仍指原目标；未知依赖拒绝，不支持跨文稿导入。
- **删除页**：`doc.deleteSlide(page,options)` / `doc.deleteSlides([1,3],options)`，页号按本次调用开始时的页序，返回删除数（0 合法）。默认拒绝其他页入站链接；显式 `{links="remove"}` 才清理支持的点击/悬停链接，未知引用仍拒绝。同步维护支持的节/自定义放映/大纲引用，拒绝使自定义放映变空。不会清理全部孤儿媒体/图表，**不是敏感数据擦除工具**。
- **读表格**：`doc.getTable(page,target)`，target 为形状 id 或唯一名称；返回 rows/merges/rowCount/columnCount/rowHeights/columnWidths，rows 保留物理网格覆盖位置，尺寸为 point。
- **填表格**：`doc.setTableCells(page,target,values,{row=1;column=1})` 或 `doc.setTableCell(page,target,row,column,value)`。保持样式/尺寸，继承首段/首运行格式，新文字替换旧域和文字链接；null 跳过、空串清空、0/false 保留，支持 CR/LF/VT/TAB。合并覆盖格只允许空占位。返回写入逻辑格数，失败 `null,err`。
- **合并单元格**：`doc.mergeTableCells(page,target,{row,column,rowSpan,colSpan},options)`。默认拒绝覆盖非空格；`{content="append"}` 按行优先追加段落，保留格式。不能重叠已有合并，不拆分、不增删行列、不自动缩字。
- 每次结构操作原子提交，失败不留半页/半表；多次调用不是整批事务。editor 保留未改属性，不自动修复旧文件的排版；不重算页码缓存、缩略图或应用统计。

## 原生读取与媒体抽取

```aardio
import fsys.openXml.pptx;
var data,err = fsys.openXml.pptx.read("/input.pptx",{includeNotes=true});
if(!data) return null,err;
for i,text in data.slides {
    print("第 " + i + " 页：",text,data.notes[i]);
}
for i,w in data.warnings { print(w.partName,w.message); }
return data;
```

```aardio
import fsys.openXml.pptx;
var media,err = fsys.openXml.pptx.listMedia("/input.pptx");
if(!media) return null,err;
var result,err,partial = fsys.openXml.pptx.extractMedia("/input.pptx","/media",{overwrite=false});
if(!result) return null,err,partial;
return result; // files 为本次成功项，skipped 为已存在的跳过项
```

- 读取不需 Office/WPS，使用系统 MSXML 与 ZIP 库。页序取主文档列表，不按文件名编号；包含隐藏和空白页。`notes` 逐页对齐，无备注用空串；`noteCount` 为实际含备注部件的页数。
- 支持普通文本、分组、基本表格，保留段落/换行/TAB；按 XML 形状树顺序，不承诺视觉阅读顺序。不读取母版继承文字，不做 OCR、图表/SmartArt 语义或渲染；留意 warnings。
- `listEntries(path,pattern,options)` 列实际 ZIP 条目（含目录），pattern 为 aardio 模式串。媒体限定 `ppt/media/` 与主部件同级 media 目录及子目录，包含未引用资源；不做逐页引用映射或任意路径发现，不下载外链、不执行媒体。
- 媒体按末级文件名平铺导出原字节；同名冲突预先报错，非法文件名拒绝。`extractMedia` 默认不覆盖。CRC、长度、限额或写入失败返回 `null,err,partial`；此前成功文件保留，不是整批事务。
- 默认单部件 16 MiB、累计 128 MiB；大媒体可显式调高 `options.maxPartBytes/maxReadBytes`，最高 128 MiB / 1 GiB。一次在内存容纳一个部件，不是无限流式导出。所有入口自动释放读取句柄；列出条目/媒体不代表校验过全部内容。空结果与失败须区分。

## 按需使用 Office/WPS COM

```aardio
import autos.skills.powerPoint;
var pp = autos.skills.powerPoint;
```

### 入口与生命周期

- `pp.getApp(startIfMissing=false,visible=true)` 底层调用 `com.powerPoint(startIfMissing)`，按 PowerPoint.Application、WPP.Application、KWPP.Application 尝试连接；true 允许找不到时创建。visible=false 表示不主动显示，不强制隐藏用户实例。
- 返回 **com.powerPoint 透明代理**，可直接用 `ppt.Presentations.Open(...)`、`ppt.Visible` 等原生 Application 方法/属性；底层 COM 接口需通过 `.Application` 或 `.oPowerPoint` 取得。Presentation/Slide/Shape 子对象保持原生 COM 对象。
- **帮助函数和智能提示不是 API 白名单**：复用已有 VBA/PowerPoint 对象模型知识，直接写 aardio 点号调用。不必为每个方法造封装。WPS 方法覆盖由实际应用决定，不能因文稿显示正常就断言支持全部 Office COM API。
- 默认复用应用，保留打开/创建返回的 Presentation，勿依赖 ActivePresentation（无窗口文稿尤其如此）。只保存、关闭本任务文稿；用户原本打开的文稿按任务需要保留。代理 `Release()/Close()` 只断开代理引用；文稿 `pres.Close()` 关闭文稿，**两者不是同一个操作**。
- 默认不 Quit。ROT、Visible、创建成功、文稿数为零都不证明独占；不要为退出共享应用而探查/强杀进程。需要释放时清除自己持有的引用，必要时 `collectgarbage("collect")`。
- `pp.startApp(visible=false)` / `pp.quitApp(app,owned,timeout=15000)` 是显式独立验收的可选入口，**不是渲染/导出的必经步骤**。startApp 返回原生 Application 和归属记录，已有 PowerPoint 进程则拒绝；quitApp 仅在记录有效且无文稿时尝试 Quit，再等自然退出，不强杀。调用方仍须确认允许退出整个应用。
- `com.powerPoint` 构造时已有特定挂起错误对话框的兼容处理；技能层不要重复点击、禁用加载项或提升权限。若应用退出异常影响任务，交由用户处理，不把某一机器的加载项问题当作通用生命周期规则。

### 创建文稿与导出

COM 同样可以直接制作页面，不限于补齐原生能力。此例保留文稿供继续编辑：

```aardio
import autos.skills.powerPoint;
var pp = autos.skills.powerPoint;
var pres,err = pp.createPresentation(true,true);
if(!pres) return null,err;
pp.addTitleSlide(pres,"自动生成的演示文稿","created by aardio Autos");
var slide,err = pp.addBlankSlide(pres);
if(!slide) return null,err;
pp.addTextBox(slide,'这里是正文要点\r\n- 第一条\r\n- 第二条',80,80,600,180,{
    fontName="Microsoft YaHei";fontSize=22;
    color=0x000000;lineVisible=false;
});
var path,err = pp.saveAs(pres,"/demo.pptx","pptx",false);
if(!path) return null,err;
return path;
```

导出已有文稿；原生生成的 PPTX 也可这样交给应用渲染：

```aardio
import autos.skills.powerPoint;
var pp = autos.skills.powerPoint;
var pres,err = pp.openPresentation("/input.pptx",true,false,true);
if(!pres) return null,err;
var dir,err = pp.exportSlidesAsImages(pres,"/slides","png",1920,1080);
// 也可用 pp.exportAsPdf(pres,"/output.pdf",false)。
pp.closePresentation(pres,false);
pres = null;
if(!dir) return null,err;
return dir;
```

- COM 几何/字号为 point；图片导出的宽高为像素。`Font.Color.RGB / Fill.ForeColor.RGB` 为 `0xBBGGRR`（红色 0x0000FF、蓝色 0xFF0000），不要照抄原生颜色字符串。
- `pp.saveAs/exportAsPdf` 默认允许覆盖；需要保护已有目标时显式传 overwrite=false。图片导出使用独立目录，避免与用户现有文件混放。
- COM 修改 `ChartData.Workbook` 后，保存工作簿不等于刷新图表缓存；在关闭前先 Calculate/Chart.Refresh 并处理消息，再保存文稿。需要保证结果时保存重开确认。
- COM 验证使用可返回结果的后台线程，不用拿不到错误的独立子进程；按需验证样本，不把启动 Office 或全面回归当成每次任务的前置条件。

### 嵌入 MP4（不链接，随文稿保存）

在已取得的 `pres`、目标页 `slide` 和技能别名 `pp` 上直接调用；导入时 `/clip.mp4` 必须是存在的本地文件：

```aardio
var video = slide.Shapes.AddMediaObject2(
    io.fullpath("/clip.mp4"),
    0/*LinkToFile: msoFalse*/, -1/*SaveWithDocument: msoTrue*/,
    60,100,640,360
);
var path,err = pp.saveAs(pres,"/with-video.pptx","pptx",false);
if(!path) return null,err;
return path;
```

- 明确指定 `LinkToFile=0`、`SaveWithDocument=-1`，不要依赖媒体默认值。保存成功后视频嵌入文稿，分发 PPTX 不需要附带原 MP4 文件。
- **方法名为 `AddMediaObject2`**，其返回值是 Shape；旧 `AddMediaObject` 没有这两个链接/保存参数，不能把上述参数原样移过去。签名依据 Microsoft Learn 的 Shapes.AddMediaObject2 文档。
- WPS/旧 Office 的接口及媒体解码能力需按实际环境确认；不支持时明确报错或请用户在应用中插入，不静默退化成外链。嵌入成功不等于已验证播放；目标机器仍需支持视频编码。
- 此功能走 COM；原生 `fsys.openXml` 暂不提供 MP4 嵌入接口。

## 技能帮助函数速查

原生函数仅转发共享基础库，按需加载：

- `pp.writePptx(path,slides,options)` → builder.write。
- `pp.checkPptx(slides,options,checkOptions)` → builder.check。
- `pp.editPptx(path,options)` → pptx.editor.open，返回须 close 的编辑会话。

COM 便捷入口（以下函数均在 pp 下，原生对象模型可直接继续使用）：

- `getApp(startIfMissing=false,visible=true)`；`isRunning()`；`getAppInfo(startIfMissing=false)` 返回 name/version/presentations/activePresentation。
- `createPresentation(startIfMissing=true,visible=true)`；`openPresentation(path,startIfMissing=true,withWindow=true,readOnly=false)`；`getActivePresentation(startIfMissing=false)`。
- `getPresentationInfo(pres)` / `getActivePresentationInfo(startIfMissing=false)` 返回 name/fullName/path/slideCount/saved。
- `addBlankSlide(pres,index)`；`addTitleSlide(pres,title,subtitle,index)`；`addTextBox(slide,text,left,top,width,height,options)`，options 支持 fontName/fontSize/bold/italic/color/align/fillColor/lineColor/lineVisible。
- `saveAs(pres,path,format,overwrite=true)`，format 可为 pptx/pptm/ppsx/ppt/pdf/png/jpg 或格式常量。
- `exportAsPdf(pres,path,overwrite=true)`：优先 ExportAsFixedFormat，失败尝试 SaveAs。
- `exportSlidesAsImages(pres,dir,format="png",width=0,height=0)`；`closePresentation(pres,saveChanges=false)`，true 表示先保存再关闭，false 不先调用 Save。
- `startApp(visible=false)` / `quitApp(app,owned,timeout=15000)`，使用条件见生命周期段落。

兼容抽取入口仍可使用，但新代码宜直接调用 pptx 库：

- `pp.listPptxEntries(path,pattern,options)` → listEntries，含 path/isDir/size/formattedSize 等。
- `pp.extractTextFromPptx(path,includeNotes=true,options)` → read，包含逐页正文、备注、pages/warnings。
- `pp.listPptxMedia(path,options)` → listMedia，含 path/name/ext/size/isDir/formattedSize/partName/contentType/compressedSize。
- `pp.extractPptxMedia(path,outputDir,overwrite=true,options)` → extractMedia，但返回本次成功文件数组；失败第三返回值为 partial。**此兼容入口默认覆盖，基础库 extractMedia 默认不覆盖**；建议显式 false。
- options 可设包层读取限额；兼容入口的 includeNotes/overwrite 实参（含默认值）优先于 options 同名字段，不修改传入的 options 表。

常用常量均在 pp 下：msoFalse=0、msoTrue=-1、msoTextOrientationHorizontal=1、ppLayoutBlank=12、ppSaveAsOpenXMLPresentation=24、ppSaveAsPDF=32、ppFixedFormatTypePDF=2、ppAlignLeft/Center/Right=1/2/3。

## 范例与深入入口

按目标查相应范例，不必全读：

| 任务 | 范例（位于 `~/examples/File/OpenXML/`） |
| --- | --- |
| 图文、渐变、表格与排版 | `pptx-design.aardio`；其中形状柱条不等于原生 chart |
| 逐段落、Morph、标题/两栏版式 | `pptx-show.aardio` |
| 页码、链接、编号、圆角/阴影 | `pptx-details.aardio` |
| 复制、删除、填表与合并 | `pptx-data.aardio` |
| 四种二维图表及 0/null 空点 | `pptx-charts.aardio` |

详细参数与边界按需读 `~/docs/library/fsys/openXml/pptx/` 下的 `builder/index.md`、`builder/details.md`、`editor/index.md`、`editor/data.md`、`chart/index.md`；COM 代理指南为 `~/docs/library/com/powerPoint/index.md`。库参考可用 lookup_library_reference；智能提示不是 COM API 限制。

## 默认工作流

1. 明确新建/编辑/抽取/导出需求、源件保护及目标应用；优先选择简单可靠的原生路线，COM 更方便或能力需要时直接用或混用。
2. 原生生成先准备 slides/options，按需预检并处理问题后写入；原生编辑在独立会话完成，另存并 close。不要为了纯读取或生成而无故启动 Office。
3. 需要 COM 时用 getApp/openPresentation 连接或按需创建，保存返回的文稿对象；不默认要求独占实例，不干扰用户其他文稿。
4. 区分失败、空结果和 0；处理 err/warnings/partial。只做任务需要的验证：存在/结构、关键数据、渲染或实际播放各有不同用途。
5. 交付说明输出位置与必要边界；只清理本任务资源，不 Quit 共享应用，不未经允许覆盖源件。
