# 调用示例

以下均直接调用 SDK，不经过 Office/WPS。文件示例中的 `/example.xlsx`、`/example.pptx` 需替换为实际输入；确定性内存示例可直接运行。外部输入的完整错误边界见[结构验证](validation.html)。

## DOCX：内存创建、保存、重新打开

```aardio
import DocumentFormat.OpenXml;
var ox = DocumentFormat.OpenXml;
var stream = System.IO.MemoryStream();
var doc = ox.Packaging.WordprocessingDocument.Create(stream);
var part = doc.AddMainDocumentPart();

var root = ox.Wordprocessing.Document();
var body = ox.Wordprocessing.Body();
var paragraph = ox.Wordprocessing.Paragraph();
var run = ox.Wordprocessing.Run();
run.Append([ox.Wordprocessing.Text("Hello, Open XML!")]);
paragraph.Append([run]);
body.Append([paragraph]);
root.Append([body]);
part.Document = root;

doc.Dispose(); // 默认 AutoSave=true；完成包写入，但不释放调用方的流
stream.Position = 0;
var reopened = ox.Packaging.WordprocessingDocument.Open(stream);
var text = reopened.MainDocumentPart.Document.Body.InnerText;
reopened.Dispose();
stream.Dispose();
return text;
```

创建到文件只需将 `Create` 首参换为输出路径，并去掉流重开部分。该入口会覆盖已有文件；模板编辑应先复制文件，再对副本 `Open(path,true)`。

## XLSX：按工作簿顺序解析工作表关系

```aardio
import DocumentFormat.OpenXml;
var doc = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open("/example.xlsx");
var ok,rows = call(function(){
    var workbookPart = doc.WorkbookPart;
    var sheets = workbookPart.Workbook.Sheets;
    var result = [];
    if(sheets) for i,sheet in dotNet.each(sheets.ChildElements) {
        var relationshipId = sheet.Id.Value;
        var part = workbookPart.GetPartById(relationshipId);
        table.push(result,{
            name = sheet.Name.Value;
            sheetId = sheet.SheetId.Value;
            relationshipId = relationshipId;
            part = tostring(part.Uri);
        });
    }
    return result;
},null);
doc.Dispose();
if(!ok) return null,rows;
return rows;
```

`SheetId`、关系 ID 和工作表在集合中的位置不是同一概念。根据关系获取的部件还可能是图表工作表等类型，不能一概当作 `WorksheetPart`。

读取单元格时应区分共享字符串、内联字符串、布尔值、数值及公式缓存；日期还涉及样式与日期系统。`CellValue.Text` 不是通用的最终显示值。本页不封装整套 Excel 解释器或公式计算器。

## PPTX：按演示顺序读取幻灯片的原始文本

```aardio
import DocumentFormat.OpenXml;
var doc = DocumentFormat.OpenXml.Packaging.PresentationDocument.Open("/example.pptx");
var ok,rows = call(function(){
    var presentationPart = doc.PresentationPart;
    var slideIds = presentationPart.Presentation.SlideIdList;
    var result = [];
    if(slideIds) for i,slideId in dotNet.each(slideIds.ChildElements) {
        var slidePart = presentationPart.GetPartById(slideId.RelationshipId.Value);
        table.push(result,{
            id = slideId.Id.Value;
            text = slidePart.Slide.InnerText;
        });
    }
    return result;
},null);
doc.Dispose();
if(!ok) return null,rows;
return rows;
```

使用 `SlideIdList` 决定顺序，不依赖 `SlideParts` 的枚举顺序。`InnerText` 不保留形状或段落边界，不包含图片 OCR、备注部件，也不等于视觉阅读顺序。

## 更多 API

需要筛选后代元素、添加部件或处理类型化值时，先看 [.NET 互操作](interop.html)。具体文档格式的完整 API 直接查 [微软 Open XML 文档](https://learn.microsoft.com/office/open-xml/open-xml-sdk)，不在本库参考中重复罗列。
