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


Получить названия всех слайдов в презентации

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


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

В пакете 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.

Пример кода

Следующий пример кода возвращает все заголовки слайдов в файле презентации. Например, можно использовать следующую foreach инструкцию в своей программе, чтобы вернуть все заголовки в файле презентации, расположенном в первом аргументе.

foreach(string title in GetSlideTitles(args[0]))
{
    Console.WriteLine(title);
}

В результате будет получен список отдельных строк, составленный из заголовков презентации.

Ниже приведен полный пример кода на языках C# и Visual Basic.

// Get a list of the titles of all the slides in the presentation.
static IList<string> GetSlideTitles(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        IList<string>? titles = GetSlideTitlesFromPresentation(presentationDocument);

        return (IList<string>)(titles ?? Enumerable.Empty<string>());
    }
}

// Get a list of the titles of all the slides in the presentation.
static IList<string>? GetSlideTitlesFromPresentation(PresentationDocument presentationDocument)
{
    // Get a PresentationPart object from the PresentationDocument object.
    PresentationPart? presentationPart = presentationDocument.PresentationPart;

    if (presentationPart is not null && presentationPart.Presentation is not null)
    {
        // Get a Presentation object from the PresentationPart object.
        Presentation presentation = presentationPart.Presentation;

        if (presentation.SlideIdList is not null)
        {
            List<string> titlesList = new List<string>();

            // Get the title of each slide in the slide order.
            foreach (var slideId in presentation.SlideIdList.Elements<SlideId>())
            {
                if (slideId.RelationshipId is null)
                {
                    continue;
                }

                SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slideId.RelationshipId!);

                // Get the slide title.
                string title = GetSlideTitle(slidePart);

                // An empty title can also be added.
                titlesList.Add(title);
            }

            return titlesList;
        }

    }

    return null;
}

// Get the title string of the slide.
static string GetSlideTitle(SlidePart slidePart)
{
    if (slidePart is null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Declare a paragraph separator.
    string? paragraphSeparator = null;

    if (slidePart.Slide is not null)
    {
        // Find all the title shapes.
        var shapes = from shape in slidePart.Slide.Descendants<Shape>()
                     where IsTitleShape(shape)
                     select shape;

        StringBuilder paragraphText = new StringBuilder();

        foreach (var shape in shapes)
        {
            var paragraphs = shape.TextBody?.Descendants<D.Paragraph>();
            if (paragraphs is null)
            {
                continue;
            }

            // Get the text in each paragraph in this shape.
            foreach (var paragraph in paragraphs)
            {
                // Add a line break.
                paragraphText.Append(paragraphSeparator);

                foreach (var text in paragraph.Descendants<D.Text>())
                {
                    paragraphText.Append(text.Text);
                }

                paragraphSeparator = "\n";
            }
        }

        return paragraphText.ToString();
    }

    return string.Empty;
}

// Determines whether the shape is a title shape.
static bool IsTitleShape(Shape shape)
{
    PlaceholderShape? placeholderShape = shape.NonVisualShapeProperties?.ApplicationNonVisualDrawingProperties?.GetFirstChild<PlaceholderShape>();

    if (placeholderShape is not null && placeholderShape.Type is not null && placeholderShape.Type.HasValue)
    {
        return placeholderShape.Type == PlaceholderValues.Title || placeholderShape.Type == PlaceholderValues.CenteredTitle;
    }

    return false;
}

См. также

Справочник по библиотеке классов пакета SDK Open XML