Compartir a través de


Obtener todo el texto de una diapositiva en una presentación

En este tema se muestra cómo usar las clases del SDK de Open XML para Office para obtener todo el texto de una diapositiva de una presentación mediante programación.


Obtención de un objeto PresentationDocument

En el SDK de Open XML, la PresentationDocument clase representa un paquete de documento de presentación. Para trabajar con un documento de presentación, cree primero una instancia de la PresentationDocument clase y, a continuación, trabaje con esa instancia. Para crear la instancia de clase a partir del documento, llame al Open método que usa una ruta de acceso de archivo y a un valor booleano como segundo parámetro para especificar si un documento es editable. Para abrir un documento para el acceso de lectura y escritura, asigne el valor true a este parámetro; para el acceso de solo lectura, asígnele el valor false como se muestra en la instrucción siguiente using . En este código, el file parámetro es una cadena que representa la ruta de acceso del archivo desde el que desea abrir el documento.

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

Con v3.0.0+ el Close() método se ha quitado en favor de confiar en la instrucción using. Esto garantiza que se llama automáticamente al Dispose() método cuando se alcanza la llave de cierre. El bloque que sigue a la using instrucción establece un ámbito para el objeto que se crea o se denomina en la using instrucción , en este caso presentationDocument.


Estructura básica de un documento de presentación

La estructura básica de un PresentationML documento consta de varias partes, entre las que se encuentra la parte principal que contiene la definición de presentación. El siguiente texto de la especificación ISO/IEC 29500 presenta la forma general de un PresentationML paquete.

La parte principal de un PresentationML paquete comienza con un elemento raíz de presentación. Dicho elemento contiene una presentación que, a su vez, hace referencia a una lista de diapositivas, a otra de patrones de diapositivas, a otra de patrones de notas y a otra de patrones de documentos. La lista de diapositivas hace referencia a todas las diapositivas de la presentación, la de patrones de diapositivas a todos los patrones de diapositivas que se han usado en la presentación, el patrón de notas contiene información acerca del formato de las páginas de notas y el patrón de documentos describe la apariencia de los documentos.

Un documento es un conjunto impreso de diapositivas que se pueden proporcionar a un público.

Al igual que el texto y los gráficos, cada diapositiva puede incluir comentarios y notas, tener un diseño y formar parte de una o varias presentaciones personalizadas. Un comentario es una anotación dirigida a la persona que se encarga del mantenimiento de las diapositivas de la presentación. Una nota es un aviso o texto dirigido al moderador o al público.

Otras características que un PresentationML documento puede incluir son las siguientes: animación, audio, vídeo y transiciones entre diapositivas .

Un PresentationML documento no se almacena como un cuerpo grande en una sola parte. En su lugar, los elementos que implementan ciertas agrupaciones de funcionalidades se almacenan en partes independientes. Por ejemplo, todos los autores de un documento se almacenan en una parte de autores mientras que cada diapositiva tiene su propia parte.

ISO/IEC 29500: 2016

El siguiente ejemplo de código XML representa una presentación que contiene dos diapositivas denotadas por los identificadores 267 y 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>

Con el SDK de Open XML, puede crear contenido y estructura de documentos mediante clases fuertemente tipadas que corresponden a elementos PresentationML. Puede encontrar estas clases en el espacio de nombres. En la tabla siguiente se enumeran los nombres de clase de las clases correspondientes a los sldelementos , sldLayout, sldMastery notesMaster .

Elemento de PresentationML Open XML SDK (clase) Descripción
<sld/> Slide Diapositiva de presentación. Es el elemento raíz de SlidePart.
<sldLayout/> SlideLayout Diseño de la diapositiva. Es el elemento raíz de SlideLayoutPart.
<sldMaster/> SlideMaster Patrón de diapositivas. Es el elemento raíz de SlideMasterPart.
<notesMaster/> NotesMaster Patrón de notas (o handoutMaster). Es el elemento raíz de NotesMasterPart.

Funcionamiento del código de ejemplo

El código de ejemplo consta de tres sobrecargas del GetAllTextInSlide método . En el segmento siguiente, el primer método sobrecargado abre la presentación de origen que contiene la diapositiva con texto que se va a obtener y pasa la presentación al segundo método sobrecargado, que obtiene la parte de diapositiva. Este método devuelve la matriz de cadenas que el segundo método le devuelve, cada una de las cuales representa un párrafo de texto en la diapositiva especificada.

// Get all the text in a slide.
public static string[] GetAllTextInSlide(string presentationFile, int slideIndex)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation and the slide index
        // to the next GetAllTextInSlide method, and
        // then return the array of strings it returns. 
        return GetAllTextInSlide(presentationDocument, slideIndex);
    }
}

El segundo método sobrecargado toma el documento de presentación que se pasó y obtiene una parte de diapositiva para pasar al tercer método sobrecargado. Devuelve al primer método sobrecargado la matriz de cadenas (cada una de las cuales representa un párrafo de texto en la diapositiva especificada) que el tercer método sobrecargado le devuelve.

