Table of Contents

Class PresentationEditor

Namespace
DocToolkit
Assembly
DocToolkit.Pptx.dll

Opens and edits PowerPoint (.pptx) presentations.

public static class PresentationEditor
Inheritance
PresentationEditor
Inherited Members

Methods

AddChart(byte[], int, ChartType, ChartData, string, double, double, double, double)

Adds a chart to slide slideIndex and returns the updated presentation.

public static byte[] AddChart(byte[] pptx, int slideIndex, ChartType type, ChartData data, string title = "", double leftPoints = 0, double topPoints = 0, double widthPoints = 432, double heightPoints = 252)

Parameters

pptx byte[]

The presentation to add the chart to. It is not modified.

slideIndex int

1-based, because that is how a reader numbers slides.

type ChartType

The chart's shape.

data ChartData

The chart's categories and value series.

title string

The chart's title. Empty for no title.

leftPoints double

The chart's left edge, in points from the slide's left edge.

topPoints double

The chart's top edge, in points from the slide's top edge.

widthPoints double

The chart's width, in points.

heightPoints double

The chart's height, in points.

Returns

byte[]

Exceptions

ArgumentNullException

pptx or data is null.

ArgumentException

pptx is empty.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

DocumentConversionException

The package could not be opened or edited.

AddChartAsync(Stream, int, ChartType, ChartData, string, double, double, double, double, CancellationToken)

Reads a .pptx from source and returns a new presentation with a chart added to slide slideIndex — see AddChart(byte[], int, ChartType, ChartData, string, double, double, double, double) for the parameters. source is read to its end and is neither disposed, closed nor sought.

public static Task<byte[]> AddChartAsync(Stream source, int slideIndex, ChartType type, ChartData data, string title = "", double leftPoints = 0, double topPoints = 0, double widthPoints = 432, double heightPoints = 252, CancellationToken ct = default)

Parameters

source Stream
slideIndex int
type ChartType
data ChartData
title string
leftPoints double
topPoints double
widthPoints double
heightPoints double
ct CancellationToken

Returns

Task<byte[]>

Exceptions

ArgumentNullException

source or data is null.

ArgumentException

source is not readable or held no bytes.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

AddChartAsync(string, int, ChartType, ChartData, string, double, double, double, double, CancellationToken)

Reads a .pptx from path and returns a new presentation with a chart added to slide slideIndex — see AddChart(byte[], int, ChartType, ChartData, string, double, double, double, double) for the parameters.

public static Task<byte[]> AddChartAsync(string path, int slideIndex, ChartType type, ChartData data, string title = "", double leftPoints = 0, double topPoints = 0, double widthPoints = 432, double heightPoints = 252, CancellationToken ct = default)

Parameters

path string

The .pptx to read.

slideIndex int

1-based, because that is how a reader numbers slides.

type ChartType

The chart's shape.

data ChartData

The chart's categories and value series.

title string

The chart's title. Empty for no title.

leftPoints double

The chart's left edge, in points from the slide's left edge.

topPoints double

The chart's top edge, in points from the slide's top edge.

widthPoints double

The chart's width, in points.

heightPoints double

The chart's height, in points.

ct CancellationToken

Cancels the read.

Returns

Task<byte[]>

Exceptions

ArgumentNullException

path or data is null.

ArgumentException

path is blank, or the file it names is empty.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

FileNotFoundException

path does not exist.

DirectoryNotFoundException

path's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

Create(IEnumerable<PptxSlide>)

Creates a deck from slides, one slide each.

This exists for content that comes from data rather than from an existing file: there is no template to edit, so ReplaceText(byte[], IReadOnlyDictionary<string, string>) cannot help, and the same slides produce the same CONTENT on every machine — nothing here consults the current culture. Not the same BYTES: the OpenXml SDK mints fresh relationship ids per package, so two calls with identical slides in the same process differ. Do not build a cache key, a content hash or a golden-file test on the bytes.

An empty sequence is valid and produces a valid deck with no slides.

public static byte[] Create(IEnumerable<PptxSlide> slides)

Parameters

slides IEnumerable<PptxSlide>

The slides, in deck order.

Returns

byte[]

Examples

byte[] pptx = PresentationEditor.Create(new[]
{
    PptxSlide.Titled("Quarterly Report", "Revenue up 12%"),
    PptxSlide.Titled("Outlook", "Hiring 3 engineers"),
});

Exceptions

ArgumentNullException

slides is null.

ArgumentException

An element of slides is null.

DocumentConversionException

The deck could not be built.

CreateAsync(IEnumerable<PptxSlide>, Stream, CancellationToken)

Builds a deck from slides and writes it to destination. See Create(IEnumerable<PptxSlide>) for the slide semantics.

destination is written, from its current position, and is not disposed, closed or sought — it belongs to the caller, and may be write-only and forward-only, such as an HTTP response body.

public static Task CreateAsync(IEnumerable<PptxSlide> slides, Stream destination, CancellationToken ct = default)

Parameters

slides IEnumerable<PptxSlide>

The slides, in deck order.

destination Stream

The stream the deck is written to.

ct CancellationToken

Cancels the build and the write to destination.

Returns

Task

Exceptions

ArgumentNullException

slides or destination is null.

ArgumentException

An element of slides is null, or destination is not writable.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The deck could not be built or written.

