Gestionar marcadores de posición de presentación en Python

Visión general

Un marcador de posición es una forma que reserva una posición para un tipo particular de contenido en una plantilla de presentación. Los ejemplos más comunes son los marcadores de título, cuerpo, imagen, gráfico y marcadores de contenido de uso general. A diferencia de una forma ordinaria, un marcador de posición puede heredar su posición, tamaño, formato y otros ajustes de una diapositiva de diseño o de una diapositiva maestra.

Aspose.Slides expone la información del marcador de posición a través de la propiedad Shape.placeholder. La propiedad devuelve un objeto Placeholder o None para una forma normal. Utilice Placeholder.type para determinar qué se pretende contener en el marcador de posición.

La clase de forma sigue siendo importante después de conocer el tipo de marcador de posición:

  • Un marcador de posición vacío de texto, imagen, gráfico o contenido suele representarse mediante un AutoShape.
  • Un marcador de posición de imagen poblado puede representarse mediante un PictureFrame.
  • Un marcador de posición de gráfico poblado puede representarse mediante un Chart.
  • Un marcador de posición de contenido puede contener varios tipos de contenido. Compruebe tanto Placeholder.type como la clase de forma en tiempo de ejecución en lugar de asumir que todo marcador de posición es un AutoShape.

Entender la herencia de marcadores de posición

Los marcadores de posición forman una jerarquía:

  1. Una diapositiva maestra define estilos reutilizables y, en algunos casos, marcadores de posición a nivel maestro.
  2. Una diapositiva de diseño define la disposición utilizada por una o más diapositivas normales y puede heredar de la maestra.
  3. Una diapositiva normal contiene los marcadores de posición para esa diapositiva y puede heredar de su diseño.

Llame a Shape.get_base_placeholder para subir un nivel en esta jerarquía. Un marcador de posición de diapositiva normalmente devuelve su marcador de posición de diseño; un marcador de posición de diseño puede devolver su marcador de posición maestro. El método devuelve None cuando la forma no tiene un marcador de posición base.

El siguiente ejemplo enumera los marcadores de posición en la primera diapositiva y muestra sus marcadores de posición base:

import aspose.slides as slides

with slides.Presentation("template.pptx") as presentation:
    slide = presentation.slides[0]

    for shape in slide.shapes:
        if shape.placeholder is None:
            continue

        placeholder_type = shape.placeholder.type
        type_name = type(shape).__name__
        print(f"Slide placeholder: {placeholder_type}; shape class: {type_name}")

        layout_placeholder = shape.get_base_placeholder()
        if layout_placeholder is not None:
            layout_placeholder_type = layout_placeholder.placeholder.type if layout_placeholder.placeholder is not None else None
            print(f"  Layout placeholder: {layout_placeholder_type}")

            master_placeholder = layout_placeholder.get_base_placeholder()
            if master_placeholder is not None:
                master_placeholder_type = master_placeholder.placeholder.type if master_placeholder.placeholder is not None else None
                print(f"  Master placeholder: {master_placeholder_type}")

Editar un marcador de posición en una diapositiva normal crea o modifica una anulación local para esa diapositiva. Editar el diseño o la maestra relacionados puede afectar a todas las diapositivas que aún heredan ese ajuste. Una forma ordinaria local no tiene marcador de posición base y no empieza a heredar solo por ocupar las mismas coordenadas.

Eliminar el estado de marcador de posición

Al adaptar una plantilla, utilice Shape.remove_placeholder para mantener un objeto existente como una forma ordinaria. Su propiedad placeholder pasa a ser None, pero la forma permanece en la colección de la diapositiva. En contraste, ShapeCollection.remove elimina la forma de esa colección.

El siguiente ejemplo requiere template.pptx con al menos una diapositiva y un marcador de posición de texto no vacío en la primera diapositiva. Use un marcador de posición con formato heredado de su diseño o maestra para ver el efecto de eliminar esa relación. El ejemplo verifica que la misma forma permanece, vuelve a llamar al método sobre la forma ya ordinaria y guarda el resultado.

import aspose.slides as slides