static string[] GetAllTextInSlide(PresentationDocument presentationDocument, int slideIndex)
{
    // Verify that the slide index is not out of range.
    if (slideIndex < 0)
    {
        throw new ArgumentOutOfRangeException("slideIndex");
    }

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

    // Verify that the presentation part and presentation exist.
    if (presentationPart is not null && presentationPart.Presentation is not null)
    {
        // Get the Presentation object from the presentation part.
        Presentation presentation = presentationPart.Presentation;

        // Verify that the slide ID list exists.
        if (presentation.SlideIdList is not null)
        {
            // Get the collection of slide IDs from the slide ID list.
            DocumentFormat.OpenXml.OpenXmlElementList slideIds = presentation.SlideIdList.ChildElements;

            // If the slide ID is in range...
            if (slideIndex < slideIds.Count)
            {
                // Get the relationship ID of the slide.
                string? slidePartRelationshipId = ((SlideId)slideIds[slideIndex]).RelationshipId;

                if (slidePartRelationshipId is null)
                {
                    return [];
                }

                // Get the specified slide part from the relationship ID.
                SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);

                // Pass the slide part to the next method, and
                // then return the array of strings that method
                // returns to the previous method.
                return GetAllTextInSlide(slidePart);
            }
        }
    }

    // Else, return null.
    return [];
}

El segmento de código siguiente muestra el tercer método sobrecargado, que toma la parte de diapositivas que se pasó y devuelve al segundo método sobrecargado una matriz de cadenas de párrafos de texto. Primero comprueba la existencia de la parte de diapositivas que se pasó y, a continuación, crea una lista vinculada de cadenas. Recorre en iteración los párrafos de la diapositiva pasada y, al usar un StringBuilder objeto para concatenar todas las líneas de texto de un párrafo, asigna cada párrafo a una cadena de la lista vinculada. Luego, devuelve al segundo método sobrecargado una matriz de cadenas que representa todo el texto de la diapositiva especificada de la presentación.

static string[] GetAllTextInSlide(SlidePart slidePart)
{
    // Verify that the slide part exists.
    if (slidePart is null)
    {
        throw new ArgumentNullException("slidePart");
    }

    // Create a new linked list of strings.
    LinkedList<string> texts = new LinkedList<string>();

    // If the slide exists...
    if (slidePart.Slide is not null)
    {
        // Iterate through all the paragraphs in the slide.
        foreach (DocumentFormat.OpenXml.Drawing.Paragraph paragraph in
            slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
        {
            // Create a new string builder.                    
            StringBuilder paragraphText = new StringBuilder();

            // Iterate through the lines of the paragraph.
            foreach (DocumentFormat.OpenXml.Drawing.Text text in
                paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
            {
                // Append each line to the previous lines.
                paragraphText.Append(text.Text);
            }

            if (paragraphText.Length > 0)
            {
                // Add each paragraph to the linked list.
                texts.AddLast(paragraphText.ToString());
            }
        }
    }

    // Return an array of strings.
    return texts.ToArray();
}

Código de ejemplo

A continuación se proporciona el código de ejemplo completo que se puede usar para obtener todo el texto de una diapositiva específica de un archivo de presentación. Por ejemplo, puede usar el siguiente foreach bucle en el programa para obtener la matriz de cadenas devuelta por el método GetAllTextInSlide, que representa el texto de la diapositiva en el índice del archivo de slideIndex presentación que se encuentra en filePath.

foreach (string text in GetAllTextInSlide(filePath, int.Parse(slideIndex)))
{
    Console.WriteLine(text);
}

A continuación se incluye el código de ejemplo completo en C# y Visual Basic.

// Get all the text in a slide.
public static string[] GetAllTextInSlide(string presentationFile, int slideIndex)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation and the slide index
        // to the next GetAllTextInSlide method, and
        // then return the array of strings it returns. 
        return GetAllTextInSlide(presentationDocument, slideIndex);
    }
}
static string[] GetAllTextInSlide(PresentationDocument presentationDocument, int slideIndex)
{
    // Verify that the slide index is not out of range.
    if (slideIndex < 0)
    {
        throw new ArgumentOutOfRangeException("slideIndex");
    }

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

    // Verify that the presentation part and presentation exist.
    if (presentationPart is not null && presentationPart.Presentation is not null)
    {
        // Get the Presentation object from the presentation part.
        Presentation presentation = presentationPart.Presentation;

        // Verify that the slide ID list exists.
        if (presentation.SlideIdList is not null)
        {
            // Get the collection of slide IDs from the slide ID list.
            DocumentFormat.OpenXml.OpenXmlElementList slideIds = presentation.SlideIdList.ChildElements;

            // If the slide ID is in range...
            if (slideIndex < slideIds.Count)
            {
                // Get the relationship ID of the slide.
                string? slidePartRelationshipId = ((SlideId)slideIds[slideIndex]).RelationshipId;

                if (slidePartRelationshipId is null)
                {
                    return [];
                }

                // Get the specified slide part from the relationship ID.
                SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);

                // Pass the slide part to the next method, and
                // then return the array of strings that method
                // returns to the previous method.
                return GetAllTextInSlide(slidePart);
            }
        }
    }

    // Else, return null.
    return [];
}
static string[] GetAllTextInSlide(SlidePart slidePart)
{
    // Verify that the slide part exists.
    if (slidePart is null)
    {
        throw new ArgumentNullException("slidePart");
    }

    // Create a new linked list of strings.
    LinkedList<string> texts = new LinkedList<string>();

    // If the slide exists...
    if (slidePart.Slide is not null)
    {
        // Iterate through all the paragraphs in the slide.
        foreach (DocumentFormat.OpenXml.Drawing.Paragraph paragraph in
            slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
        {
            // Create a new string builder.                    
            StringBuilder paragraphText = new StringBuilder();

            // Iterate through the lines of the paragraph.
            foreach (DocumentFormat.OpenXml.Drawing.Text text in
                paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
            {
                // Append each line to the previous lines.
                paragraphText.Append(text.Text);
            }

            if (paragraphText.Length > 0)
            {
                // Add each paragraph to the linked list.
                texts.AddLast(paragraphText.ToString());
            }
        }
    }

    // Return an array of strings.
    return texts.ToArray();
}

Recursos adicionales