Abrir un documento de la presentación para el acceso de solo lectura
En este tema se describe cómo usar las clases del SDK de Open XML para Office para abrir mediante programación un documento de presentación para el acceso de solo lectura.
Procedimiento para abrir un archivo de acceso de solo lectura
Es posible que desee abrir un documento de presentación para leer las diapositivas. Es posible que desee extraer información de una diapositiva, copiar una diapositiva en una biblioteca de diapositivas o enumerar los títulos de las diapositivas. En tales casos, quiere hacerlo de forma que se asegure de que el documento permanece sin cambios. Para ello, abra el documento para el acceso de solo lectura. En este tema How-To se describen varias maneras de abrir mediante programación un documento de presentación de solo lectura.
Creación de una instancia de la clase PresentationDocument
En Open XML SDK, la clase PresentationDocument representa un paquete de documentos de presentación. Para trabajar con un documento de presentación, debe crear primero una instancia de la clase PresentationDocument y, a continuación, trabajar con esa instancia. Para crear la instancia de clase a partir del documento, llame a uno de los métodos Open . Se proporcionan varios métodos Open, cada uno con una firma diferente. La siguiente tabla contiene un subconjunto de las sobrecargas para el método Open que puede usar para abrir el paquete.
Nombre | Descripción |
---|---|
Open(String, Boolean) | Cree una nueva instancia de la clase PresentationDocument desde el archivo especificado. |
Open(Stream, Boolean) | Cree una nueva instancia de la clase PresentationDocument desde la secuencia de E/S. |
Open(Package) | Cree una nueva instancia de la clase PresentationDocument desde el paquete especificado. |
La tabla anterior incluye dos métodos Open que aceptan un valor booleano como el segundo parámetro para especificar si se puede editar el documento. Para abrir un documento de acceso de solo lectura, especifique el valor false para este parámetro.
Por ejemplo, puede abrir el archivo de presentación como de solo lectura y asignarlo a un objeto PresentationDocument como se muestra en la siguiente instrucción using. En este código, el parámetro presentationFile es una cadena que representa la ruta del archivo desde donde desea abrir el documento.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Insert other code here.
}
También puede usar la segunda sobrecarga del método Open en la tabla anterior para crear una instancia de la clase PresentationDocument basada en el flujo de entrada y salida. Puede usar este enfoque si tiene una aplicación Microsoft SharePoint Foundation 2010 que usa E/S de secuencia y desea usar el SDK de Open XML para trabajar con un documento. El segmento de código siguiente abre un documento en base a un flujo.
Stream stream = File.Open(strDoc, FileMode.Open);
using (PresentationDocument presentationDocument =
PresentationDocument.Open(stream, false))
{
// Place other code here.
}
Supongamos que tiene una aplicación que emplea la compatibilidad con Open XML en el espacio de nombres System.IO.Packaging de la biblioteca de clases de .NET Framework y que desea usar el SDK de Open XML para trabajar con un paquete de solo lectura. El SDK de Open XML incluye una sobrecarga de método que acepta un paquete como único parámetro. Ningún parámetro Boolean indica si el documento debe o no abrirse para su edición. Se recomienda abrir el paquete en modo de solo lectura antes de crear la instancia de la clase PresentationDocument. El segmento de código siguiente lleva a cabo esta operación.
Package presentationPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read);
using (PresentationDocument presentationDocument =
PresentationDocument.Open(presentationPackage))
{
// Other code goes here.
}
Estructura básica de un documento de presentación
La estructura básica de un documento PresentationML consta de varias partes, entre las que se encuentra la parte principal que contiene la definición de la presentación. El siguiente texto de la especificación ISO/IEC 29500 presenta la forma general de un paquete de PresentationML.
La parte principal de un paquete PresentationML 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 documento PresentationML puede incluir son las siguientes: animación, audio, vídeo y transiciones entre diapositivas .
Los documentos PresentationML no se almacenan como un gran cuerpo en una sola parte. En su lugar, los elementos que implementan ciertas agrupaciones de funcionalidades se almacenan en partes independientes. Por ejemplo, todos los comentarios de un documento se almacenan en una parte de comentarios mientras que cada diapositiva cuenta con su propia parte.
© ISO/IEC29500: 2008.
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 DocumentFormat.OpenXml.Presentation . En la tabla siguiente se enumeran los nombres de las clases que corresponden a los elementos sld, sldLayout, sldMaster y notesMaster.
Elemento de PresentationML | Open XML SDK (clase) | Descripción |
---|---|---|
Sld | Diapositiva | 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
En el código de ejemplo, una vez que abra el documento de presentación en la instrucción using para acceso de solo lectura, cree una instancia de PresentationPart y abra la lista de diapositivas. A continuación, obtenga el identificador de relación de la primera diapositiva.
// Get the relationship ID of the first slide.
PresentationPart part = ppt.PresentationPart;
OpenXmlElementList slideIds = part.Presentation.SlideIdList.ChildElements;
string relId = (slideIds[index] as SlideId).RelationshipId;
Desde el identificador de relación, relId, se obtiene la parte de diapositiva y, a continuación, el texto interno de la diapositiva mediante la compilación de una cadena de texto mediante StringBuilder.
// Get the slide part from the relationship ID.
SlidePart slide = (SlidePart)part.GetPartById(relId);
// Build a StringBuilder object.
StringBuilder paragraphText = new StringBuilder();
// Get the inner text of the slide.
IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
foreach (A.Text text in texts)
{
paragraphText.Append(text.Text);
}
sldText = paragraphText.ToString();
El texto interno de la diapositiva, que es un parámetro out del método GetSlideIdAndText, se pasa al método principal que se mostrará.
Importante
[!IMPORTANTE] En este ejemplo se muestra solo el texto en el archivo de presentación. Las partes que no son de texto, como formas o gráficos, no se muestran.
Código de ejemplo
En el siguiente ejemplo se abre un archivo de presentación para el acceso de solo lectura y se obtiene el texto interno de una diapositiva en el índice especificado. Para llamar al método GetSlideIdAndText pase la ruta completa del documento de presentación. También pase el parámetro outsldText, al que se le asignará un valor en el mismo método y, a continuación, podrá mostrar el valor en el programa principal. Por ejemplo, la siguiente llamada al método GetSlideIdAndText obtiene el texto interno en la segunda diapositiva en un archivo de presentación que se denomina "Myppt13.pptx".
Sugerencia
[!SUGERENCIA] La excepción más esperada de este programa es la excepción ArgumentOutOfRangeException. Puede obtenerse si, por ejemplo, tiene un archivo con dos diapositivas y desea mostrar el texto en la diapositiva número 4. Por tanto, es mejor usar un bloque try cuando llama al método GetSlideIdAndText como se muestra en el siguiente ejemplo.
string file = @"C:\Users\Public\Documents\Myppt13.pptx";
string slideText;
int index = 1;
try
{
GetSlideIdAndText(out slideText, file, index);
Console.WriteLine("The text in the slide #{0} is: {1}", index + 1, slideText);
}
catch (ArgumentOutOfRangeException exp)
{
Console.WriteLine(exp.Message);
}
A continuación se incluye el listado de códigos completo en C# y Visual Basic.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using A = DocumentFormat.OpenXml.Drawing;
GetSlideIdAndText(out string text, args[0], int.Parse(args[1]));
static void GetSlideIdAndText(out string sldText, string docName, int index)
{
using (PresentationDocument ppt = PresentationDocument.Open(docName, false))
{
// Get the relationship ID of the first slide.
PresentationPart? part = ppt.PresentationPart;
OpenXmlElementList slideIds = part?.Presentation?.SlideIdList?.ChildElements ?? default;
// If there are no slide IDs then there are no slides.
if (slideIds.Count == 0)
{
sldText = "";
return;
}
string? relId = (slideIds[index] as SlideId)?.RelationshipId;
if (relId is null)
{
sldText = "";
return;
}
// Get the slide part from the relationship ID.
SlidePart slide = (SlidePart)part!.GetPartById(relId);
// Build a StringBuilder object.
StringBuilder paragraphText = new StringBuilder();
// Get the inner text of the slide:
IEnumerable<A.Text> texts = slide.Slide.Descendants<A.Text>();
foreach (A.Text text in texts)
{
paragraphText.Append(text.Text);
}
sldText = paragraphText.ToString();
}
}