Saltar al contenido

Escribiendo ficheros docx de Word con Python. Capítulo VII – Estilos

Hemos visto ya unas cuantas cosas: cómo es el documento y algunas de sus características, cómo incluir cabeceros y pies de página, cómo trabajar con texto, reaprovechar una serie de nombres y funcionalidad para hacer cosas un tanto más específicas,… Hoy vamos a meternos de forma superficial en los estilos y cómo podemos usarlos para ahorrarnos trabajo y dar formato dónde y cómo queremos.

Microsoft Word dispone de muchos estilos que podemos ver en la interfaz gráfica del procesador de textos. Es importante conocerlos puesto que cualquier cosa que escribamos en un documento tiene un estilo asociado. Es conveniente que sea así puesto que podemos reaprovechar una serie de características para aplicarlas en las partes del documento que necesitemos. Por ejemplo, imaginad que trabajáis en una empresa que utiliza una serie de colores en toda su documentación que son parte de su imagen corporativa. Podría ser que todas las tablas tienen un cabecero que es verde y una primera columna que es verde, que todas las celdas están centradas y la fuente es tamaño 10 Pt,… Simplemente seleccionando ese estilo predefinido podríamos aplicarlo a las tablas que necesitemos. Los estilos nos ayudan a identificar también partes del contenido. Un estilo se aplica a un cabecero, a un párrafo, a una tabla o a una lista.

Os voy a dejar esta metáfora escrita por Allen Wyatt:

“Styles are nothing more than a named definition of how text should appear. You can best understand this by comparing your text to water (this is your content). The appearance of the water depends on the attributes of the container in which it is placed. If you place it in a glass it will look one way; if you place it in a pitcher, it looks a different way. The relationship between text and styles is no different; if you change the style that has been applied to text, then the appearance of the text automatically changes.”

Que traducido libremente sería:

“Los estilos no son más que una definición de cómo debería aparecer el texto. Lo podemos entender mejor comparando nuestro texto con agua (nuestro contenido). La apariencia del agua depende de los atributos del contenedor que la contiene. Si colocas el agua en un vaso de cristal se verá de una forma, si la colocas en una jarra se verá de forma diferente. La relación entre el texto y los estilos no es diferente, si cambias el estilo que has aplicado a un texto el texto cambia de forma automática.”

Bueno, nos metemos en harina. Ya vimos en el anterior capítulo los enums que teníamos de estilos:

# hacemos unos imports
import random
import string

from docx import Document
from docx.enum.style import (
    WD_BUILTIN_STYLE, WD_STYLE, WD_STYLE_TYPE
)
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.enum.dml import MSO_COLOR_TYPE
from docx.shared import Pt, Cm, RGBColor

Voy a sacar información sobre los estilos:

builtin_style_names = [st.name for st in WD_BUILTIN_STYLE.__members__]
style_names = [st.name for st in WD_STYLE.__members__]
style_types = [st.name for st in WD_STYLE_TYPE.__members__]

print(",\t".join(builtin_style_names), end="\n\n")
print(",\t".join(style_names), end="\n\n")
print(",\t".join(style_types))

Lo anterior mostrará algo como lo siguiente:

