Compartir a través de


Reemplazar la parte del tema en un documento de procesamiento de texto

En este tema se muestra cómo usar las clases del SDK de Open XML para Office para reemplazar mediante programación un elemento de documento en un documento de procesamiento de texto.

Partes de documento y paquetes

Un documento Open XML se almacena como un paquete, cuyo formato está definido por ISO/IEC 29500. El paquete puede incluir varias partes con relaciones entre ellas. La relación entre las partes controla la categoría del documento. Un documento puede definirse como un documento de procesamiento de texto si su elemento de relación de paquete contiene una relación con una parte de documento principal. Si su elemento de relación de paquete contiene una relación con una parte de presentación, puede definirse como un documento de presentación. Si su elemento de relación de paquete contiene una relación con una parte de libro, se define como un documento de hoja de cálculo. En este tema sobre procedimientos se usará un paquete de documentos de procesamiento de texto.

Obtención de un objeto WordprocessingDocument

En el código de ejemplo, empiece abriendo el archivo de procesamiento de texto creando una instancia de la WordprocessingDocument clase como se muestra en la instrucción siguiente using . En la misma instrucción, se abre el documento de archivo de procesamiento de texto mediante el Open método , con el parámetro booleano establecido true en para habilitar la edición del documento.

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))

Con v3.0.0+ el Close() método se ha quitado en favor de confiar en la instrucción using. Garantiza que se llama automáticamente al Dispose() método cuando se alcanza la llave de cierre. El bloque que sigue a la instrucción using establece un ámbito para el objeto que se crea o se nombra en la instrucción using. Dado que la WordprocessingDocument clase del SDK de Open XML guarda y cierra automáticamente el objeto como parte de su IDisposable implementación y, dado Dispose() que se llama automáticamente al salir del bloque, no es necesario llamar Save() explícitamente o siempre que Dispose() use una using instrucción.

Procedimiento para cambiar el tema en un paquete de Word

Si desea cambiar el tema en un documento Word, haga clic en la cinta diseño y, a continuación, haga clic en Temas. Se abrirá el menú desplegable Temas. Para elegir uno de los temas integrados y aplicarlo al documento Word, haga clic en el icono de tema. También puede usar la opción Buscar temas... para encontrar y aplicar un archivo de tema en el equipo.

Estructura del elemento theme

El elemento theme está constituido por combinaciones de color, fuente y formato. En este procedimiento se explica cómo cambiar el tema mediante programación. Por este motivo, se recomienda que se familiarice con el elemento theme. La siguiente información de la especificación ISO/IEC 29500 puede ser útil al trabajar con este elemento.

Este elemento define el tipo complejo de nivel raíz asociado a una hoja de estilos compartida (o tema). Este elemento contiene todas las distintas opciones de formato disponibles para un documento a través de un tema y define la apariencia general del documento cuando se usan objetos con tema en el documento.

[Ejemplo: considere la siguiente imagen como un ejemplo de diferentes temas en uso aplicados a una presentación. En este ejemplo, puede ver cómo un tema afecta a la fuente, los colores, los fondos, los rellenos y los efectos de los distintos objetos de una presentación. Fin del ejemplo]

Ejemplo de tema

En este ejemplo, se observa cómo puede afectar un tema a la fuente, los colores, los fondos, los rellenos y los efectos de distintos objetos de una presentación. Fin del ejemplo]

© ISO/IEC 29500: 2016

En la siguiente tabla se enumeran los posibles tipos secundarios de la clase Theme.

Elemento de PresentationML Open XML SDK (clase) Descripción
<custClrLst/> CustomColorList Lista de colores personalizados
<extLst/> ExtensionList Lista de extensiones
<extraClrSchemeLst/> ExtraColorSchemeList Lista de combinaciones de colores adicionales
<objectDefaults/> ObjectDefaults Valores predeterminados de objeto
<themeElements/> ThemeElements Elementos theme

