Поделиться через


Вставьте новый слайд в презентацию...

В этом разделе показано, как использовать классы в пакете SDK Open XML для Office для перемещения слайда на новую позицию в презентации программными средствами.


Получение объекта Presentation

В пакете SDK Open PresentationDocument XML класс представляет пакет документов презентации. Чтобы работать с документом презентации, сначала создайте экземпляр PresentationDocument класса , а затем работайте с этим экземпляром. Чтобы создать экземпляр класса из документа, вызовите Open метод, использующий путь к файлу, и логическое значение в качестве второго параметра, чтобы указать, доступен ли документ для редактирования. Для подсчета количества слайдов в презентации рекомендуется открыть файл только для чтения, чтобы избежать случайной записи в файл. Для этого укажите значение false для логического параметра, как показано в следующей using инструкции. В этом коде presentationFile параметр представляет собой строку, представляющую путь к файлу, из которого требуется открыть документ.

{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))

В версии 3.0.0+ Close() метод был удален в пользу использования инструкции using. Это гарантирует автоматический Dispose() вызов метода при достижении закрывающей фигурной скобки. Блок, следующий за using оператором , устанавливает область для объекта, созданного или именованного в инструкцииusing, в данном случае presentationDocument.


Базовая структура документа презентации

Базовая структура PresentationML документа состоит из нескольких частей, среди которых есть main часть, содержащая определение презентации. В следующем тексте из спецификации ISO/IEC 29500 представлена общая форма PresentationML пакета.

Main часть PresentationML пакета начинается с корневого элемента презентации. Этот элемент содержит презентацию, которая, в свою очередь, ссылается на список слайдов, список образцов слайдов, список образцов заметок и список образцов раздаточных материалов. Список слайдов ссылается на все слайды в презентации; список образцов слайдов ссылается на все образцы слайдов, используемые в презентации; в списке образцов заметок содержатся данные о форматировании страниц заметок, а в списке образцов раздаточных материалов описан внешний вид раздаточных материалов.

Раздаточные материалы представляют собой набор распечатанных слайдов, которые можно раздать слушателям для последующего использования.

Наряду с текстом и изображениями слайды могут содержать комментарии, заметки и разметку, а также могут входить в одну или несколько пользовательских презентаций. Комментарий представляет собой примечание, которое адресовано сотруднику, ответственному за обслуживание набора слайдов. Заметка представляет собой напоминание или отрывок текста, предназначенный для докладчика или для слушателей.

Другие функции документа PresentationML могут включать следующие: анимацию, звук, видео и переходы между слайдами.

Документ PresentationML не хранится в виде одного большого текста в одной части. Элементы с определенной группировкой функций хранятся в различных частях. Например, все авторы в документе хранятся в одной части авторов, а каждый слайд имеет свою собственную часть.

ISO/IEC 29500: 2016

Указанный ниже пример кода XML описывает презентацию, содержащую 2 слайда с идентификаторами 267 и 256.

    <p:presentation xmlns:p="…" … > 
       <p:sldMasterIdLst>
          <p:sldMasterId
             xmlns:rel="https://…/relationships" rel:id="rId1"/>
       </p:sldMasterIdLst>
       <p:notesMasterIdLst>
          <p:notesMasterId
             xmlns:rel="https://…/relationships" rel:id="rId4"/>
       </p:notesMasterIdLst>
       <p:handoutMasterIdLst>
          <p:handoutMasterId
             xmlns:rel="https://…/relationships" rel:id="rId5"/>
       </p:handoutMasterIdLst>
       <p:sldIdLst>
          <p:sldId id="267"
             xmlns:rel="https://…/relationships" rel:id="rId2"/>
          <p:sldId id="256"
             xmlns:rel="https://…/relationships" rel:id="rId3"/>
       </p:sldIdLst>
           <p:sldSz cx="9144000" cy="6858000"/>
       <p:notesSz cx="6858000" cy="9144000"/>
    </p:presentation>

С помощью пакета SDK Open XML можно создавать структуру документа и содержимое с помощью строго типизированных классов, соответствующих элементам PresentationML. Эти классы можно найти в пространстве имен. В следующей таблице перечислены имена классов, которые соответствуют sldэлементам , sldLayout, sldMasterи notesMaster .

Элемент PresentationML Класс пакета SDK Open XML Описание
<sld/> Slide Слайд презентации. Это корневой элемент части SlidePart.
<sldLayout/> SlideLayout Разметка слайда. Это корневой элемент части SlideLayoutPart.
<sldMaster/> SlideMaster Образец слайда. Это корневой элемент части SlideMasterPart.
<notesMaster/> NotesMaster Образец заметок (или handoutMaster). Это корневой элемент части NotesMasterPart.

Механизм работы примера кода

Для перемещения конкретного слайда в файле презентации на новое место необходимо сначала узнать количество слайдов в презентации. Таким образом, код в данном разделе состоит из двух частей. В первой части выполняется подсчет количества слайдов, во второй — перемещение слайда.


Подсчет количества слайдов