BLOCK_QUOTATION,	BODY_TEXT,	BODY_TEXT_2,	BODY_TEXT_3,	
BODY_TEXT_FIRST_INDENT,	BODY_TEXT_FIRST_INDENT_2,	BODY_TEXT_INDENT,	
BODY_TEXT_INDENT_2,	BODY_TEXT_INDENT_3,	BOOK_TITLE,	
CAPTION,	CLOSING,	COMMENT_REFERENCE,	
COMMENT_TEXT,	DATE,	DEFAULT_PARAGRAPH_FONT,	EMPHASIS,	
ENDNOTE_REFERENCE,	ENDNOTE_TEXT,	ENVELOPE_ADDRESS,	
ENVELOPE_RETURN,	FOOTER,	FOOTNOTE_REFERENCE,	
FOOTNOTE_TEXT,	HEADER,	HEADING_1,	HEADING_2,	
HEADING_3,	HEADING_4,	HEADING_5,	HEADING_6,	
HEADING_7,	HEADING_8,	HEADING_9,	HTML_ACRONYM,	
HTML_ADDRESS,	HTML_CITE,	HTML_CODE,	HTML_DFN,	
HTML_KBD,	HTML_NORMAL,	HTML_PRE,	HTML_SAMP,	
HTML_TT,	HTML_VAR,	HYPERLINK,	
HYPERLINK_FOLLOWED,	INDEX_1,	INDEX_2,	
INDEX_3,	INDEX_4,	INDEX_5,	INDEX_6,	
INDEX_7,	INDEX_8,	INDEX_9,	INDEX_HEADING,	
INTENSE_EMPHASIS,	INTENSE_QUOTE,	INTENSE_REFERENCE,	
LINE_NUMBER,	LIST,	LIST_2,	LIST_3,	LIST_4,	LIST_5,	
LIST_BULLET,	LIST_BULLET_2,	LIST_BULLET_3,	LIST_BULLET_4,	
LIST_BULLET_5,	LIST_CONTINUE,	LIST_CONTINUE_2,	
LIST_CONTINUE_3,	LIST_CONTINUE_4,	IST_CONTINUE_5,	
LIST_NUMBER,	LIST_NUMBER_2,	LIST_NUMBER_3,	LIST_NUMBER_4,	
LIST_NUMBER_5,	LIST_PARAGRAPH,	MACRO_TEXT,	MESSAGE_HEADER,	
NAV_PANE,	NORMAL,	NORMAL_INDENT,	NORMAL_OBJECT,	
NORMAL_TABLE,	NOTE_HEADING,	PAGE_NUMBER,	PLAIN_TEXT,	
QUOTE,	SALUTATION,	SIGNATURE,	STRONG,	SUBTITLE,	
SUBTLE_EMPHASIS,	SUBTLE_REFERENCE,	ABLE_COLORFUL_GRID,	
TABLE_COLORFUL_LIST,	TABLE_COLORFUL_SHADING,	TABLE_DARK_LIST,	
TABLE_LIGHT_GRID,	TABLE_LIGHT_GRID_ACCENT_1,	TABLE_LIGHT_LIST,	
TABLE_LIGHT_LIST_ACCENT_1,	TABLE_LIGHT_SHADING,	TABLE_LIGHT_SHADING_ACCENT_1,	
TABLE_MEDIUM_GRID_1,	TABLE_MEDIUM_GRID_2,	TABLE_MEDIUM_GRID_3,	
TABLE_MEDIUM_LIST_1,	TABLE_MEDIUM_LIST_1_ACCENT_1,	TABLE_MEDIUM_LIST_2,	
TABLE_MEDIUM_SHADING_1,	TABLE_MEDIUM_SHADING_1_ACCENT_1,	TABLE_MEDIUM_SHADING_2,	
TABLE_MEDIUM_SHADING_2_ACCENT_1,	TABLE_OF_AUTHORITIES,	TABLE_OF_FIGURES,	
TITLE,	TOAHEADING,	TOC_1,	TOC_2,	TOC_3,	TOC_4,	TOC_5,	
TOC_6,	TOC_7,	TOC_8,	TOC_9

