PowerPoint add-ins

You can use PowerPoint add-ins to build engaging solutions for your users' presentations across platforms including Windows, iPad, Mac, and in a browser. You can create two types of PowerPoint add-ins:

PowerPoint add-in scenarios

The code examples in this article demonstrate some basic tasks for developing add-ins for PowerPoint. Please note the following:

  • To display information, these examples use the app.showNotification function, which is included in the Visual Studio Office Add-ins project templates. If you aren't using Visual Studio to develop your add-in, you'll need replace the showNotification function with your own code.

  • Several of these examples also use a Globals object that's declared beyond the scope of these functions as:

    let Globals = {activeViewHandler:0, firstSlideId:0};

  • To use these examples, your add-in project must reference Office.js v1.1 library or later.

Detect the presentation's active view and handle the ActiveViewChanged event

If you're building a content add-in, you'll need to get the presentation's active view and handle the ActiveViewChanged event, as part of your Office.onReady handler.

Note

In PowerPoint on the web, the Document.ActiveViewChanged event will never fire as Slide Show mode is treated as a new session. In this case, the add-in must fetch the active view on load, as shown in the following code sample.

Note the following about the code sample:

  • The getActiveFileView function calls the Document.getActiveViewAsync method to return whether the presentation's current view is "edit" (any of the views in which you can edit slides, such as Normal or Outline View) or "read" (Slide Show or Reading View).

  • The registerActiveViewChanged function calls the addHandlerAsync method to register a handler for the Document.ActiveViewChanged event.

// General Office.onReady function. Called after the add-in loads and Office JS is initialized.
Office.onReady(function() {
    // Get whether the current view is edit or read.
    const currentView = getActiveFileView();

    // Register for the active view changed handler.
    registerActiveViewChanged();

    // Render the content based off of the currentView.
    //....
});

function getActiveFileView()
{
    Office.context.document.getActiveViewAsync(function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
            app.showNotification("Action failed with error: " + asyncResult.error.message);
        } else {
            app.showNotification(asyncResult.value);
        }
    });

}

function registerActiveViewChanged() {
    Globals.activeViewHandler = function (args) {
        app.showNotification(JSON.stringify(args));
    }

    Office.context.document.addHandlerAsync(Office.EventType.ActiveViewChanged, Globals.activeViewHandler,
        function (asyncResult) {
            if (asyncResult.status === Office.AsyncResultStatus.Failed) {
                app.showNotification("Action failed with error: " + asyncResult.error.message);
            } else {
                app.showNotification(asyncResult.status);
            }
        });
}

In the following code sample, the getSelectedRange function calls the Document.getSelectedDataAsync method to get the JSON object returned by asyncResult.value, which contains an array named slides. The slides array contains the IDs, titles, and indexes of selected range of slides (or of the current slide, if multiple slides aren't selected). It also saves the ID of the first slide in the selected range to a global variable.

function getSelectedRange() {
    // Gets the ID, title, and index of the current slide (or selected slides) and store the first slide ID. */
    Globals.firstSlideId = 0;

    Office.context.document.getSelectedDataAsync(Office.CoercionType.SlideRange, function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
            app.showNotification("Action failed with error: " + asyncResult.error.message);
        } else {
            Globals.firstSlideId = asyncResult.value.slides[0].id;
            app.showNotification(JSON.stringify(asyncResult.value));
        }
    });
}

In the following code sample, the goToFirstSlide function calls the Document.goToByIdAsync method to navigate to the first slide that was identified by the getSelectedRange function shown previously.

function goToFirstSlide() {
    Office.context.document.goToByIdAsync(Globals.firstSlideId, Office.GoToType.Slide, function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
            app.showNotification("Action failed with error: " + asyncResult.error.message);
        } else {
            app.showNotification("Navigation successful");
        }
    });
}

In the following code sample, the goToSlideByIndex function calls the Document.goToByIdAsync method to navigate to the next slide in the presentation.

function goToSlideByIndex() {
    const goToFirst = Office.Index.First;
    const goToLast = Office.Index.Last;
    const goToPrevious = Office.Index.Previous;
    const goToNext = Office.Index.Next;

    Office.context.document.goToByIdAsync(goToNext, Office.GoToType.Index, function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Failed) {
            app.showNotification("Action failed with error: " + asyncResult.error.message);
        } else {
            app.showNotification("Navigation successful");
        }
    });
}

Get the URL of the presentation

In the following code sample, the getFileUrl function calls the Document.getFileProperties method to get the URL of the presentation file.

function getFileUrl() {
    // Gets the URL of the current file.
    Office.context.document.getFilePropertiesAsync(function (asyncResult) {
        const fileUrl = asyncResult.value.url;
        if (fileUrl === "") {
            app.showNotification("The file hasn't been saved yet. Save the file and try again.");
        } else {
            app.showNotification(fileUrl);
        }
    });
}

Create a presentation

Your add-in can create a new presentation, separate from the PowerPoint instance in which the add-in is currently running. The PowerPoint namespace has the createPresentation method for this purpose. When this method is called, the new presentation is immediately opened and displayed in a new instance of PowerPoint. Your add-in remains open and running with the previous presentation.

PowerPoint.createPresentation();

The createPresentation method can also create a copy of an existing presentation. The method accepts a Base64-encoded string representation of an .pptx file as an optional parameter. The resulting presentation will be a copy of that file, assuming the string argument is a valid .pptx file. The FileReader class can be used to convert a file into the required Base64-encoded string, as demonstrated in the following example.

const myFile = document.getElementById("file");
const reader = new FileReader();

reader.onload = function (event) {
    // Strip off the metadata before the Base64-encoded string.
    const startIndex = reader.result.toString().indexOf("base64,");
    const copyBase64 = reader.result.toString().substr(startIndex + 7);

    PowerPoint.createPresentation(copyBase64);
};

// Read in the file as a data URL so we can parse the Base64-encoded string.
reader.readAsDataURL(myFile.files[0]);

See also