with slides.Presentation("template.pptx") as presentation:
    slide = presentation.slides[0]
    found = False

    for index in range(len(slide.shapes)):
        shape = slide.shapes[index]
        if not isinstance(shape, slides.AutoShape) or shape.placeholder is None:
            continue
        if shape.text_frame is None or not shape.text_frame.text:
            continue

        shape_count = len(slide.shapes)
        shape.remove_placeholder()

        print(f"Placeholder removed: {shape.placeholder is None}")
        print(f"Same shape retained: {slide.shapes[index] == shape}")
        print(f"Shape count unchanged: {len(slide.shapes) == shape_count}")

        # Llamar al método sobre una forma ordinaria no tiene efecto.
        shape.remove_placeholder()
        found = True
        break

    if found:
        presentation.save("placeholder-status-removed.pptx", slides.export.SaveFormat.PPTX)
    else:
        print("No nonempty text placeholder was found on the first slide.")

Para un marcador de posición coincidente, las tres comprobaciones devuelven True. El texto permanece, pero la posición, tamaño, rotación, fuente, alineación de párrafo, márgenes del marco de texto, anclaje vertical, relleno y ajustes de línea heredados pueden cambiar cuando se elimina la relación del marcador de posición. Por ejemplo, el formato de título heredado puede volver al formato de texto ordinario. Consulte Slide Layout para obtener más información sobre los diseños.

Para preservar la apariencia prevista, capture la posición, tamaño y rotación resueltos antes de la llamada y copie los valores de formato efectivo requeridos en variables separadas. Obtenga esos valores mediante PortionFormat.get_effective, ParagraphFormat.get_effective, TextFrameFormat.get_effective, FillFormat.get_effective, y LineFormat.get_effective. No confíe solo en los objetos de formato efectivo, ya que sus valores de formato de texto pueden cambiar tras eliminar la relación. Aplique explícitamente los valores capturados a la forma ordinaria después, incluyendo la familia, tamaño, estilo y color de fuente, los ajustes de párrafo, los ajustes del marco de texto, el relleno y la línea que usa su plantilla.

La geometría de la forma heredada también puede necesitar asignarse explícitamente mediante GeometryShape.shape_type. Para un marcador de posición de texto rectangular, esto implica asignar ShapeType.RECTANGLE; restaurar solo el relleno y la línea puede no restaurar el rectángulo visible. Las plantillas con efectos adicionales o formato más complejo requieren que esos ajustes también se gestionen.

Cambiar texto en un marcador de posición

Los marcadores de posición de título, título centrado, subtítulo, cuerpo y texto normalmente admiten texto. Verifique que sea un AutoShape antes de usar su propiedad text_frame.

Este ejemplo actualiza el primer marcador de posición de título en la primera diapositiva y guarda el resultado:

import aspose.slides as slides

with slides.Presentation("template.pptx") as presentation:
    slide = presentation.slides[0]
    title_shape = None

    for shape in slide.shapes:
        if not isinstance(shape, slides.AutoShape) or shape.placeholder is None:
            continue

        placeholder_type = shape.placeholder.type
        if placeholder_type in (slides.PlaceholderType.TITLE, slides.PlaceholderType.CENTERED_TITLE):
            title_shape = shape
            break

    if title_shape is None:
        raise RuntimeError("The first slide does not contain a title placeholder.")

    title_shape.text_frame.text = "Quarterly Business Review"
    presentation.save("title-placeholder-updated.pptx", slides.export.SaveFormat.PPTX)

Este patrón evita tratar marcadores de posición de imagen, gráfico, tabla o multimedia como objetos AutoShape. También identifica el marcador de posición por su propósito en lugar de depender de un índice de forma frágil.

Establecer texto de indicación en un diseño

El texto de indicación es la instrucción en tiempo de diseño que se muestra en un marcador de posición vacío, como Haga clic para añadir título. Establezca texto de indicación personalizado en el marcador de posición del diseño en lugar de intentar alcanzarlo a través de la colección de formas de una diapositiva normal. Acceda al diseño mediante Slide.layout_slide e itere sobre LayoutSlide.shapes.

El siguiente ejemplo cambia las indicaciones de título y subtítulo en el diseño utilizado por la primera diapositiva:

import aspose.slides as slides

