Crear un estilo de carácter y agregarlo a un documento de procesamiento de texto
En este tema se muestra cómo usar las clases del SDK de Open XML para Office para crear y agregar mediante programación un estilo de carácter a un documento de procesamiento de texto. Se incluye un método de ejemplo CreateAndAddCharacterStyle para ilustrar la tarea, además de un método de ejemplo complementario para agregar la parte de estilos cuando sea necesario.
Método CreateAndAddCharacterStyle
El método de ejemplo CreateAndAddCharacterStyle puede usarse para agregar un estilo a un documento de procesamiento de texto. Primero debe obtener una referencia a la parte de definiciones de estilo del documento al que desea agregar el estilo. Vea un ejemplo que muestra cómo hacerlo en la sección "Llamar al método de ejemplo".
El método acepta cuatro parámetros, que indican: una referencia a la parte de definiciones de estilo, el Id. del estilo (un identificador interno), el nombre del estilo (para uso externo en la interfaz de usuario) y, opcionalmente, cualquier alias de estilo (nombres alternativos usados en la interfaz de usuario).
public static void CreateAndAddCharacterStyle(StyleDefinitionsPart styleDefinitionsPart,
string styleid, string stylename, string aliases="")
Encontrará el listado completo de códigos para el método en la sección Código de ejemplo.
Acerca de los identificadores de estilo, nombres de estilo y alias
El documento usa el Id. de estilo para hacer referencia al estilo, y puede considerarse su principal identificador. Normalmente, el Id. de estilo se usa para identificar un estilo en el código. Un estilo puede también tener otro nombre que se muestre en la interfaz de usuario. Por lo tanto, el nombre de estilo aparece con frecuencia con el tamaño de letra correspondiente y con espacio (por ejemplo, Título 1), mientras que el Id. de estilo es más conciso (por ejemplo, título1) y está destinado a uso interno. Los alias especifican nombres de estilo alternativos que se pueden usar en la interfaz de usuario de una aplicación.
Por ejemplo, considere el siguiente ejemplo de código XML tomado de la definición de un estilo.
<w:style w:type="character" w:styleId="OverdueAmountChar" . . .
<w:aliases w:val="Late Due, Late Amount" />
<w:name w:val="Overdue Amount Char" />
. . .
</w:style>
El atributo styleId del elemento de estilo define el principal identificador interno del estilo, el Id. de estilo (OverdueAmountChar). El elemento de alias especifica dos nombres de estilo alternativos, Late Due y Late Amount, que están separados por comas. Cada nombre debe estar separado por una o más comas. Por último, el elemento name especifica el nombre de estilo principal, que es el que normalmente se muestra en la interfaz de usuario de una aplicación.
Llamar al método de ejemplo
Puede usar el método de ejemplo CreateAndAddCharacterStyle para crear y agregar un estilo especificado a un documento de procesamiento de texto mediante el SDK de Open XML. El siguiente código de ejemplo muestra cómo abrir y obtener una referencia a un documento de procesamiento de texto, recuperar una referencia a la parte de definiciones de estilo del documento y, después, llamar al método CreateAndAddCharacterStyle.
Para llamar al método, pase una referencia a la parte de definiciones de estilo como primer parámetro, el Id. de estilo como segundo parámetro, el nombre del estilo como tercer parámetro y, opcionalmente, cualquier alias como cuarto parámetro. A modo de ejemplo, el siguiente código crea el estilo de carácter "Overdue Amount Char" en un archivo de ejemplo de nombre "CreateAndAddCharacterStyle.docx". También crea tres ejecuciones de texto en un párrafo y aplica el estilo a la segunda ejecución.
string strDoc = @"C:\Users\Public\Documents\CreateAndAddCharacterStyle.docx";
using (WordprocessingDocument doc =
WordprocessingDocument.Open(strDoc, true))
{
// Get the Styles part for this document.
StyleDefinitionsPart part =
doc.MainDocumentPart.StyleDefinitionsPart;
// If the Styles part does not exist, add it.
if (part == null)
{
part = AddStylesPartToPackage(doc);
}
// Create and add the character style with the style id, style name, and
// aliases specified.
CreateAndAddCharacterStyle(part,
"OverdueAmountChar",
"Overdue Amount Char",
"Late Due, Late Amount");
// Add a paragraph with a run with some text.
Paragraph p =
new Paragraph(
new Run(
new Text("this is some text "){Space = SpaceProcessingModeValues.Preserve}));
// Add another run with some text.
p.AppendChild<Run>(new Run(new Text("in a run "){Space = SpaceProcessingModeValues.Preserve}));
// Add another run with some text.
p.AppendChild<Run>(new Run(new Text("in a paragraph."){Space = SpaceProcessingModeValues.Preserve}));
// Add the paragraph as a child element of the w:body.
doc.MainDocumentPart.Document.Body.AppendChild(p);
// Get a reference to the second run (indexed starting with 0).
Run r = p.Descendants<Run>().ElementAtOrDefault(1);
// If the Run has no RunProperties object, create one.
if (r.Elements<RunProperties>().Count() == 0)
{
r.PrependChild<RunProperties>(new RunProperties());
}
// Get a reference to the RunProperties.
RunProperties rPr = r.RunProperties;
// Set the character style of the run.
if (rPr.RunStyle == null)
rPr.RunStyle = new RunStyle();
rPr.RunStyle.Val = "OverdueAmountChar";
Tipos de estilo
WordprocessingML admite seis tipos de estilo, cuatro de los cuales puede especificar mediante el atributo de tipo en el elemento style. La siguiente información, de la sección 17.7.4.17 de la especificación ISO/IEC 29500, presenta tipos de estilo.
Tipos de estilo se refiere a la propiedad en un estilo que define el tipo de estilo creado con esta definición de estilo. WordprocessingML admite seis tipos de definiciones de estilo mediante los valores para el atributo de tipo de definición de estilo:
- Estilos de párrafo
- Estilos de carácter
- Estilos vinculados (párrafo + carácter) Realizados a través del elemento link (§17.7.4.6).
- Estilos de tabla
- Estilos de numeración
- Párrafo predeterminado + propiedades de carácter
Considere un estilo denominado Título 1 en un documento como se muestra en el ejemplo de código siguiente.
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1"/>
<w:basedOn w:val="Normal"/>
<w:next w:val="Normal"/>
<w:link w:val="Heading1Char"/>
<w:uiPriority w:val="1"/>
<w:qformat/>
<w:rsid w:val="00F303CE"/>
…
</w:style>
El atributo de tipo tiene un valor de párrafo, que indica que la siguiente definición de estilo es un estilo de párrafo.
Puede configurar los tipos de estilo de párrafo, carácter, tabla y numeración especificando el valor correspondiente en el atributo de tipo del elemento de estilo.
Tipo de estilo de carácter
Especifique el carácter como tipo de estilo configurando el valor del atributo de tipo del elemento de estilo como "character".
La siguiente información extraída de la sección 17.7.9 de la especificación ISO/IEC 29500 analiza los estilos de carácter. Tenga en cuenta que los números de sección precedidos de § indican secciones de la especificación ISO.
17.7.9 Estilos de ejecución (carácter)
Los estilos de caracteres son estilos que se aplican al contenido de una o varias ejecuciones de texto dentro del contenido de un documento. Esta definición implica que el estilo solo puede definir propiedades de carácter (propiedades que se aplican al texto de un párrafo) porque no se puede aplicar a párrafos. Solo las ejecuciones de un documento pueden hacer referencia a estilos de carácter, y será el elemento rStyle de las propiedades de una ejecución el que haga referencia a ellos.
Un estilo de carácter tiene dos características que definen el tipo de estilo:
El atributo de tipo del estilo tiene un valor de carácter, que indica que la siguiente definición de estilo es un estilo de carácter.
El estilo solo especifica propiedades de carácter mediante el elemento rPr. En este caso, las propiedades de ejecución son el conjunto de propiedades aplicadas a cada ejecución de este estilo.
El estilo de carácter se aplica después a ejecuciones haciendo referencia al valor del atributo styleId para dicho estilo en el elemento rStyle de las propiedades de ejecución.
La siguiente imagen muestra texto al que se le ha aplicado un estilo de carácter. Un estilo de carácter solo se puede aplicar a texto de subpárrafos.
Figura 1. Texto con un estilo de carácter aplicado
Funcionamiento del código
El método CreateAndAddCharacterStyle empieza recuperando una referencia al elemento de estilos de la parte de estilos. El elemento de estilos es el elemento raíz de la parte y contiene cada uno de los elementos de estilo. Si la referencia es nula, el elemento styles se crea y se guarda en la parte.
// Get access to the root element of the styles part.
Styles styles = styleDefinitionsPart.Styles;
if (styles == null)
{
styleDefinitionsPart.Styles = new Styles();
styleDefinitionsPart.Styles.Save();
}
Crear el estilo
Para crear el estilo, el código crea una instancia de la clase Style y establece ciertas propiedades, como Type of style (paragraph), StyleId y si el estilo es customStyle.
// Create a new character style and specify some of the attributes.
Style style = new Style()
{
Type = StyleValues.Character,
StyleId = styleid,
CustomStyle = true
};
El código genera el siguiente XML.
<w:style w:type="character" w:styleId="OverdueAmountChar" w:customStyle="true" xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
</w:style>
Después, el código crea los elementos secundarios del estilo, que definen sus propiedades. Para crear un elemento, cree una instancia de la clase correspondiente y, luego, llame al método Append([]) para agregar el elemento secundario al estilo. Para obtener más información sobre estas propiedades, consulte la sección 17.7 de la especificación ISO/IEC 29500 .
// Create and add the child elements (properties of the style).
Aliases aliases1 = new Aliases() { Val = aliases };
StyleName styleName1 = new StyleName() { Val = stylename };
LinkedStyle linkedStyle1 = new LinkedStyle() { Val = "OverdueAmountPara" };
if (aliases != "")
style.Append(aliases1);
style.Append(styleName1);
style.Append(linkedStyle1);
A continuación, el código crea una instancia de un objeto StyleRunProperties para crear un elemento rPr (propiedades de segmento). Debe especificar las propiedades del carácter que se aplican al estilo, como la fuente y el color, en este elemento. A continuación, las propiedades se anexan como elementos secundarios del elemento rPr.
Cuando se crean las propiedades de segmento, el código anexa el elemento rPr al estilo y el elemento de estilo al elemento raíz styles en la parte styles.
// Create the StyleRunProperties object and specify some of the run properties.
StyleRunProperties styleRunProperties1 = new StyleRunProperties();
Bold bold1 = new Bold();
Color color1 = new Color() { ThemeColor = ThemeColorValues.Accent2 };
RunFonts font1 = new RunFonts() { Ascii = "Tahoma" };
Italic italic1 = new Italic();
// Specify a 24 point size.
FontSize fontSize1 = new FontSize() { Val = "48" };
styleRunProperties1.Append(font1);
styleRunProperties1.Append(fontSize1);
styleRunProperties1.Append(color1);
styleRunProperties1.Append(bold1);
styleRunProperties1.Append(italic1);
// Add the run properties to the style.
style.Append(styleRunProperties1);
// Add the style to the styles part.
styles.Append(style);
El siguiente XML muestra el estilo final generado por el código que se muestra en este caso.
<w:style w:type="character" w:styleId="OverdueAmountChar" w:customStyle="true" xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:aliases w:val="Late Due, Late Amount" />
<w:name w:val="Overdue Amount Char" />
<w:link w:val="OverdueAmountPara" />
<w:rPr>
<w:rFonts w:ascii="Tahoma" />
<w:sz w:val="48" />
<w:color w:themeColor="accent2" />
<w:b />
<w:i />
</w:rPr>
</w:style>
Aplicar el estilo de carácter
Una vez creado el estilo, puede aplicarlo a una ejecución haciendo referencia al valor del atributo styleId para este estilo en el elemento rStyle de las propiedades de ejecución. El siguiente código de ejemplo muestra cómo aplicar un estilo a una ejecución a la que hace referencia la variable r. El Id. del estilo que se va a aplicar, OverdueAmountChar en este ejemplo, se almacena en la propiedad RunStyle del objeto rPr. Esta propiedad representa el elemento rStyle de las propiedades de ejecución.
// If the Run has no RunProperties object, create one.
if (r.Elements<RunProperties>().Count() == 0)
{
r.PrependChild<RunProperties>(new RunProperties());
}
// Get a reference to the RunProperties.
RunProperties rPr = r.RunProperties;
// Set the character style of the run.
if (rPr.RunStyle == null)
rPr.RunStyle = new RunStyle();
rPr.RunStyle.Val = "OverdueAmountChar";
Código de ejemplo
A continuación figura el código de ejemplo CreateAndAddCharacterStyle completo en C# y Visual Basic.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
CreateAndAddCharacterStyle(args[0], args[1], args[2], args[3]);
// Create a new character style with the specified style id, style name and aliases and
// add it to the specified style definitions part.
static void CreateAndAddCharacterStyle(string filePath, string styleid, string stylename, string aliases = "")
{
using (WordprocessingDocument wordprocessingDocument = WordprocessingDocument.Open(filePath, true))
{
// Get access to the root element of the styles part.
Styles? styles = wordprocessingDocument?.MainDocumentPart?.StyleDefinitionsPart?.Styles ?? AddStylesPartToPackage(wordprocessingDocument).Styles;
if (styles is not null)
{
// Create a new character style and specify some of the attributes.
Style style = new Style()
{
Type = StyleValues.Character,
StyleId = styleid,
CustomStyle = true
};
// Create and add the child elements (properties of the style).
Aliases aliases1 = new Aliases() { Val = aliases };
StyleName styleName1 = new StyleName() { Val = stylename };
LinkedStyle linkedStyle1 = new LinkedStyle() { Val = "OverdueAmountPara" };
if (aliases != "")
style.Append(aliases1);
style.Append(styleName1);
style.Append(linkedStyle1);
// Create the StyleRunProperties object and specify some of the run properties.
StyleRunProperties styleRunProperties1 = new StyleRunProperties();
Bold bold1 = new Bold();
Color color1 = new Color() { ThemeColor = ThemeColorValues.Accent2 };
RunFonts font1 = new RunFonts() { Ascii = "Tahoma" };
Italic italic1 = new Italic();
// Specify a 24 point size.
FontSize fontSize1 = new FontSize() { Val = "48" };
styleRunProperties1.Append(font1);
styleRunProperties1.Append(fontSize1);
styleRunProperties1.Append(color1);
styleRunProperties1.Append(bold1);
styleRunProperties1.Append(italic1);
// Add the run properties to the style.
style.Append(styleRunProperties1);
// Add the style to the styles part.
styles.Append(style);
}
}
}
// Add a StylesDefinitionsPart to the document. Returns a reference to it.
static StyleDefinitionsPart AddStylesPartToPackage(WordprocessingDocument? doc)
{
StyleDefinitionsPart part;
if (doc?.MainDocumentPart is null)
{
throw new ArgumentNullException("MainDocumentPart is null.");
}
part = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
Styles root = new Styles();
root.Save(part);
return part;
}