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:
1 2 3 4 5 6 7 8 9 10 11 |
# 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:
1 2 3 4 5 6 7 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
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:
1 2 3 4 5 |
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:
1 2 3 |
doc = Document() styles = doc.styles print(styles) |
Lo anterior mostrará algo como:
1 |
<docx.styles.styles.Styles object at 0x7fa5260e1d50> |
Si inspecciono lo que hay en el objeto Styles
:
1 |
print(dir(styles)) |
Veo lo siguiente:
1 2 3 4 5 6 7 8 9 |
['__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:
1 2 |
for t in WD_STYLE_TYPE.__members__: print(t.name, styles.default(t.value)) |
Lo anterior mostrará en pantalla:
1 2 3 4 |
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:
1 2 3 4 5 6 7 8 9 10 |
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á:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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:
1 2 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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:
1 2 3 4 |
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.