BLOCK_QUOTATION,	BODY_TEXT,	BODY_TEXT_2,	
BODY_TEXT_3,	BODY_TEXT_FIRST_INDENT,	BODY_TEXT_FIRST_INDENT_2,	
BODY_TEXT_INDENT,	BODY_TEXT_INDENT_2,	BODY_TEXT_INDENT_3,	
BOOK_TITLE,	CAPTION,	CLOSING,	COMMENT_REFERENCE,	
COMMENT_TEXT,	DATE,	DEFAULT_PARAGRAPH_FONT,	EMPHASIS,	
ENDNOTE_REFERENCE,	ENDNOTE_TEXT,	ENVELOPE_ADDRESS,	
ENVELOPE_RETURN,	FOOTER,	FOOTNOTE_REFERENCE,	
FOOTNOTE_TEXT,	HEADER,	HEADING_1,	HEADING_2,	
HEADING_3,	HEADING_4,	HEADING_5,	HEADING_6,	
HEADING_7,	HEADING_8,	HEADING_9,	HTML_ACRONYM,	
HTML_ADDRESS,	HTML_CITE,	HTML_CODE,	HTML_DFN,	
HTML_KBD,	HTML_NORMAL,	HTML_PRE,	HTML_SAMP,	
HTML_TT,	HTML_VAR,	HYPERLINK,	HYPERLINK_FOLLOWED,	
INDEX_1,	INDEX_2,	INDEX_3,	INDEX_4,	
INDEX_5,	INDEX_6,	INDEX_7,	INDEX_8,	
INDEX_9,	INDEX_HEADING,	INTENSE_EMPHASIS,	
INTENSE_QUOTE,	INTENSE_REFERENCE,	LINE_NUMBER,	LIST,	
LIST_2,	LIST_3,	LIST_4,	LIST_5,	LIST_BULLET,	LIST_BULLET_2,	
LIST_BULLET_3,	LIST_BULLET_4,	LIST_BULLET_5,	LIST_CONTINUE,	
LIST_CONTINUE_2,	LIST_CONTINUE_3,	LIST_CONTINUE_4,	
LIST_CONTINUE_5,	LIST_NUMBER,	LIST_NUMBER_2,	
LIST_NUMBER_3,	LIST_NUMBER_4,	LIST_NUMBER_5,	LIST_PARAGRAPH,	
MACRO_TEXT,	MESSAGE_HEADER,	NAV_PANE,	NORMAL,	
NORMAL_INDENT,	NORMAL_OBJECT,	NORMAL_TABLE,	NOTE_HEADING,	
PAGE_NUMBER,	PLAIN_TEXT,	QUOTE,	SALUTATION,	
SIGNATURE,	STRONG,	SUBTITLE,	SUBTLE_EMPHASIS,	
SUBTLE_REFERENCE,	TABLE_COLORFUL_GRID,	
TABLE_COLORFUL_LIST,	TABLE_COLORFUL_SHADING,	
TABLE_DARK_LIST,	TABLE_LIGHT_GRID,	
TABLE_LIGHT_GRID_ACCENT_1,	TABLE_LIGHT_LIST,	
TABLE_LIGHT_LIST_ACCENT_1,	TABLE_LIGHT_SHADING,	
TABLE_LIGHT_SHADING_ACCENT_1,	TABLE_MEDIUM_GRID_1,	
TABLE_MEDIUM_GRID_2,	TABLE_MEDIUM_GRID_3,	TABLE_MEDIUM_LIST_1,	
TABLE_MEDIUM_LIST_1_ACCENT_1,	TABLE_MEDIUM_LIST_2,	TABLE_MEDIUM_SHADING_1,	
TABLE_MEDIUM_SHADING_1_ACCENT_1,	TABLE_MEDIUM_SHADING_2,	TABLE_MEDIUM_SHADING_2_ACCENT_1,	
TABLE_OF_AUTHORITIES,	TABLE_OF_FIGURES,	TITLE,	
TOAHEADING,	TOC_1,	TOC_2,	TOC_3,	TOC_4,	TOC_5,	TOC_6,	
TOC_7,	TOC_8,	TOC_9

CHARACTER,	LIST,	PARAGRAPH,	TABLE

Hago una comprobación que comento más abajo:

for name in builtin_style_names:
    if name not in style_names: print(name)

for name in style_names:
    if name not in builtin_style_names: print(name)

Como veis, hay un montón de estilos. También podéis ver que lo que está en la enum WD_BUILTIN_STYLE está también en la enum WD_STYLE. A lo largo del tutorial voy a usar el primero porque explícito es mejor que implícito. Por último, también veis que los estilos tienen tipos que pueden ser caracter, lista, párrafo o tabla.

Inspeccionando los estilos

Cuando creamos un documento este documento tiene una serie de estilos:

doc = Document()
styles = doc.styles
print(styles)

Lo anterior mostrará algo como:

<docx.styles.styles.Styles object at 0x7fa5260e1d50>

Si inspecciono lo que hay en el objeto Styles:

print(dir(styles))

Veo lo siguiente:

['__class__', '__contains__', '__delattr__', '__dir__', '__doc__', 
 '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', 
 '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', 
 '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
 '__sizeof__', '__slots__', '__str__', '__subclasshook__', '_element', 
 '_get_by_id', '_get_style_id_from_name', '_get_style_id_from_style', 
 '_parent', 'add_style', 'default', 'element', 'get_by_id', 
 'get_style_id', 'latent_styles', 'part']