with slides.Presentation("template.pptx") as presentation:
    layout_slide = presentation.slides[0].layout_slide

    for shape in layout_slide.shapes:
        if not isinstance(shape, slides.AutoShape) or shape.placeholder is None:
            continue

        placeholder_type = shape.placeholder.type

        if placeholder_type in (slides.PlaceholderType.TITLE, slides.PlaceholderType.CENTERED_TITLE):
            shape.text_frame.text = "Enter a concise slide title"
        elif placeholder_type == slides.PlaceholderType.SUBTITLE:
            shape.text_frame.text = "Enter a subtitle or reporting period"

    presentation.save("custom-placeholder-prompts.pptx", slides.export.SaveFormat.PPTX)

El texto de indicación no es contenido de diapositiva normal. Está destinado a marcadores de posición vacíos en aplicaciones de edición como PowerPoint. Una vez que un usuario o programa suministra contenido real, la indicación deja de mostrarse. Cambiar una indicación tampoco sustituye el texto existente en las diapositivas que usan el diseño.

Actualizar un marcador de posición de imagen

Hay dos casos a tratar:

El siguiente ejemplo admite ambos casos y guarda la presentación:

import aspose.slides as slides

with slides.Presentation("picture-template.pptx") as presentation:
    slide = presentation.slides[0]
    picture_placeholder = None

    for shape in slide.shapes:
        if shape.placeholder is not None and shape.placeholder.type == slides.PlaceholderType.PICTURE:
            picture_placeholder = shape
            break

    if picture_placeholder is None:
        raise RuntimeError("The first slide does not contain a picture placeholder.")

    with open("replacement.png", "rb") as image_stream:
        image_bytes = image_stream.read()

    image = presentation.images.add_image(image_bytes)

    if isinstance(picture_placeholder, slides.PictureFrame):
        picture_placeholder.picture_format.picture.image = image
    else:
        slide.shapes.add_picture_frame(slides.ShapeType.RECTANGLE, picture_placeholder.x, picture_placeholder.y, picture_placeholder.width, picture_placeholder.height, image)
        slide.shapes.remove(picture_placeholder)

    presentation.save("picture-placeholder-updated.pptx", slides.export.SaveFormat.PPTX)

El reemplazo creado para un marcador de posición vacío es un marco de imagen local, no un nuevo marcador de posición, porque Shape.placeholder es de solo lectura. Conserva la posición reservada pero ya no hereda el comportamiento específico del marcador de posición. Si es esencial mantener la relación del marcador de posición, prepare y rellene el marcador en PowerPoint primero, y luego actualice el PictureFrame resultante con Aspose.Slides.

Para la transparencia de imágenes, recorte y otros efectos específicos de la imagen, consulte Manage Picture Frames. esas operaciones pertenecen al marco de imagen o al relleno de imagen, no a los metadatos del marcador de posición.

Trabajar con marcadores de posición de gráfico y contenido

Un marcador de posición de gráfico poblado puede representarse mediante un Chart. Este ejemplo localiza dicho gráfico tanto por tipo de marcador de posición como por clase en tiempo de ejecución, cambia su título y guarda el archivo:

import aspose.slides as slides
import aspose.slides.charts as charts

with slides.Presentation("chart-template.pptx") as presentation:
    slide = presentation.slides[0]
    placeholder_chart = None

    for shape in slide.shapes:
        if isinstance(shape, charts.Chart) and shape.placeholder is not None and shape.placeholder.type == slides.PlaceholderType.CHART:
            placeholder_chart = shape
            break

    if placeholder_chart is None:
        raise RuntimeError("The first slide does not contain a populated chart placeholder.")

    placeholder_chart.has_title = True
    placeholder_chart.chart_title.add_text_frame_for_overriding("Quarterly Revenue")
    presentation.save("chart-placeholder-updated.pptx", slides.export.SaveFormat.PPTX)

Un marcador de posición de contenido general suele tener PlaceholderType.OBJECT. En PowerPoint actúa como lanzador para varios tipos de contenido, incluidos gráficos, tablas, diagramas, imágenes y multimedia. Tras poblarlo, inspeccione la clase de forma real para saber qué contiene. Los diseños especializados también pueden exponer PlaceholderType.CHART, PlaceholderType.TABLE, PlaceholderType.PICTURE, PlaceholderType.MEDIA, o PlaceholderType.DIAGRAM.

