Управление заполнителями презентаций на Android

Обзор

Заполнитель — это фигура, зарезервирующая позицию для определённого типа содержимого в шаблоне презентации. Типичными примерами являются заголовок, основной текст, рисунок, диаграмма и универсальные заполнитель‑контент. В отличие от обычной фигуры, заполнитель может наследовать позицию, размер, форматирование и другие параметры от макетного или мастер‑слайда.

Aspose.Slides предоставляет информацию о заполняющих элементах через метод IShape.getPlaceholder. Метод возвращает объект IPlaceholder или null для обычной фигуры. Используйте IPlaceholder.getType, чтобы определить, какое содержимое предполагается в заполнителе.

Интерфейс фигуры всё равно важен после того, как известен тип заполнителя:

  • Пустой текстовый, рисунковый, диаграммный или контентный заполнитель обычно представлен объектом IAutoShape.
  • Заполненный рисунковый заполнитель может быть представлен объектом IPictureFrame.
  • Заполненный диаграммный заполнитель может быть представлен объектом IChart.
  • Контентный заполнитель может содержать несколько типов содержимого. Проверяйте как IPlaceholder.getType, так и интерфейс фигуры во время выполнения, вместо предположения, что каждый заполнитель — это IAutoShape.

Понимание наследования заполнителей

Заполнители образуют иерархию:

  1. Мастер‑слайд определяет переиспользуемые стили и, в некоторых случаях, заполнители уровня мастера.
  2. Слайд‑макет определяет расположение, используемое одним или несколькими обычными слайдами, и может наследовать от мастера.
  3. Обычный слайд содержит заполнители для этого слайда и может наследовать от своего макета.

Вызовите IShape.getBasePlaceholder, чтобы подняться на один уровень вверх по этой иерархии. Заполнитель обычного слайда обычно возвращает заполнитель своего макета; заполнитель макета может вернуть заполнитель мастера. Метод возвращает null, когда у фигуры нет базового заполнителя.

Ниже приведён пример, который перечисляет заполнители на первом слайде и выводит их базовые заполнители:

import com.aspose.slides.*;

Presentation presentation = new Presentation("template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);

    for (IShape shape : slide.getShapes()) {
        IPlaceholder placeholder = shape.getPlaceholder();
        if (placeholder == null) {
            continue;
        }

        byte placeholderType = placeholder.getType();
        String typeName = shape.getClass().getSimpleName();
        String slidePlaceholderMessage = "Slide placeholder: " + placeholderType + "; shape interface: " + typeName;
        System.out.println(slidePlaceholderMessage);

        IShape layoutPlaceholder = shape.getBasePlaceholder();
        if (layoutPlaceholder != null) {
            IPlaceholder layoutPlaceholderInfo = layoutPlaceholder.getPlaceholder();
            Byte layoutPlaceholderType = layoutPlaceholderInfo == null ? null : layoutPlaceholderInfo.getType();
            String layoutPlaceholderMessage = "  Layout placeholder: " + layoutPlaceholderType;
            System.out.println(layoutPlaceholderMessage);

            IShape masterPlaceholder = layoutPlaceholder.getBasePlaceholder();
            if (masterPlaceholder != null) {
                IPlaceholder masterPlaceholderInfo = masterPlaceholder.getPlaceholder();
                Byte masterPlaceholderType = masterPlaceholderInfo == null ? null : masterPlaceholderInfo.getType();
                String masterPlaceholderMessage = "  Master placeholder: " + masterPlaceholderType;
                System.out.println(masterPlaceholderMessage);
            }
        }
    }
} finally {
    presentation.dispose();
}

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

Изменение текста в заполнителе

Заполнители заголовков, центрированных заголовков, подзаголовков, основного текста и текста обычно поддерживают текст. Проверьте, является ли фигура IAutoShape, прежде чем использовать её метод getTextFrame.

Этот пример обновляет первый заполнитель заголовка на первом слайде и сохраняет результат:

import com.aspose.slides.*;