CreateToFileAsync(IEnumerable<PptxSlide>, string, CancellationToken)

Builds a deck from slides and writes it to outputPath. See Create(IEnumerable<PptxSlide>) for the slide semantics.

Named CreateToFileAsync rather than a third CreateAsync overload, matching WorkbookEditor.CreateToFileAsync: the distinct name keeps which kind of destination a call writes to visible at the call site, rather than resting on the argument type alone.

The deck is built completely before the output is opened. That ordering is what stops a failed build truncating a file that was already there, and it is pinned by FilePathOverloadTests rather than left as a comment — it survives only as long as nobody rewrites this into a streaming write.

public static Task CreateToFileAsync(IEnumerable<PptxSlide> slides, string outputPath, CancellationToken ct = default)

Parameters

slides IEnumerable<PptxSlide>

The slides, in deck order.

outputPath string

Where to write the deck. Overwritten if it exists.

ct CancellationToken

Cancels the write to outputPath.

Returns

Task

Exceptions

ArgumentNullException

slides or outputPath is null.

ArgumentException

outputPath is blank, or an element of slides is null.

DirectoryNotFoundException

outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The deck could not be built.

ExtractText(byte[])

All text found on every slide, one entry per text-bearing body, in the order the deck is presented rather than the order the slide parts happen to be related.

A "text-bearing body" is any element holding <a:p> paragraphs: an ordinary shape's <p:txBody>, a shape nested in a group, and a table cell's <a:txBody> alike. Paragraphs within one body are joined with newlines. This is deliberately the same walk ReplaceText(byte[], IReadOnlyDictionary<string, string>) performs, so anything this reports is something that can be replaced and vice versa. Speaker notes and slide masters/layouts are not included.

Each slide's SmartArt diagrams follow that slide's own text-bearing bodies, one entry per diagram — see ReadSmartArt(byte[], int). A SmartArt diagram's text lives in a diagram data part, not a <p:txBody>, so it is not itself a text-bearing body and was invisible here before this was added; it is not something ReplaceText(byte[], IReadOnlyDictionary<string, string>) can reach.

public static IReadOnlyList<string> ExtractText(byte[] pptx)

Parameters

pptx byte[]

Returns

IReadOnlyList<string>

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

DocumentConversionException

The package could not be opened or read.

ExtractTextAsync(Stream, CancellationToken)

Reads a .pptx from source and returns all text found on every slide, one entry per text-bearing body, in deck order — see ExtractText(byte[]) for exactly what counts as a text-bearing body. source is read to its end and is neither disposed, closed nor sought.

public static Task<IReadOnlyList<string>> ExtractTextAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream
ct CancellationToken

Returns

Task<IReadOnlyList<string>>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

ExtractTextAsync(string, CancellationToken)

Reads a .pptx from path and returns all text found on every slide, one entry per text-bearing body, in deck order — see ExtractText(byte[]) for exactly what counts as a text-bearing body.

public static Task<IReadOnlyList<string>> ExtractTextAsync(string path, CancellationToken ct = default)

Parameters

path string

The .pptx to read.

ct CancellationToken

Cancels the read.

Returns

Task<IReadOnlyList<string>>

One entry per text-bearing body, in deck order.

Exceptions

ArgumentNullException

path is null.

ArgumentException

path is blank, or the file it names is empty.

FileNotFoundException

path does not exist.

DirectoryNotFoundException

path's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

InsertSlides(byte[], int, IEnumerable<PptxSlide>)

A copy of pptx with slides inserted so that the first of them becomes slide atIndex. See Create(IEnumerable<PptxSlide>) for what a PptxSlide becomes.

Each inserted slide attaches to the layout of the slide immediately before the insertion point — or, when inserting at position 1 of a non-empty deck, the layout of what is currently the first slide — so it renders consistently with its neighbours rather than requiring a caller to name one. A deck with no slides at all falls back to its first slide master's first layout.

The inserted slide's title and body boxes inherit the target layout's own placeholder position only when that layout positions that placeholder itself — it has a placeholder of the matching role (same type, and for the body, the same index), and that placeholder carries its own position and size, and it is one of the layout's own TOP-LEVEL shapes: a placeholder nested inside a group (p:grpSp) on the layout does not count, matching role and complete geometry notwithstanding. A hand-designed deck's own title/body geometry is then honoured rather than overridden.

Otherwise the shape keeps this library's own fixed coordinates, rescaled to fit the target deck's canvas size. That covers four distinct cases, and the first two are common: a layout with no placeholder of that role at all (an ordinary "Title Slide" layout uses ctrTitle/subTitle), a layout that names the role but leaves its geometry to the slide master (a stock "Title and Content" layout usually does), a layout whose placeholder carries only part of a box (a position with no size, or a size with no position), and a layout that positions the role's placeholder only inside a group. Inheriting in any of these would leave content schema-valid but with no box this library's render pipeline (which resolves a slide's inherited geometry from the layout's TOP-LEVEL shape tree only — never from inside a group, and never by resolving layout → master) could actually draw in — invisible in a render. That is why the fallback exists: it keeps content visible, positioned by this library's own choice, at the cost of not matching a hand-designed layout's own intended position in these cases.

public static byte[] InsertSlides(byte[] pptx, int atIndex, IEnumerable<PptxSlide> slides)

Parameters

pptx byte[]

