Share via


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 Office Open XML se almacena como un paquete, cuyo formato se define mediante ISO/IEC 29500-2. 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, comience por la apertura del archivo de procesamiento de texto mediante la creación de una instancia de la clase WordprocessingDocument como se muestra en la siguiente instrucción using. En la misma instrucción, abra el archivo de procesamiento de texto document mediante el método Open con el parámetro Boolean establecido en verdadero para habilitar la edición del documento.

    using (WordprocessingDocument wordDoc = 
            WordprocessingDocument.Open(document, true))
    {
        // Insert other code here.
    }

La instrucción using proporciona una alternativa recomendada a la típica secuencia .Open, .Save, .Close. Garantiza que se llamará automáticamente al método Dispose (un método interno que Open XML SDK usa para limpiar recursos) cuando se llegue a 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, en este caso wordDoc. Dado que la clase WordprocessingDocument en Open XML SDK guarda y cierra el objeto automáticamente como parte de su implementación System.IDisposable y que se llama automáticamente a Dispose cuando sale del bloque, no necesita llamar explícitamente a Save y Close, siempre que use using.

Procedimiento para cambiar el tema en un paquete de Word

Si desea cambiar el tema en un documento de Word, haga clic en Diseño de página de la cinta de opciones 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 de 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 consta de los esquemas 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, vemos cómo un tema puede afectar a la fuente, los colores, los fondos, los rellenos y los efectos de los distintos objetos de una presentación. Fin del ejemplo]

© ISO/IEC29500: 2008.

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 elemento themeElements es la parte que contiene el formato principal definido en el tema. Las demás partes proporcionan invalidaciones, valores predeterminados y adiciones a la información de 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 incluye 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 objeto wordDoc y eliminar la parte de tema anterior.

    public static void ReplaceTheme(string document, string themeFile)
    {
        using (WordprocessingDocument wordDoc =
            WordprocessingDocument.Open(document, true))
        {
            MainDocumentPart mainPart = wordDoc.MainDocumentPart;

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

A continuación, puede crear un nuevo objeto ThemePart y agregarlo al objeto MainDocumentPart. A continuación, agregue contenido mediante un StreamReader y StreamWriter objetos para copiar el tema del themeFile al objeto 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());
    }

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, que permite copiar el tema del archivo "Theme1.xml" al archivo "MyPkg7.docx".

    string document = @"C:\Users\Public\Documents\\MyPkg7.docx";
    string themeFile = @"C:\Users\Public\Documents\Theme1.xml";
    ReplaceTheme(document, themeFile);

Después de ejecutar el programa, abra el archivo de Word y observe el cambio de fuente.

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

using DocumentFormat.OpenXml.Packaging;
using System;
using System.IO;

ReplaceTheme(args[0], args[1]);

// 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 is null || wordDoc.MainDocumentPart.Document.Body is null || 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());
        }
    }
}