El siguiente fragmento de esquema XML define las cuatro partes del elemento theme. El themeElements elemento es la pieza que contiene el formato principal definido dentro del tema. Las demás partes proporcionan invalidaciones, valores predeterminados y adiciones a la información contenida en themeElements. El tipo complejo que define un tema, CT_OfficeStyleSheet, se define de la siguiente manera:

    <complexType name="CT_OfficeStyleSheet">
       <sequence>
           <element name="themeElements" type="CT_BaseStyles" minOccurs="1" maxOccurs="1"/>
           <element name="objectDefaults" type="CT_ObjectStyleDefaults" minOccurs="0" maxOccurs="1"/>
           <element name="extraClrSchemeLst" type="CT_ColorSchemeList" minOccurs="0" maxOccurs="1"/>
           <element name="custClrLst" type="CT_CustomColorList" minOccurs="0" maxOccurs="1"/>
           <element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
       </sequence>
       <attribute name="name" type="xsd:string" use="optional" default=""/>
    </complexType>

Este tipo complejo también contiene un CT_OfficeArtExtensionList, que se usa para la extensibilidad futura de este tipo complejo.

Funcionamiento del código de ejemplo

Después de abrir el archivo, puede crear una instancia de MainDocumentPart en el wordDoc objeto y eliminar la parte del tema anterior.

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
    if (wordDoc?.MainDocumentPart?.ThemePart is null)
    {
        throw new ArgumentNullException("MainDocumentPart and/or Body and/or ThemePart is null.");
    }

    MainDocumentPart mainPart = wordDoc.MainDocumentPart;

    // Delete the old document part.
    mainPart.DeletePart(mainPart.ThemePart);

A continuación, puede crear agregar un nuevo ThemePart objeto y agregarlo al MainDocumentPart objeto . A continuación, agregue contenido mediante objetos StreamReader y StreamWriter para copiar el tema del themeFile objeto al ThemePart objeto .

// Add a new document part and then add content.
ThemePart themePart = mainPart.AddNewPart<ThemePart>();

using (StreamReader streamReader = new StreamReader(themeFile))
using (StreamWriter streamWriter = new StreamWriter(themePart.GetStream(FileMode.Create)))
{
    streamWriter.Write(streamReader.ReadToEnd());
}

Código de ejemplo

En el siguiente ejemplo de código se muestra cómo reemplazar la parte de documento de tema en un documento de procesamiento de texto con la parte de tema de otro paquete. El archivo de tema pasado como el segundo argumento debe ser una parte de tema válido en formato XML (por ejemplo, Theme1.xml). Puede extraer esta parte de un documento o archivo de tema existente (.THMX) cuyo nombre se haya cambiado para que sea un archivo .zip. Para llamar al método ReplaceTheme , puede usar el siguiente ejemplo de llamada para copiar el tema del archivo desde arg[1] y hacia el archivo ubicado en arg[0]

string document = args[0];
string themeFile = args[1];

ReplaceTheme(document, themeFile);

Después de ejecutar el programa, abra el archivo Word y observe que el nuevo tema cambia.

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

// This method can be used to replace the theme part in a package.
static void ReplaceTheme(string document, string themeFile)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
    {
        if (wordDoc?.MainDocumentPart?.ThemePart is null)
        {
            throw new ArgumentNullException("MainDocumentPart and/or Body and/or ThemePart is null.");
        }

        MainDocumentPart mainPart = wordDoc.MainDocumentPart;

        // Delete the old document part.
        mainPart.DeletePart(mainPart.ThemePart);
        // Add a new document part and then add content.
        ThemePart themePart = mainPart.AddNewPart<ThemePart>();

        using (StreamReader streamReader = new StreamReader(themeFile))
        using (StreamWriter streamWriter = new StreamWriter(themePart.GetStream(FileMode.Create)))
        {
            streamWriter.Write(streamReader.ReadToEnd());
        }
    }
}

Recursos adicionales