Vemos que el objeto Styles, que contiene los estilos disponibles en la plantilla base, proporciona un método default. Este método nos indica qué tipo de estilo se usoó para cada tipo de contenido:

for t in WD_STYLE_TYPE.__members__:
    print(t.name, styles.default(t.value))

Lo anterior mostrará en pantalla:

CHARACTER <docx.styles.style._CharacterStyle object at 0x7fa53c0bb250>
LIST <docx.styles.style._NumberingStyle object at 0x7fa53c0bb250>
PARAGRAPH _ParagraphStyle('Normal') id: 140347653730896
TABLE _TableStyle('Normal Table') id: 140347653730896

Vemos que el estilo de párrafo por defecto es 'Normal' y que el estilo de tabla por defecto es 'Normal Table'. El carácter, por ejemplo, no tiene un estilo explícito y hereda lo que necesita del párrafo o de la tabla en la que se encuentre a no ser que definamos un estilo para el carácter que estemos añadiendo.

Como hemos comentado, la plantilla que tenemos por defecto dispone de una serie de estilos. Vamos a ver cuáles son:

mapeo_tipos = {member.value: member.name for member in WD_STYLE_TYPE.__members__}
print(" i ",
      "Name" + " " * 21,
      "Type" + " " * 6,
      "Is Builtin")
for i, s in enumerate(styles):
    print(f"{i + 1:03} "
          f"{s.name: <25} "
          f"{mapeo_tipos[s.type]: <10} "
          f"{s.builtin:<5}")

El anterior código mostrará:

 i  Name                      Type       Is Builtin