Presentation presentation = new Presentation("template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IAutoShape titleShape = null;

    for (IShape shape : slide.getShapes()) {
        if (!(shape instanceof IAutoShape)) {
            continue;
        }

        IAutoShape autoShape = (IAutoShape) shape;
        IPlaceholder placeholder = autoShape.getPlaceholder();
        if (placeholder == null) {
            continue;
        }

        byte placeholderType = placeholder.getType();
        if (placeholderType == PlaceholderType.Title || placeholderType == PlaceholderType.CenteredTitle) {
            titleShape = autoShape;
            break;
        }
    }

    if (titleShape == null) {
        throw new IllegalStateException("The first slide does not contain a title placeholder.");
    }

    titleShape.getTextFrame().setText("Quarterly Business Review");
    presentation.save("title-placeholder-updated.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Такой подход позволяет избежать приведения рисунков, диаграмм, таблиц или медиа‑заполнителей к типу IAutoShape. Он также идентифицирует заполнитель по назначению, а не полагается на хрупкий индекс фигуры.

Установление текста‑подсказки в макете

Текст‑подсказка — это инструкционная надпись, отображаемая в пустом заполнителе в режиме дизайна, например Click to add title. Устанавливайте пользовательскую подсказку в заполнителе макета, а не через коллекцию фигур обычного слайда. Доступ к макету получайте через ISlide.getLayoutSlide и перебирайте коллекцию, возвращаемую ILayoutSlide.getShapes.

Следующий пример изменяет подсказки заголовка и подзаголовка в макете, используемом первым слайдом:

import com.aspose.slides.*;

Presentation presentation = new Presentation("template.pptx");
try {
    ILayoutSlide layoutSlide = presentation.getSlides().get_Item(0).getLayoutSlide();

    for (IShape shape : layoutSlide.getShapes()) {
        if (!(shape instanceof IAutoShape)) {
            continue;
        }

        IAutoShape autoShape = (IAutoShape) shape;
        IPlaceholder placeholder = autoShape.getPlaceholder();
        if (placeholder == null) {
            continue;
        }

        byte placeholderType = placeholder.getType();

        if (placeholderType == PlaceholderType.Title || placeholderType == PlaceholderType.CenteredTitle) {
            autoShape.getTextFrame().setText("Enter a concise slide title");
        } else if (placeholderType == PlaceholderType.Subtitle) {
            autoShape.getTextFrame().setText("Enter a subtitle or reporting period");
        }
    }

    presentation.save("custom-placeholder-prompts.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Текст‑подсказка — это не обычное содержимое слайда. Он предназначен для пустых заполнителей в редакторах, таких как PowerPoint. Как только пользователь или программа задают реальное содержимое, подсказка больше не отображается. Изменение подсказки также не заменяет существующий текст на слайдах, использующих данный макет.

Обновление заполнителя рисунка

Существуют два варианта обработки:

  • Если рисунковый заполнитель уже заполнен и представлен объектом IPictureFrame, замените изображение через IPictureFillFormat.getPicture и ISlidesPicture.setImage.
  • Если это всё ещё пустой заполнитель, добавьте рисунковый кадр в координатах заполнителя с помощью IShapeCollection.addPictureFrame и удалите пустой заполнитель.

Следующий пример поддерживает оба случая и сохраняет презентацию:

import com.aspose.slides.*;
import java.io.FileInputStream;

Presentation presentation = new Presentation("picture-template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IShape picturePlaceholder = null;

    for (IShape shape : slide.getShapes()) {
        IPlaceholder placeholder = shape.getPlaceholder();
        if (placeholder != null && placeholder.getType() == PlaceholderType.Picture) {
            picturePlaceholder = shape;
            break;
        }
    }

    if (picturePlaceholder == null) {
        throw new IllegalStateException("The first slide does not contain a picture placeholder.");
    }

    IPPImage image;
    try (FileInputStream imageStream = new FileInputStream("replacement.png")) {
        image = presentation.getImages().addImage(imageStream);
    }

    if (picturePlaceholder instanceof IPictureFrame) {
        IPictureFrame pictureFrame = (IPictureFrame) picturePlaceholder;
        pictureFrame.getPictureFormat().getPicture().setImage(image);
    } else {
        slide.getShapes().addPictureFrame(ShapeType.Rectangle, picturePlaceholder.getX(), picturePlaceholder.getY(), picturePlaceholder.getWidth(), picturePlaceholder.getHeight(), image);
        slide.getShapes().remove(picturePlaceholder);
    }

    presentation.save("picture-placeholder-updated.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Созданная замена для пустого заполнителя — это локальный рисунковый кадр, а не новый заполнитель, поскольку IShape.getPlaceholder не предоставляет сеттера. Он сохраняет зарезервированную позицию, но больше не наследует поведение заполнителя. Если сохранение связи с заполнителем критично, сначала подготовьте и заполните заполнитель в PowerPoint, а затем обновите полученный IPictureFrame с помощью Aspose.Slides.

Для прозрачности изображения, обрезки и других эффектов, специфичных для рисунка, смотрите статью Manage Picture Frames. Эти операции относятся к рисунковому кадру или заливке, а не к метаданным заполнителя.

Работа с диаграммными и контентными заполнителями

Заполненный диаграммный заполнитель может быть представлен объектом IChart. Пример ниже находит такую диаграмму по типу заполнителя и интерфейсу во время выполнения, меняет её заголовок и сохраняет файл:

import com.aspose.slides.*;

Presentation presentation = new Presentation("chart-template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IChart placeholderChart = null;

    for (IShape shape : slide.getShapes()) {
        if (!(shape instanceof IChart)) {
            continue;
        }

        IChart chart = (IChart) shape;
        IPlaceholder placeholder = chart.getPlaceholder();
        if (placeholder != null && placeholder.getType() == PlaceholderType.Chart) {
            placeholderChart = chart;
            break;
        }
    }

    if (placeholderChart == null) {
        throw new IllegalStateException("The first slide does not contain a populated chart placeholder.");
    }

    placeholderChart.setTitle(true);
    placeholderChart.getChartTitle().addTextFrameForOverriding("Quarterly Revenue");
    presentation.save("chart-placeholder-updated.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Общий контентный заполнитель обычно имеет тип PlaceholderType.Object. В PowerPoint он выступает как средство запуска для нескольких типов содержимого, включая диаграммы, таблицы, схемы, рисунки и медиа. После заполнения исследуйте реальный интерфейс фигуры, чтобы узнать, что именно она содержит. Специализированные макеты могут также раскрывать типы PlaceholderType.Chart, PlaceholderType.Table, PlaceholderType.Picture, PlaceholderType.Media, или PlaceholderType.Diagram.

Aspose.Slides не преобразует пустой IAutoShape в IChart простым изменением IPlaceholder.getType; тип нельзя изменить через интерфейс. Чтобы программно заполнить пустую диаграмму или область контента, добавьте требуемый объект в координаты заполнителя, а затем удалите пустой заполнитель. Пример ниже делает это для диаграммы:

import com.aspose.slides.*;

Presentation presentation = new Presentation("content-template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    IShape targetPlaceholder = null;

    for (IShape shape : slide.getShapes()) {
        IPlaceholder placeholder = shape.getPlaceholder();
        if (placeholder == null) {
            continue;
        }

        byte placeholderType = placeholder.getType();
        if (placeholderType == PlaceholderType.Chart || placeholderType == PlaceholderType.Object) {
            targetPlaceholder = shape;
            break;
        }
    }

    if (targetPlaceholder == null) {
        throw new IllegalStateException("The first slide does not contain a chart or content placeholder.");
    }

    IChart chart = slide.getShapes().addChart(ChartType.ClusteredColumn, targetPlaceholder.getX(), targetPlaceholder.getY(), targetPlaceholder.getWidth(), targetPlaceholder.getHeight());
    chart.setTitle(true);
    chart.getChartTitle().addTextFrameForOverriding("Quarterly Revenue");
    slide.getShapes().remove(targetPlaceholder);
    presentation.save("content-placeholder-replaced-with-chart.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

Добавленная диаграмма — это обычная локальная диаграмма. Она занимает область заполнителя, но не наследует от заполнителя макета. При необходимости заменить категории, серии или данные книги используйте специализированные статьи по управлению диаграммами.

Полный пример: обновление текста или изображения

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

import com.aspose.slides.*;
import java.io.FileInputStream;

Presentation presentation = new Presentation("template.pptx");
try {
    ISlide slide = presentation.getSlides().get_Item(0);
    boolean updated = false;

    for (IShape shape : slide.getShapes()) {
        IPlaceholder placeholder = shape.getPlaceholder();
        if (placeholder == null) {
            continue;
        }

        byte placeholderType = placeholder.getType();

        if ((placeholderType == PlaceholderType.Title || placeholderType == PlaceholderType.CenteredTitle) && shape instanceof IAutoShape) {
            IAutoShape titleShape = (IAutoShape) shape;
            titleShape.getTextFrame().setText("Quarterly Business Review");
            updated = true;
            break;
        }

        if (placeholderType == PlaceholderType.Picture) {
            IPPImage image;
            try (FileInputStream imageStream = new FileInputStream("replacement.png")) {
                image = presentation.getImages().addImage(imageStream);
            }

            if (shape instanceof IPictureFrame) {
                IPictureFrame pictureFrame = (IPictureFrame) shape;
                pictureFrame.getPictureFormat().getPicture().setImage(image);
            } else {
                slide.getShapes().addPictureFrame(ShapeType.Rectangle, shape.getX(), shape.getY(), shape.getWidth(), shape.getHeight(), image);
                slide.getShapes().remove(shape);
            }

            updated = true;
            break;
        }
    }

    if (!updated) {
        throw new IllegalStateException("No supported title or picture placeholder was found on the first slide.");
    }

    presentation.save("placeholder-content-updated.pptx", SaveFormat.Pptx);
} finally {
    presentation.dispose();
}

FAQ

Что такое базовый заполнитель?

Базовый заполнитель — это соответствующая фигура на макете или мастер‑слайде, от которой наследуется другой заполнитель. Используйте IShape.getBasePlaceholder для получения его. Обычная локальная фигура возвращает null, поскольку она не входит в иерархию заполнителей.

Могу ли я изменить все заголовки слайдов, отредактировав заполнитель в макете?

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

Как управлять заполнителями даты, номера слайда, верхнего и нижнего колонтитулов?

Используйте менеджеры верхних и нижних колонтитулов в контексте соответствующего слайда, макета, мастера, заметок или раздаточного листа. См. статью Manage Presentation Header and Footer для полных примеров.