Пример кода для подсчета количества слайдов состоит из двух перегрузок метода CountSlides. Первая перегрузка использует параметр, string а вторая перегрузка PresentationDocument — параметр . В первом CountSlides методе пример кода открывает документ презентации в инструкции using . Затем объект передается PresentationDocument во второй CountSlides метод, который возвращает целочисленное число, представляющее количество слайдов в презентации.

// Pass the presentation to the next CountSlides method
// and return the slide count.
return CountSlides(presentationDocument);

Во втором CountSlides методе код проверяет, что переданный PresentationDocument объект не является , и если это не nullтак, он получает PresentationPart объект из PresentationDocument объекта . С помощью SlideParts кода получает slideCount и возвращает его.

int slidesCount = 0;

// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;

// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
    slidesCount = presentationPart.SlideParts.Count();
}

// Return the slide count to the previous method.
return slidesCount;

Перемещение слайда на новое место

Для перемещения слайда в новую позицию необходимо открыть файл для чтения и записи, указав значение true для логического параметра, как показано в следующей using инструкции. Код для перемещения слайда состоит из двух перегрузок MoveSlide метода . Первый перегруженный MoveSlide метод принимает три параметра: строку, представляющую имя файла презентации и путь, и два целых числа, представляющих текущую позицию индекса слайда и позицию индекса, в которую перемещается слайд соответственно. Он открывает файл презентации, получает PresentationDocument объект, а затем передает этот объект и два целых числа и fromtoво второй перегруженный MoveSlide метод, который выполняет фактическое перемещение.

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}

Во втором перегруженном MoveSlide методе CountSlides метод вызывается для получения количества слайдов в презентации. Затем код проверяет, from находятся ли отсчитываемые от нуля индексы и to, находятся в диапазоне и отличаются друг от друга.

// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Call the CountSlides method to get the number of slides in the presentation.
    int slidesCount = CountSlides(presentationDocument);

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }

Объект PresentationPart объявляется и устанавливается равным части представления переданного PresentationDocument объекта. Объект PresentationPart используется для создания Presentation объекта, а затем для создания SlideIdList объекта, представляющего список слайдов в презентации из Presentation объекта . Определяется идентификатор исходного (перемещаемого) слайда и положение конечного слайда (слайда, после которого необходимо вставить исходный слайд).

// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;

// The slide count is not zero, so the presentation must contain slides.            
Presentation? presentation = presentationPart?.Presentation;

if (presentation is null)
{
    throw new ArgumentNullException(nameof(presentation));
}

SlideIdList? slideIdList = presentation.SlideIdList;

if (slideIdList is null)
{
    throw new ArgumentNullException(nameof(slideIdList));
}

// Get the slide ID of the source slide.
SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;

if (sourceSlide is null)
{
    throw new ArgumentNullException(nameof(sourceSlide));
}

SlideId? targetSlide = null;

// Identify the position of the target slide after which to move the source slide.
if (to == 0)
{
    targetSlide = null;
}
else if (from < to)
{
    targetSlide = slideIdList.ChildElements[to] as SlideId;
}
else
{
    targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
}

Метод Remove объекта используется для удаления исходного SlideID слайда из текущего положения, а затем InsertAfter метод объекта используется для вставки исходного SlideIdList слайда в положение индекса после целевого слайда. Наконец, измененная презентация сохраняется.

// Remove the source slide from its current position.
sourceSlide.Remove();

// Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide);

Пример кода

Ниже приведен полный пример кода, который можно использовать для перемещения слайда из одной позиции в другую в одном файле презентации в C# и Visual Basic.

// Counting the slides in the presentation.
public static int CountSlides(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation to the next CountSlides method
        // and return the slide count.
        return CountSlides(presentationDocument);
    }
}

// Count the slides in the presentation.
static int CountSlides(PresentationDocument presentationDocument)
{
    int slidesCount = 0;

    // Get the presentation part of document.
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    // Get the slide count from the SlideParts.
    if (presentationPart is not null)
    {
        slidesCount = presentationPart.SlideParts.Count();
    }

    // Return the slide count to the previous method.
    return slidesCount;
}

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}

// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument is null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Call the CountSlides method to get the number of slides in the presentation.
    int slidesCount = CountSlides(presentationDocument);

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }

    // Get the presentation part from the presentation document.
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    // The slide count is not zero, so the presentation must contain slides.            
    Presentation? presentation = presentationPart?.Presentation;

    if (presentation is null)
    {
        throw new ArgumentNullException(nameof(presentation));
    }

    SlideIdList? slideIdList = presentation.SlideIdList;

    if (slideIdList is null)
    {
        throw new ArgumentNullException(nameof(slideIdList));
    }

    // Get the slide ID of the source slide.
    SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;

    if (sourceSlide is null)
    {
        throw new ArgumentNullException(nameof(sourceSlide));
    }

    SlideId? targetSlide = null;

    // Identify the position of the target slide after which to move the source slide.
    if (to == 0)
    {
        targetSlide = null;
    }
    else if (from < to)
    {
        targetSlide = slideIdList.ChildElements[to] as SlideId;
    }
    else
    {
        targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
    }
    // Remove the source slide from its current position.
    sourceSlide.Remove();

    // Insert the source slide at its new position after the target slide.
    slideIdList.InsertAfter(sourceSlide, targetSlide);
}

См. также