001 Normal                    PARAGRAPH  1    
002 Header                    PARAGRAPH  1    
003 Header Char               CHARACTER  0    
004 Footer                    PARAGRAPH  1    
005 Footer Char               CHARACTER  0    
006 Heading 1                 PARAGRAPH  1    
007 Heading 2                 PARAGRAPH  1    
008 Heading 3                 PARAGRAPH  1    
009 Heading 4                 PARAGRAPH  1    
010 Heading 5                 PARAGRAPH  1    
011 Heading 6                 PARAGRAPH  1    
012 Heading 7                 PARAGRAPH  1    
013 Heading 8                 PARAGRAPH  1    
014 Heading 9                 PARAGRAPH  1    
015 Default Paragraph Font    CHARACTER  1    
016 Normal Table              TABLE      1    
017 No List                   LIST       1    
018 No Spacing                PARAGRAPH  1    
019 Heading 1 Char            CHARACTER  0    
020 Heading 2 Char            CHARACTER  0    
021 Heading 3 Char            CHARACTER  0    
022 Title                     PARAGRAPH  1    
023 Title Char                CHARACTER  0    
024 Subtitle                  PARAGRAPH  1    
025 Subtitle Char             CHARACTER  0    
026 List Paragraph            PARAGRAPH  1    
027 Body Text                 PARAGRAPH  1    
028 Body Text Char            CHARACTER  0    
029 Body Text 2               PARAGRAPH  1    
030 Body Text 2 Char          CHARACTER  0    
031 Body Text 3               PARAGRAPH  1    
032 Body Text 3 Char          CHARACTER  0    
033 List                      PARAGRAPH  1    
034 List 2                    PARAGRAPH  1    
035 List 3                    PARAGRAPH  1    
036 List Bullet               PARAGRAPH  1    
037 List Bullet 2             PARAGRAPH  1    
038 List Bullet 3             PARAGRAPH  1    
039 List Number               PARAGRAPH  1    
040 List Number 2             PARAGRAPH  1    
041 List Number 3             PARAGRAPH  1    
042 List Continue             PARAGRAPH  1    
043 List Continue 2           PARAGRAPH  1    
044 List Continue 3           PARAGRAPH  1    
045 macro                     PARAGRAPH  1    
046 Macro Text Char           CHARACTER  0    
047 Quote                     PARAGRAPH  1    
048 Quote Char                CHARACTER  0    
049 Heading 4 Char            CHARACTER  0    
050 Heading 5 Char            CHARACTER  0    
051 Heading 6 Char            CHARACTER  0    
052 Heading 7 Char            CHARACTER  0    
053 Heading 8 Char            CHARACTER  0    
054 Heading 9 Char            CHARACTER  0    
055 Caption                   PARAGRAPH  1    
056 Strong                    CHARACTER  1    
057 Emphasis                  CHARACTER  1    
058 Intense Quote             PARAGRAPH  1    
059 Intense Quote Char        CHARACTER  0    
060 Subtle Emphasis           CHARACTER  1    
061 Intense Emphasis          CHARACTER  1    
062 Subtle Reference          CHARACTER  1    
063 Intense Reference         CHARACTER  1    
064 Book Title                CHARACTER  1    
065 TOC Heading               PARAGRAPH  1    
066 Table Grid                TABLE      1    
067 Light Shading             TABLE      1    
068 Light Shading Accent 1    TABLE      1    
069 Light Shading Accent 2    TABLE      1    
070 Light Shading Accent 3    TABLE      1    
071 Light Shading Accent 4    TABLE      1    
072 Light Shading Accent 5    TABLE      1    
073 Light Shading Accent 6    TABLE      1    
074 Light List                TABLE      1    
075 Light List Accent 1       TABLE      1    
076 Light List Accent 2       TABLE      1    
077 Light List Accent 3       TABLE      1    
078 Light List Accent 4       TABLE      1    
079 Light List Accent 5       TABLE      1    
080 Light List Accent 6       TABLE      1    
081 Light Grid                TABLE      1    
082 Light Grid Accent 1       TABLE      1    
083 Light Grid Accent 2       TABLE      1    
084 Light Grid Accent 3       TABLE      1    
085 Light Grid Accent 4       TABLE      1    
086 Light Grid Accent 5       TABLE      1    
087 Light Grid Accent 6       TABLE      1    
088 Medium Shading 1          TABLE      1    
089 Medium Shading 1 Accent 1 TABLE      1    
090 Medium Shading 1 Accent 2 TABLE      1    
091 Medium Shading 1 Accent 3 TABLE      1    
092 Medium Shading 1 Accent 4 TABLE      1    
093 Medium Shading 1 Accent 5 TABLE      1    
094 Medium Shading 1 Accent 6 TABLE      1    
095 Medium Shading 2          TABLE      1    
096 Medium Shading 2 Accent 1 TABLE      1    
097 Medium Shading 2 Accent 2 TABLE      1    
098 Medium Shading 2 Accent 3 TABLE      1    
099 Medium Shading 2 Accent 4 TABLE      1    
100 Medium Shading 2 Accent 5 TABLE      1    
101 Medium Shading 2 Accent 6 TABLE      1    
102 Medium List 1             TABLE      1    
103 Medium List 1 Accent 1    TABLE      1    
104 Medium List 1 Accent 2    TABLE      1    
105 Medium List 1 Accent 3    TABLE      1    
106 Medium List 1 Accent 4    TABLE      1    
107 Medium List 1 Accent 5    TABLE      1    
108 Medium List 1 Accent 6    TABLE      1    
109 Medium List 2             TABLE      1    
110 Medium List 2 Accent 1    TABLE      1    
111 Medium List 2 Accent 2    TABLE      1    
112 Medium List 2 Accent 3    TABLE      1    
113 Medium List 2 Accent 4    TABLE      1    
114 Medium List 2 Accent 5    TABLE      1    
115 Medium List 2 Accent 6    TABLE      1    
116 Medium Grid 1             TABLE      1    
117 Medium Grid 1 Accent 1    TABLE      1    
118 Medium Grid 1 Accent 2    TABLE      1    
119 Medium Grid 1 Accent 3    TABLE      1    
120 Medium Grid 1 Accent 4    TABLE      1    
121 Medium Grid 1 Accent 5    TABLE      1    
122 Medium Grid 1 Accent 6    TABLE      1    
123 Medium Grid 2             TABLE      1    
124 Medium Grid 2 Accent 1    TABLE      1    
125 Medium Grid 2 Accent 2    TABLE      1    
126 Medium Grid 2 Accent 3    TABLE      1    
127 Medium Grid 2 Accent 4    TABLE      1    
128 Medium Grid 2 Accent 5    TABLE      1    
129 Medium Grid 2 Accent 6    TABLE      1    
130 Medium Grid 3             TABLE      1    
131 Medium Grid 3 Accent 1    TABLE      1    
132 Medium Grid 3 Accent 2    TABLE      1    
133 Medium Grid 3 Accent 3    TABLE      1    
134 Medium Grid 3 Accent 4    TABLE      1    
135 Medium Grid 3 Accent 5    TABLE      1    
136 Medium Grid 3 Accent 6    TABLE      1    
137 Dark List                 TABLE      1    
138 Dark List Accent 1        TABLE      1    
139 Dark List Accent 2        TABLE      1    
140 Dark List Accent 3        TABLE      1    
141 Dark List Accent 4        TABLE      1    
142 Dark List Accent 5        TABLE      1    
143 Dark List Accent 6        TABLE      1    
144 Colorful Shading          TABLE      1    
145 Colorful Shading Accent 1 TABLE      1    
146 Colorful Shading Accent 2 TABLE      1    
147 Colorful Shading Accent 3 TABLE      1    
148 Colorful Shading Accent 4 TABLE      1    
149 Colorful Shading Accent 5 TABLE      1    
150 Colorful Shading Accent 6 TABLE      1    
151 Colorful List             TABLE      1    
152 Colorful List Accent 1    TABLE      1    
153 Colorful List Accent 2    TABLE      1    
154 Colorful List Accent 3    TABLE      1    
155 Colorful List Accent 4    TABLE      1    
156 Colorful List Accent 5    TABLE      1    
157 Colorful List Accent 6    TABLE      1    
158 Colorful Grid             TABLE      1    
159 Colorful Grid Accent 1    TABLE      1    
160 Colorful Grid Accent 2    TABLE      1    
161 Colorful Grid Accent 3    TABLE      1    
162 Colorful Grid Accent 4    TABLE      1    
163 Colorful Grid Accent 5    TABLE      1    
164 Colorful Grid Accent 6    TABLE      1    