Aspose.Slides no convierte un marcador de posición vacío de AutoShape en un Chart simplemente cambiando Placeholder.type; el tipo es de solo lectura. Para rellenar programáticamente un área de gráfico o contenido vacío, añada el objeto necesario en las coordenadas del marcador y luego elimine el marcador vacío. El siguiente ejemplo lo hace para un gráfico:

import aspose.slides as slides
import aspose.slides.charts as charts

with slides.Presentation("content-template.pptx") as presentation:
    slide = presentation.slides[0]
    target_placeholder = None

    for shape in slide.shapes:
        if shape.placeholder is None:
            continue

        if shape.placeholder.type in (slides.PlaceholderType.CHART, slides.PlaceholderType.OBJECT):
            target_placeholder = shape
            break

    if target_placeholder is None:
        raise RuntimeError("The first slide does not contain a chart or content placeholder.")

    chart = slide.shapes.add_chart(charts.ChartType.CLUSTERED_COLUMN, target_placeholder.x, target_placeholder.y, target_placeholder.width, target_placeholder.height)
    chart.has_title = True
    chart.chart_title.add_text_frame_for_overriding("Quarterly Revenue")
    slide.shapes.remove(target_placeholder)
    presentation.save("content-placeholder-replaced-with-chart.pptx", slides.export.SaveFormat.PPTX)

El gráfico añadido es un gráfico local ordinario. Ocupa el área del marcador de posición pero no hereda del marcador de posición del diseño. Utilice los artículos dedicados a la gestión de gráficos (chart management articles) cuando necesite reemplazar sus categorías, series o datos del libro de trabajo.

Ejemplo completo: actualizar contenido de texto o imagen

El siguiente ejemplo de extremo a extremo abre una plantilla, busca en la primera diapositiva un marcador de posición de título o de imagen, verifica los tipos de marcador de posición y de forma, actualiza el contenido correspondiente y guarda el resultado. El ejemplo evita deliberadamente suponer un índice de forma o tratar todos los marcadores de posición como la misma clase de forma.

import aspose.slides as slides

with slides.Presentation("template.pptx") as presentation:
    slide = presentation.slides[0]
    updated = False

    for shape in slide.shapes:
        if shape.placeholder is None:
            continue

        placeholder_type = shape.placeholder.type

        if placeholder_type in (slides.PlaceholderType.TITLE, slides.PlaceholderType.CENTERED_TITLE) and isinstance(shape, slides.AutoShape):
            shape.text_frame.text = "Quarterly Business Review"
            updated = True
            break

        if placeholder_type == slides.PlaceholderType.PICTURE:
            with open("replacement.png", "rb") as image_stream:
                image_bytes = image_stream.read()

            image = presentation.images.add_image(image_bytes)

            if isinstance(shape, slides.PictureFrame):
                shape.picture_format.picture.image = image
            else:
                slide.shapes.add_picture_frame(slides.ShapeType.RECTANGLE, shape.x, shape.y, shape.width, shape.height, image)
                slide.shapes.remove(shape)

            updated = True
            break

    if not updated:
        raise RuntimeError("No supported title or picture placeholder was found on the first slide.")

    presentation.save("placeholder-content-updated.pptx", slides.export.SaveFormat.PPTX)

Preguntas frecuentes

¿Qué es un marcador de posición base?

Un marcador de posición base es la forma correspondiente en el diseño o la maestra de la que otro marcador de posición hereda. Utilice Shape.get_base_placeholder para recuperarlo. Una forma local ordinaria devuelve None porque no forma parte de la jerarquía de marcadores de posición.

¿Puedo cambiar todos los títulos de diapositiva editando un marcador de posición de diseño?

Puede cambiar el formato heredado o el texto de indicación mediante un diseño, pero el contenido del título existente se almacena en las diapositivas normales. Para reemplazar el texto real del título en toda la presentación, itere sobre las diapositivas y actualice cada marcador de posición de título.

¿Cómo gestiono los marcadores de posición de fecha, número de diapositiva, encabezado y pie de página?

Utilice los gestores de encabezado y pie de página en el ámbito de la diapositiva, diseño, maestra, notas o folletos correspondiente. Consulte Manage Presentation Header and Footer para ejemplos completos.