The presentation to insert into. It is not modified.

atIndex int

1-based position the first inserted slide will occupy. 1 puts them in front of everything; SlideCount + 1 appends, which is deliberately allowed — it is the obvious way to say "after everything".

slides IEnumerable<PptxSlide>

The slides to insert, in order.

Returns

byte[]

Exceptions

ArgumentNullException

pptx or slides is null.

ArgumentException

pptx is empty, or an element of slides is null.

ArgumentOutOfRangeException

atIndex is below 1 or more than one past the last slide.

DocumentConversionException

The package could not be opened or edited, or the slide the new content would attach to has no layout of its own.

InsertSlidesAsync(Stream, int, IEnumerable<PptxSlide>, Stream, CancellationToken)

Reads a .pptx from source, inserts slides at atIndex, and writes the result to destination — see InsertSlides(byte[], int, IEnumerable<PptxSlide>) for the insertion and layout rules.

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

public static Task InsertSlidesAsync(Stream source, int atIndex, IEnumerable<PptxSlide> slides, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the .pptx package is read from.

atIndex int

1-based insertion position; SlideCount + 1 appends.

slides IEnumerable<PptxSlide>

The slides to insert, in order.

destination Stream

The stream the edited .pptx package is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

source is not readable or held no bytes, destination is not writable, or an element of slides is null.

ArgumentOutOfRangeException

atIndex is below 1 or more than one past the last slide.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited, or the slide the new content would attach to has no layout of its own.

InsertSlidesAsync(string, string, int, IEnumerable<PptxSlide>, CancellationToken)

Reads a .pptx from inputPath, inserts slides at atIndex, and writes the result to outputPath — see InsertSlides(byte[], int, IEnumerable<PptxSlide>) for the insertion and layout rules. The two paths may be the same file: the updated bytes are computed in full before outputPath is opened.

public static Task InsertSlidesAsync(string inputPath, string outputPath, int atIndex, IEnumerable<PptxSlide> slides, CancellationToken ct = default)

Parameters

inputPath string

The .pptx to read.

outputPath string

Where to write the result. Overwritten if it exists.

atIndex int

1-based insertion position; SlideCount + 1 appends.

slides IEnumerable<PptxSlide>

The slides to insert, in order.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Exceptions

ArgumentNullException

A path or slides is null.

ArgumentException

A path is blank, the file at inputPath is empty, or an element of slides is null.

ArgumentOutOfRangeException

atIndex is below 1 or more than one past the last slide.

FileNotFoundException

inputPath does not exist.

DirectoryNotFoundException

inputPath's or outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited, or the slide the new content would attach to has no layout of its own.

InspectSignatures(byte[])

Inspects pptx for digital signatures — whether it carries one, how many, and who claims to have signed it. Does not validate anything cryptographically; see ValidateSignatures(byte[], DocumentSignatureValidationOptions?).

public static DocumentSignatureInfo InspectSignatures(byte[] pptx)

Parameters

pptx byte[]

Returns

DocumentSignatureInfo

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

DocumentConversionException

The presentation could not be inspected.

InspectSignaturesAsync(Stream, CancellationToken)

Reads a .pptx from source and inspects it for digital signatures — see InspectSignatures(byte[]). source is read to its end and is neither disposed, closed nor sought.

public static Task<DocumentSignatureInfo> InspectSignaturesAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream
ct CancellationToken

Returns

Task<DocumentSignatureInfo>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The presentation could not be inspected.

IsProtected(byte[])

Whether pptx is an ENCRYPTED Office document.

public static bool IsProtected(byte[] pptx)

Parameters

pptx byte[]

The bytes to inspect.

Returns

bool

Remarks

This is not a validity check, and a false is not a promise that anything else will succeed. It distinguishes an encrypted document from a plain one; input that is neither — an image, a PDF, a text file, random bytes — is not encrypted, so this answers false for it, while every other method on this class refuses it. Measured over real files: a JPEG and a PDF both return false here and both throw from ExtractText.

The summary used to say "that is, whether the other methods on this class will refuse it". That reads as a guard — test it, and if false, proceed — and takes the wrong branch for every input that is not a document at all. The behaviour was always right and only the sentence was wrong, which is why the fix is here and not in the code.

Reads the file signature; it does not try the password and does not need one. A plain PPTX is a ZIP package, an encrypted one is a compound file, and the two are distinguishable from their first eight bytes.

Exceptions

ArgumentNullException

pptx is null.

IsProtectedAsync(Stream, CancellationToken)

Whether pptx is an ENCRYPTED Office document.

public static Task<bool> IsProtectedAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

ct CancellationToken

Cancels the read.

Returns

Task<bool>

Remarks

source is read to its end and is neither disposed, closed nor sought. Unlike IsProtected(byte[]), which answers false for an empty array, an empty source is rejected — every Stream overload in this package treats a source that held no bytes as a caller error rather than as content.

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

Protect(byte[], string)

A copy of pptx encrypted with password, so it cannot be opened without one.

public static byte[] Protect(byte[] pptx, string password)

Parameters

pptx byte[]

The presentation to encrypt.

password string

The password required to open the result. May not be empty.

Returns

byte[]

Remarks

This is file encryption, not presentation protection. Office offers both under the same menu and they are not the same thing: this scrambles the whole file, so nothing can be read without the password. The other kind - a flag asking a reader not to edit - is a request rather than a lock, and is deliberately not exposed here.

The result is not a PPTX package any more. An encrypted Office document is a compound file with the package sealed inside it, so every other method on this class refuses it - call Unprotect(byte[], string) first. That refusal is the honest behaviour: those methods could not read the content even if they tried.

Exceptions

ArgumentNullException

pptx or password is null.

ArgumentException

pptx is empty, or password is empty.

DocumentConversionException

The presentation could not be read or encrypted.

ProtectAsync(Stream, Stream, string, CancellationToken)

Reads a presentation from source and writes the encrypted copy to destination.

Neither stream is disposed, closed or sought.

public static Task ProtectAsync(Stream source, Stream destination, string password, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

destination Stream

The stream the encrypted presentation is written to.

password string

The password required to open the result. May not be empty.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Remarks

This is file encryption, not presentation protection. Office offers both under the same menu and they are not the same thing: this scrambles the whole file, so nothing can be read without the password. The other kind - a flag asking a reader not to edit - is a request rather than a lock, and is deliberately not exposed here.

The result is not a PPTX package any more. An encrypted Office document is a compound file with the package sealed inside it, so every other method on this class refuses it - call Unprotect(byte[], string) first. That refusal is the honest behaviour: those methods could not read the content even if they tried.

ReadMetadata(byte[])

The document properties pptx carries.

public static DocumentMetadata ReadMetadata(byte[] pptx)

Parameters

pptx byte[]

Returns

DocumentMetadata

Remarks

On a freshly created deck every property is null, exactly like DOCX and XLSX — measured directly rather than assumed. That is not true of WithMetadata(byte[], DocumentMetadata); see its own remarks for why writing and reading disagree here.

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

DocumentConversionException

The presentation could not be read.

ReadMetadataAsync(Stream, CancellationToken)

The document properties pptx carries.

public static Task<DocumentMetadata> ReadMetadataAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

ct CancellationToken

Cancels the read.

Returns

Task<DocumentMetadata>

Remarks

source is read to its end and is neither disposed, closed nor sought.

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The presentation could not be read.

ReadNotes(byte[], int)

The speaker notes on slide slideIndex, or an empty string when it has none. slideIndex is 1-based, like ReadSlide(byte[], int).

public static string ReadNotes(byte[] pptx, int slideIndex)

Parameters

pptx byte[]

The presentation to read.

slideIndex int

The 1-based slide number.

Returns

string

Remarks

A slide with no notes returns Empty, never null. Measured rather than assumed: every slide carries a notes object whose text is empty until something writes to it, so there is no "has notes" state to distinguish from "notes are blank" and the API does not invent one.

Notes are not returned by ExtractText(byte[]), which reads the slide bodies. They are a separate surface a reader has to ask for.

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

DocumentConversionException

The package could not be opened or read.

ReadNotesAsync(Stream, int, CancellationToken)

The speaker notes on slide slideIndex, or an empty string when it has none. slideIndex is 1-based, like ReadSlide(byte[], int).

public static Task<string> ReadNotesAsync(Stream source, int slideIndex, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

slideIndex int

The 1-based slide number.

ct CancellationToken

Cancels the read.

Returns

Task<string>

Remarks

source is read to its end and is neither disposed, closed nor sought.

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

ReadSlide(byte[], int)

All text found on slide index — see ExtractText(byte[]) for exactly what counts as a text-bearing body. Same per-body granularity as that method, scoped to one slide.

public static IReadOnlyList<string> ReadSlide(byte[] pptx, int index)

Parameters

pptx byte[]

The presentation to read.

index int

1-based, because that is how a reader numbers slides.

Returns

IReadOnlyList<string>

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

DocumentConversionException

The package could not be opened or read.

ReadSlideAsync(Stream, int, CancellationToken)

Reads a .pptx from source and returns all text found on slide index — see ReadSlide(byte[], int) for exactly what counts as a text-bearing body. source is read to its end and is neither disposed, closed nor sought.

public static Task<IReadOnlyList<string>> ReadSlideAsync(Stream source, int index, CancellationToken ct = default)

Parameters

source Stream
index int
ct CancellationToken

Returns

Task<IReadOnlyList<string>>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

ReadSlideAsync(string, int, CancellationToken)

Reads a .pptx from path and returns all text found on slide index — see ReadSlide(byte[], int) for exactly what counts as a text-bearing body.

public static Task<IReadOnlyList<string>> ReadSlideAsync(string path, int index, CancellationToken ct = default)

Parameters

path string

The .pptx to read.

index int

1-based, because that is how a reader numbers slides.

ct CancellationToken

Cancels the read.

Returns

Task<IReadOnlyList<string>>

Exceptions

ArgumentNullException

path is null.

ArgumentException

path is blank, or the file it names is empty.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

FileNotFoundException

path does not exist.

DirectoryNotFoundException

path's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

ReadSmartArt(byte[], int)

The text of every SmartArt diagram on slide index, one entry per diagram, each diagram's nodes joined with newlines in the order OfficeIMO reports them.

A SmartArt diagram's text lives in a diagram data part, not a text-bearing shape body, so it is invisible to ReadSlide(byte[], int)ExtractText(byte[]) reports it too, alongside every ordinary text-bearing body, for exactly that reason.

An empty list means the slide has no SmartArt, which is not an error — the same convention ReadSlide(byte[], int) uses for a slide with no text-bearing shapes.

public static IReadOnlyList<string> ReadSmartArt(byte[] pptx, int index)

Parameters

pptx byte[]

The presentation to read.

index int

1-based, because that is how a reader numbers slides.

Returns

IReadOnlyList<string>

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

DocumentConversionException

The package could not be opened or read.

ReadSmartArtAsync(Stream, int, CancellationToken)

Reads a .pptx from source and returns the text of every SmartArt diagram on slide index — see ReadSmartArt(byte[], int). source is read to its end and is neither disposed, closed nor sought.

public static Task<IReadOnlyList<string>> ReadSmartArtAsync(Stream source, int index, CancellationToken ct = default)

Parameters

source Stream
index int
ct CancellationToken

Returns

Task<IReadOnlyList<string>>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

ReadSmartArtAsync(string, int, CancellationToken)

Reads a .pptx from path and returns the text of every SmartArt diagram on slide index — see ReadSmartArt(byte[], int).

public static Task<IReadOnlyList<string>> ReadSmartArtAsync(string path, int index, CancellationToken ct = default)

Parameters

path string

The .pptx to read.

index int

1-based, because that is how a reader numbers slides.

ct CancellationToken

Cancels the read.

Returns

Task<IReadOnlyList<string>>

Exceptions

ArgumentNullException

path is null.

ArgumentException

path is blank, or the file it names is empty.

ArgumentOutOfRangeException

index is below 1, or above the deck's slide count.

FileNotFoundException

path does not exist.

DirectoryNotFoundException

path's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

RemoveSlides(byte[], IEnumerable<int>)

A copy of pptx with the slides at indices removed.

public static byte[] RemoveSlides(byte[] pptx, IEnumerable<int> indices)

Parameters

pptx byte[]

The presentation to remove slides from. It is not modified.

indices IEnumerable<int>

1-based slide numbers to remove, each exactly once and in any order — not a contiguous range, so [2, 7] removes exactly those two slides in one call.

Returns

byte[]

Exceptions

ArgumentNullException

pptx or indices is null.

ArgumentException

pptx is empty, or indices contains a duplicate.

ArgumentOutOfRangeException

An index in indices is outside the deck's slide range, or removing every listed index would leave a zero-slide deck.

DocumentConversionException

The package could not be opened or edited.

RemoveSlidesAsync(Stream, IEnumerable<int>, Stream, CancellationToken)

Reads a .pptx from source, removes the slides at indices, and writes the result to destination — see RemoveSlides(byte[], IEnumerable<int>) for exactly what indices accepts.

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

public static Task RemoveSlidesAsync(Stream source, IEnumerable<int> indices, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the .pptx package is read from.

indices IEnumerable<int>

1-based slide numbers to remove, each exactly once, any order.

destination Stream

The stream the edited .pptx package is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

source is not readable or held no bytes, destination is not writable, or indices contains a duplicate.

ArgumentOutOfRangeException

An index in indices is outside the deck's slide range, or removing every listed index would leave a zero-slide deck.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

RemoveSlidesAsync(string, string, IEnumerable<int>, CancellationToken)

Reads a .pptx from inputPath, removes the slides at indices, and writes the result to outputPath — see RemoveSlides(byte[], IEnumerable<int>) for exactly what indices accepts. The two paths may be the same file: the updated bytes are computed in full before outputPath is opened.

public static Task RemoveSlidesAsync(string inputPath, string outputPath, IEnumerable<int> indices, CancellationToken ct = default)

Parameters

inputPath string

The .pptx to read.

outputPath string

Where to write the result. Overwritten if it exists.

indices IEnumerable<int>

1-based slide numbers to remove, each exactly once, any order.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Exceptions

ArgumentNullException

A path or indices is null.

ArgumentException

A path is blank, the file at inputPath is empty, or indices contains a duplicate.

ArgumentOutOfRangeException

An index in indices is outside the deck's slide range, or removing every listed index would leave a zero-slide deck.

FileNotFoundException

inputPath does not exist.

DirectoryNotFoundException

inputPath's or outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

ReorderSlides(byte[], IEnumerable<int>)

A copy of pptx with its slides in the order given by order, which holds 1-based slide numbers.

public static byte[] ReorderSlides(byte[] pptx, IEnumerable<int> order)

Parameters

pptx byte[]

The presentation to reorder. It is not modified.

order IEnumerable<int>

A permutation of every slide — the same slides, in a different order. Not a subset, and no repeats.

Returns

byte[]

Exceptions

ArgumentNullException

pptx or order is null.

ArgumentException

pptx is empty, or order is not a permutation of 1..SlideCount.

DocumentConversionException

The package could not be opened or edited.

ReorderSlidesAsync(Stream, IEnumerable<int>, Stream, CancellationToken)

Reads a .pptx from source, reorders its slides per order, and writes the result to destination — see ReorderSlides(byte[], IEnumerable<int>) for exactly what order must contain.

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

public static Task ReorderSlidesAsync(Stream source, IEnumerable<int> order, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the .pptx package is read from.

order IEnumerable<int>

A permutation of every slide's 1-based number.

destination Stream

The stream the edited .pptx package is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

source is not readable or held no bytes, destination is not writable, or order is not a permutation of every slide.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

ReorderSlidesAsync(string, string, IEnumerable<int>, CancellationToken)

Reads a .pptx from inputPath, reorders its slides per order, and writes the result to outputPath — see ReorderSlides(byte[], IEnumerable<int>) for exactly what order must contain. The two paths may be the same file: the updated bytes are computed in full before outputPath is opened.

public static Task ReorderSlidesAsync(string inputPath, string outputPath, IEnumerable<int> order, CancellationToken ct = default)

Parameters

inputPath string

The .pptx to read.

outputPath string

Where to write the result. Overwritten if it exists.

order IEnumerable<int>

A permutation of every slide's 1-based number.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Exceptions

ArgumentNullException

A path or order is null.

ArgumentException

A path is blank, the file at inputPath is empty, or order is not a permutation of every slide.

FileNotFoundException

inputPath does not exist.

DirectoryNotFoundException

inputPath's or outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

ReplaceImage(byte[], string, byte[])

Replaces every shape whose text is exactly placeholder with image, which is scaled to fit inside that shape's box and centred there.

Position and size come from the template, so there is nothing to pass: a designer draws a box in PowerPoint where the image belongs and the image lands there. This deliberately does not mirror DocxEditor.ReplaceImage's size arguments — a DOCX image is inline in the text flow and needs a size, a PPTX picture is a positioned shape and already has one.

The shape's text must be nothing but the placeholder. The unit replaced is the whole shape, so a shape reading Chart: {{chart}} (Q3) would lose the words around the placeholder — silently, and with a schema-valid result. That is refused instead.

PNG and JPEG only, detected from magic bytes rather than any filename.

public static byte[] ReplaceImage(byte[] pptx, string placeholder, byte[] image)

Parameters

pptx byte[]
placeholder string
image byte[]

Returns

byte[]

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

pptx or image is empty, or placeholder is blank.

DocumentConversionException

The placeholder appears nowhere, appears only inside a grouped shape, a matched shape holds other text, a matched shape has no explicit position, the image is neither PNG nor JPEG, or the package could not be edited.

ReplaceImageAsync(Stream, string, byte[], Stream, CancellationToken)

Reads a .pptx from source, replaces every shape whose text is exactly placeholder with image, and writes the result to destination — see ReplaceImage(byte[], string, byte[]) for exactly what counts as a match and how the image is fit into the matched shape's box.

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

public static Task ReplaceImageAsync(Stream source, string placeholder, byte[] image, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the .pptx package is read from.

placeholder string

The placeholder text a shape must hold, and hold only.

image byte[]

PNG or JPEG bytes. The format is decided by the bytes, never a filename.

destination Stream

The stream the edited .pptx package is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

placeholder is blank, image is empty, source is not readable or held no bytes, or destination is not writable.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The placeholder appears nowhere, appears only inside a grouped shape, a matched shape holds other text, a matched shape has no explicit position, the image is neither PNG nor JPEG, or the package could not be edited.

ReplaceImageAsync(string, string, string, byte[], CancellationToken)

Reads a .pptx from inputPath, replaces every shape whose text is exactly placeholder with image, and writes the result to outputPath — see ReplaceImage(byte[], string, byte[]) for exactly what counts as a match and how the image is fit into the matched shape's box. The two paths may be the same file: the updated bytes are computed in full before outputPath is opened, so a document that fails to process — cannot be read, or cannot be edited — leaves outputPath untouched. That guarantee does not extend to a failure during the write itself: a full disk, a cancellation, or the process dying mid-write can still leave a partial file, so in-place editing of an irreplaceable document is not crash-safe.

public static Task ReplaceImageAsync(string inputPath, string outputPath, string placeholder, byte[] image, CancellationToken ct = default)

Parameters

inputPath string

The .pptx to read.

outputPath string

Where to write the result. Overwritten if it exists.

placeholder string

The placeholder text a shape must hold, and hold only.

image byte[]

PNG or JPEG bytes. The format is decided by the bytes, never a filename.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Exceptions

ArgumentNullException

A path, placeholder or image is null.

ArgumentException

A path is blank, the file at inputPath is empty, placeholder is blank, or image is empty.

FileNotFoundException

inputPath does not exist.

DirectoryNotFoundException

inputPath's or outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The placeholder appears nowhere, appears only inside a grouped shape, a matched shape holds other text, a matched shape has no explicit position, the image is neither PNG nor JPEG, or the package could not be edited.

ReplaceText(byte[], IReadOnlyDictionary<string, string>)

Replaces every key with its value across all slide text, returning updated bytes.

PowerPoint routinely splits a single visible word across several <a:t> runs (spell-check state, formatting changes), so a naive per-run replace misses any placeholder that straddles a run boundary. Substitution therefore happens against the concatenated text of each paragraph, but the result is spliced back into only the runs the match actually overlaps: runs outside a match keep their text and their formatting untouched. When a placeholder does straddle runs, the replacement value is written into the run holding its first character and so inherits that run's formatting.

Keys are matched in a single left-to-right pass and the longest key wins at any given offset, so a substituted value is never rescanned for further placeholders. Slides are visited in deck order; speaker notes and slide masters/layouts are not touched.

public static byte[] ReplaceText(byte[] pptx, IReadOnlyDictionary<string, string> replacements)

Parameters

pptx byte[]
replacements IReadOnlyDictionary<string, string>

Returns

byte[]

Exceptions

ArgumentNullException

Either argument is null.

ArgumentException

pptx is empty.

DocumentConversionException

The package could not be opened or edited.

ReplaceTextAsync(Stream, IReadOnlyDictionary<string, string>, Stream, CancellationToken)

Reads a .pptx from source, replaces every key with its value across all slide text, and writes the result to destination — see ReplaceText(byte[], IReadOnlyDictionary<string, string>) for exactly what counts as a match and how formatting survives it.

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

public static Task ReplaceTextAsync(Stream source, IReadOnlyDictionary<string, string> replacements, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the .pptx package is read from.

replacements IReadOnlyDictionary<string, string>

Each key is replaced by its value, longest key wins per match.

destination Stream

The stream the edited .pptx package is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Exceptions

ArgumentNullException

Any argument is null.

ArgumentException

source is not readable or held no bytes, or destination is not writable.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

ReplaceTextAsync(string, string, IReadOnlyDictionary<string, string>, CancellationToken)

Reads a .pptx from inputPath, replaces every key with its value across all slide text, and writes the result to outputPath — see ReplaceText(byte[], IReadOnlyDictionary<string, string>) for exactly what counts as a match and how formatting survives it. The two paths may be the same file: the updated bytes are computed in full before outputPath is opened, so a document that fails to process — cannot be read, or cannot be edited — leaves outputPath untouched. That guarantee does not extend to a failure during the write itself: a full disk, a cancellation, or the process dying mid-write can still leave a partial file, so in-place editing of an irreplaceable document is not crash-safe.

public static Task ReplaceTextAsync(string inputPath, string outputPath, IReadOnlyDictionary<string, string> replacements, CancellationToken ct = default)

Parameters

inputPath string

The .pptx to read.

outputPath string

Where to write the result. Overwritten if it exists.

replacements IReadOnlyDictionary<string, string>

Each key is replaced by its value, longest key wins per match.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Exceptions

ArgumentNullException

A path or replacements is null.

ArgumentException

A path is blank, or the file at inputPath is empty.

FileNotFoundException

inputPath does not exist.

DirectoryNotFoundException

inputPath's or outputPath's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or edited.

SetNotes(byte[], int, string)

Sets the speaker notes on slide slideIndex and returns the updated deck. slideIndex is 1-based, like ReadSlide(byte[], int).

public static byte[] SetNotes(byte[] pptx, int slideIndex, string notes)

Parameters

pptx byte[]

The presentation to edit. It is not modified.

slideIndex int

The 1-based slide number.

notes string

The notes text. Empty clears them.

Returns

byte[]

Remarks

Replaces whatever the slide's notes said; pass an empty string to clear them. Every other slide is left exactly as it was — measured, because editing one slide's notes and silently disturbing another's is the kind of loss no text-reading test would notice.

Exceptions

ArgumentNullException

pptx or notes is null.

ArgumentException

pptx is empty.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

DocumentConversionException

The package could not be opened or written.

SetNotesAsync(Stream, int, string, Stream, CancellationToken)

Sets the speaker notes on slide slideIndex and returns the updated deck. slideIndex is 1-based, like ReadSlide(byte[], int).

public static Task SetNotesAsync(Stream source, int slideIndex, string notes, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

slideIndex int

The 1-based slide number.

notes string

The notes text. Empty clears them.

destination Stream

The stream the updated deck is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Remarks

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

Exceptions

ArgumentNullException

An argument is null.

ArgumentException

source is not readable or held no bytes, or destination is not writable.

ArgumentOutOfRangeException

slideIndex is below 1, or above the deck's slide count.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or written.

SlideCount(byte[])

Number of slides in the deck, as counted from the deck's slide list.

public static int SlideCount(byte[] pptx)

Parameters

pptx byte[]

Returns

int

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

DocumentConversionException

The package could not be opened or read.

SlideCountAsync(Stream, CancellationToken)

Reads a .pptx from source and returns its slide count, counted from the deck's slide list. source is read to its end and is neither disposed, closed nor sought.

public static Task<int> SlideCountAsync(Stream source, CancellationToken ct = default)

Parameters

source Stream
ct CancellationToken

Returns

Task<int>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

SlideCountAsync(string, CancellationToken)

Reads a .pptx from path and returns its slide count, as counted from the deck's slide list — see SlideCount(byte[]) for details.

public static Task<int> SlideCountAsync(string path, CancellationToken ct = default)

Parameters

path string

The .pptx to read.

ct CancellationToken

Cancels the read.

Returns

Task<int>

The number of slides in the deck.

Exceptions

ArgumentNullException

path is null.

ArgumentException

path is blank, or the file it names is empty.

FileNotFoundException

path does not exist.

DirectoryNotFoundException

path's directory does not exist.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The package could not be opened or read.

Unprotect(byte[], string)

A copy of pptx with its encryption removed, so the rest of this class can work on it.

public static byte[] Unprotect(byte[] pptx, string password)

Parameters

pptx byte[]

The encrypted presentation.

password string

The password the presentation was encrypted with.

Returns

byte[]

Remarks

The output is not protected in any way. That is what was asked for, but the bytes this returns are readable by anyone who obtains them.

A presentation that was never encrypted is reported as such rather than passed through, because silently returning the input would make a broken pipeline look like a working one.

Exceptions

ArgumentNullException

pptx or password is null.

ArgumentException

pptx is empty, or password is empty.

DocumentConversionException

The password was wrong, the presentation was not encrypted, or it could not be read.

UnprotectAsync(Stream, Stream, string, CancellationToken)

Reads an encrypted presentation from source and writes the unprotected copy to destination.

Neither stream is disposed, closed or sought.

public static Task UnprotectAsync(Stream source, Stream destination, string password, CancellationToken ct = default)

Parameters

source Stream

The stream the encrypted presentation is read from.

destination Stream

The stream the unprotected presentation is written to.

password string

The password the presentation was encrypted with.

ct CancellationToken

Cancels the read and the write.

Returns

Task

Remarks

The output is not protected in any way. That is what was asked for, but the bytes this returns are readable by anyone who obtains them.

A presentation that was never encrypted is reported as such rather than passed through, because silently returning the input would make a broken pipeline look like a working one.

ValidateSignatures(byte[], DocumentSignatureValidationOptions?)

Validates every digital signature pptx carries, returning the report-level tamper-detection verdict alongside each signature's own certificate chain trust and revocation status. Read DocumentSignatureValidationResult's own remarks before treating its CryptographicStatus as tamper detection — it is not; the report-level IsCryptographicallyValid is. Never performs revocation checking or certificate downloads over the network, regardless of options — see DocumentSignatureValidationOptions's own remarks.

public static DocumentSignatureValidationReport ValidateSignatures(byte[] pptx, DocumentSignatureValidationOptions? options = null)

Parameters

pptx byte[]
options DocumentSignatureValidationOptions

Returns

DocumentSignatureValidationReport

Exceptions

ArgumentNullException

pptx is null.

ArgumentException

pptx is empty.

DocumentConversionException

The presentation could not be validated.

ValidateSignaturesAsync(Stream, DocumentSignatureValidationOptions?, CancellationToken)

Reads a .pptx from source and validates its digital signatures — see ValidateSignatures(byte[], DocumentSignatureValidationOptions?). source is read to its end and is neither disposed, closed nor sought.

public static Task<DocumentSignatureValidationReport> ValidateSignaturesAsync(Stream source, DocumentSignatureValidationOptions? options = null, CancellationToken ct = default)

Parameters

source Stream
options DocumentSignatureValidationOptions
ct CancellationToken

Returns

Task<DocumentSignatureValidationReport>

Exceptions

ArgumentNullException

source is null.

ArgumentException

source is not readable or held no bytes.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The presentation could not be validated.

WithMetadata(byte[], DocumentMetadata)

A copy of pptx carrying metadata.

public static byte[] WithMetadata(byte[] pptx, DocumentMetadata metadata)

Parameters

pptx byte[]
metadata DocumentMetadata

Returns

byte[]

Remarks

A null property leaves what the presentation already had in place, so stamping a title does not silently erase an author. Pass an empty string to clear one.

One exception, forced by OfficeIMO itself: Creator never survives as null through this method. Measured directly: OfficeIMO.PowerPoint's own Save() unconditionally stamps Creator to "OfficeIMO" whenever it is empty at save time — even on a call that never touches Creator at all, and even on a bare save that changes nothing else. ReadMetadata(byte[]) alone, with no save involved, correctly reports null on an untouched deck; it is specifically going through this method — which always saves — that loses the distinction. DOCX and XLSX do not have this behaviour; it is PowerPoint-side only, and there is no supported way around it short of never calling this method.

A second, narrower OfficeIMO defect is also worked around here rather than merely avoided. A deck built by Create(IEnumerable<PptxSlide>) carries zero core-properties relationships — verified directly, and identical to what DocxDocumentWriter produces for DOCX, which does not hit this. Touching BuiltinDocumentProperties on such a deck before Save() makes OfficeIMO create two relationships instead of one, and the save then fails with FileFormatException ("more than one Core Properties relationship") — a defect in OfficeIMO.PowerPoint's own save path, not in the input. The retry below seeds exactly one relationship via the plain, non-experimental Package API before OfficeIMO ever sees the bytes, then tries again. The seed value is drawn from metadata itself — this branch is only ever reached after a real setter has already fired, so at least one of the four properties is guaranteed non-null — so the throwaway seed write and the real value applied moments later are identical, and nothing leaks through as a placeholder the way a made-up seed string would.

Exceptions

ArgumentNullException

pptx or metadata is null.

ArgumentException

pptx is empty.

DocumentConversionException

The presentation could not be read or written.

WithMetadataAsync(Stream, DocumentMetadata, Stream, CancellationToken)

A copy of pptx carrying metadata.

public static Task WithMetadataAsync(Stream source, DocumentMetadata metadata, Stream destination, CancellationToken ct = default)

Parameters

source Stream

The stream the presentation is read from.

metadata DocumentMetadata

The properties to stamp.

destination Stream

The stream the updated presentation is written to.

ct CancellationToken

Cancels the read, the edit and the write.

Returns

Task

Remarks

source is read to its end and destination is written; neither is disposed, closed or sought, and neither has to be seekable.

Exceptions

ArgumentNullException

source, metadata or destination is null.

ArgumentException

source is not readable or held no bytes, or destination is not writable.

OperationCanceledException

ct was cancelled.

DocumentConversionException

The presentation could not be read or written.