Algunos están contenidos en WD_BUILTIN_STYLE (para estos la columna Is Builtin vale 1) y otros no (en la columna Is Builtin vale 0). Algunos tienen tipo TABLE' o 'CHARACTER,… Ok, vamos a intentar entender esto un poco mejor.

¿Qué es un estilo built-in, un estilo latente,…?

El procesador de textos Microsoft Word, dependiendo de la versión, dispone de cientos de estilos predefinidos. Podéis ver una lista aquí. Como cada estilo predefinido ocupa espacio no todos los estilos se incluyen en el documento docx. Los estilos que son built-in pero que no se incluyen por defecto en el documento se conocen como estilos latentes (latent styles). Si usamos uno de estos estilos latentes en nuestro documento entonces se incluye una referencia al mismo en styles.xml dentro del fichero docx (ver imagen más abajo para ver la jerarquía de ficheros dentro de un fichero docx) pero no se añade el estilo latente completo. Esto se hace así para ahorrar espacio en el fichero docx. Los estilos latentes están en el propio procesador de textos (MS Word, LibreOffice, OpenOffice,…) y cuando el procesador de textos encuentra una referencia a uno de estos estilos latentes dentro del fichero docx con el que estemos trabajando sabrá cómo aplicar ese estilo latente al documento cuando lo muestra en pantalla.

Para entender todo esto un poco mejor es mejor que visitéis esta sección de la documentación: https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html

Aplicando estilos

Más de uno pensará, –Todo este rollo que nos has contado está muy bien pero, ¿cómo aplicamos los estilos a nuestro documento?-. Muy bien, ahora llegamos a eso.

Como habéis visto hay estilos que se aplican a diferentes partes del texto, estilos a nivel de párrafo, a nivel de tabla, a nivel de run o carácter,… Si una parte no tiene un estilo definido hereda el estilo de lo que lo contiene. Por ejemplo, si definimos un run dentro de un párrafo pero no le indicamos estilo al run entonces este tomará las propiedades del tamaño de fuente, tipo de fuente,…, del estilo del párrafo. Como vimos más arriba los párrafos tienen un estilo predefinido, 'Normal'.

Vamos a dejar de hablar y vamos a empezar a aplicar estilos. Voy a crear un documento con todos los estilos disponibles en la plantilla para que podamos visualizar cómo son:

doc = Document()
styles = doc.styles

tipos = {m.value: m.name for m in WD_STYLE_TYPE.__members__}
estilos = {s.name: s.type for s in styles}

def create_text(n):
    possible = (string.ascii_letters + 
                string.punctuation + 
                string.digits + 
                " " * 25) # spaces to create words
    text = random.choices(possible, k=n)
    return text

def populate_table(table):
    for col in table.columns:
        for cell in col.cells:
            cell.text = create_text(3)
    
for tk, tv in tipos.items():
    doc.add_paragraph(tv, style="Title")
    for estilo, tipo in estilos.items():
        if tipo == tk:
            doc.add_paragraph(estilo, style="Heading 1")
            if tv == "CHARACTER":
                doc.add_paragraph().add_run(create_text(10), style=estilo)
            if tv == "PARAGRAPH":
                doc.add_paragraph(create_text(200), style=estilo)
            if tv == "TABLE":
                t = doc.add_table(4, 3, style=estilo)
                populate_table(t)            
    doc.add_page_break()

doc.save("new.docx")

En el anterior código lo único que hacemos es crear texto y tablas a las cuales les aplicamos un estilo u otro dependiendo de lo que son y creamos un documento que contiene todos los estilos (menos el de listas) para que tengáis un documento que podáis visualizar. Por ejemplo, en la parte de tablas podréis ver páginas parecidas a lo siguiente:

No vamos a entrar en los detalles de todos los estilos. Podéis abrir el documento que acabamos que crear y echarle un ojo a cada uno de los que os interesen para vuestros documentos.

Usando nuestros propios estilos

Obviamente, podemos crear nuestros propios estilos con nuestra imagen corporativa. Vamos a trabajar un poco con esto para ver cómo podemos tener un documento hecho a la imagen y semejanza de nuestra empresa, marca o lo que sea.

Vamos a crear un estilo para párrafos y lo vamos a aplicar a nuestro documento. Los estilos para otras cosas seguirán una mecánica similar.

Como habitualmente, empezamos creando una nueva instancia de Document y “extrayendo” los estilos:

doc = Document()
styles = doc.styles

Vamos a crear un estilo para el párrafo. Todos los párrafos de texto normal (sin contar títulos, encabezados,…) tendrán este estilo:

mi_p_estilo = styles.add_style('Estilo Parrafo', WD_STYLE_TYPE.PARAGRAPH)
# Para curarnos en salud vamos a hacer que herede de 'Normal'
# Para que los valores que no modifiquemos tome los
# de 'Normal'
mi_p_estilo.base_style = styles['Normal']
# Lo toqueteamos para que sea como queremos
# Lo que voy a hacer es muy exagerado y solo
# lo usaré de forma educativa
mi_p_estilo.paragraph_format.space_before = Pt(20)
mi_p_estilo.paragraph_format.space_after = Pt(20)
mi_p_estilo.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY
mi_p_estilo.paragraph_format.first_line_indent = Cm(2)
mi_p_estilo.paragraph_format.line_spacing = Pt(12)
mi_p_estilo.font.color.rgb = RGBColor(100, 100, 100)
mi_p_estilo.font.size = Pt(11)
mi_p_estilo.font.name = "Comic Sans MS"

Vamos a añadir unos cuantos párrafos al documento usando este estilo y guardamos el documento:

for _ in range(5):
    doc.add_paragraph(create_text(200), style="Estilo Parrafo")

doc.save("new.docx")

Vuestro documento se debería parecer en algo al siguiente:

Vemos que la primera línea tiene una indentación de 2 cm, la separación entre párrafos por arriba y por abajo es generosa, el color es gris, usamos “Comic Sans MS” como fuente con un tamaño de 11 puntos.

Resumiendo

Los estilos son algo un tanto complejo. Aquí hemos visto un poco sobre ello para intentar entender todo un poco mejor pero lo mejor es leer la documentación de los enlaces que he ido dejando en este capítulo para entenderlo todo un poco mejor.

En general, la gente no usa estilos y va formateando el texto a medida que lo va necesitando. Mal hecho. Los estilos son muy potentes y nos permiten dar un formato coherente y homogéneo a nuestros documentos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

seventy five + = seventy eight

Pybonacci