En general, lo que hemos visto hasta ahora, lo podíamos hacer prácticamente todo desde el objeto [Document](https://pybonacci.org/2020/06/11/escribiendo-ficheros-docx-de-word-con-python-capitulo-ii-document/). Desde el mismo podemos acceder a otros objetos como los párrafos, tablas, secciones, run's,...
Pero, en el anterior capítulo, vimos que empezaron a salir algunos nombres raros como Cm, Pt o WD_PARAGRAPH_ALIGNMENT.
Vamos a importar la biblioteca y ver un poco de todo lo que dispone:
import docx
for name in dir(docx):
if not name.startswith("__"):
print(name, getattr(docx, name), end="\n"*2)
Lo anterior nos mostrará una serie de cosas.
Vemos que tenemos disponibles dos clases que no vamos a comentar y la función Document que nos crea una instancia del objeto Document (sí, se llaman igual la función y la clase), es decir, prácticamente todo lo que necesitamos lo podemos obtener con la función Document que nos devolverá el objeto instanciado. Todo lo demás que está disponible son una serie de módulos. Vamos a repasarlos por encima:
api: básicamente nos ofrece la funciónDocument.blkcntnr: aquí tenemos la claseBlockItemContainerque sirve para los contenedores como el cabecero, la celda de una tabla, el cuerpo del documento,... Dispone de métodos comoadd_paragraphoadd_table.compat: compatibilidad entre Python 2/3.dml: utilidades para trabajar con color.document: aquí es donde se define la claseDocument.enum: este lo vamos a ver a continuación algo más de detalle.exceptions: varias excepciones.image: nos proporciona objetos para trabajar con imágenes en los formatos más conocidos como tiff, jpg, bmp,...opc: utilidades para trabajar con la Open Packaging Convention.oxml: utilidades para trabajar con el Office Open XML.package: utilidades para trabajar con la Open Packaging Convention.parts: las diferentes partes que forman el documento.section: la claseSectionse encuentra aquí.settings: la claseSettingsse encuentra aquí.shape: la claseInlineShapeque usamos para añadir imágenes se encuentra aquí.shared: aquí encontramos funcionalidades que se usan por los diferentes módulos y que vamos a ver en algo más de detalle a continuación.styles: aquí se encuentran definidos los estilos y la claseStyle.text: aquí se encuentran definidas cosas comoParagraph,Table,Run.
Como veis, todo está pensado para que haya un único punto de entrada que nos sirve de proxy para acceder a las diferentes partes del documento definidas como distintas clases. El resto de la biblioteca es para poder leer y escribir el documento, comprimirlo o descomprimirlo y son cosas que no necesitamos tocar. Lo que más usamos (y haciendo el gráfico de cabeza...) sería algo así:

Además de lo anterior, lo cual hemos ido viendo por encima en anteriores secciones. hemos pasado por encima sobre algunas otras cosas que obtenemos de los módulos shared y enum.
Módulo shared
Lo más importante que tenemos en este módulo son formas de establecer tamaños o medidas de forma que el resto de la biblioteca lo pueda entender. Algunas de las clases más importantes contenidas aquí son:
from docx import shared
print(dir(shared))
Lo anterior mostrará:
['Cm', 'ElementProxy', 'Emu', 'Inches', 'Length', 'Mm', 'Parented',
'Pt', 'RGBColor', 'Twips', '__builtins__', '__cached__', '__doc__',
'__file__', '__loader__', '__name__', '__package__', '__spec__',
'absolute_import', 'lazyproperty', 'print_function',
'unicode_literals', 'write_only_property']
Cmpara establecer medidas en centímetros.Emupara medidas. 1 EMU se define como 1/360000 centímetro. 914400 EMUs por pulgada. 12700 EMUs por punto.Inches, igual pero para pulgadas.Mm, igual pero en milimetros.Pt, igual pero en puntos.Twips, para medidas. Es 1/20 de un punto. Es 1/1440 pulgadas.
Todas las clases anteriores derivan de Length.
print(shared.Twips.__bases__)
Lo anterior mostrará:
(<class 'docx.shared.Length'>,)
shared.Cm(1) == shared.Mm(10)
Mostrará:
True
shared.Emu(360_000) == shared.Cm(1)
Mostrará:
True
emu = shared.Emu(360_000)
cm = shared.Cm(1)
mm = shared.Mm(10)
inch = shared.Inches(0.3937008) # 1 cm = 0.3937008 inches
Todo lo anterior sería 1 cm expresado de diferente forma. Si miramos internamente:
print(emu.real, cm.real, mm.real, inch.real)
Mostraría:
360000 360000 360000 360000
Dentro del modulo shared vemos que tenemos también la clase RGBColor. Esta clase nos ayuda a usar colores en nuestro documento y que luego la librería lo pueda usar internamente.
black = shared.RGBColor(0,0,0)
print(black)
Lo anterior mostrará:
RGBColor(0x00, 0x00, 0x00)
Módulo enum
Este módulo son enumeraciones de todo tipo que se usan en la librería. Normalmente, la mayoría no es necesario conocerlas en detalle pero algunas de ellas si que son interesantes que las conozcamos.
from docx import enum
Al siguiente, dml, no le deberíamos prestar mucha atención.
print(enum.dml.__doc__)
Lo anterior muestra:
Enumerations used by DrawingML objects
El siguiente, section, sí que puede resultar más interesante. La ayuda nos dice:
print(enum.section.__doc__)
Enumerations related to the main document in WordprocessingML files
Veamos las enumeraciones que hay en enum.section y sus valores:
for name in dir(enum.section):
_enum = getattr(enum.section, name)
if isinstance(_enum, enum.base.MetaEnumeration):
print(name)
contents = dir(getattr(enum.section, name))
for content in contents:
_value = getattr(_enum, content)
if isinstance(_value, enum.base.EnumValue):
print("\t", content)
Lo anterior mostraría algo parecido a:
WD_HEADER_FOOTER
EVEN_PAGE
FIRST_PAGE
PRIMARY
WD_HEADER_FOOTER_INDEX
EVEN_PAGE
FIRST_PAGE
PRIMARY
WD_ORIENT
LANDSCAPE
PORTRAIT
WD_ORIENTATION
LANDSCAPE
PORTRAIT
WD_SECTION
CONTINUOUS
EVEN_PAGE
NEW_COLUMN
NEW_PAGE
ODD_PAGE
WD_SECTION_START
CONTINUOUS
EVEN_PAGE
NEW_COLUMN
NEW_PAGE
ODD_PAGE
XmlEnumeration
Tenemos valores para la sección donde podemos definir si la sección será en apaisado o en vertical, si el cabecero o pie de página estará en las paginas, pares, impares, en todas,...
El siguiente, shape, se usa para definir imágenes. La ayuda nos dice:
print(enum.shape.__doc__)
La ayuda nos dice:
Enumerations related to DrawingML shapes in WordprocessingML files
El siguiente, style, se usa para definir temas relacionados con el estilo. La ayuda nos dice:
print(enum.style.__doc__)
Lo anterior muestra:
Enumerations related to styles
Si miramos lo que hay:
for name in dir(enum.style):
_enum = getattr(enum.style, name)
if isinstance(_enum, enum.base.MetaEnumeration):
print(name)
contents = dir(getattr(enum.style, name))
for content in contents:
_value = getattr(_enum, content)
if isinstance(_value, enum.base.EnumValue):
print("\t", content)
Lo anterior nos da:
WD_BUILTIN_STYLE
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
WD_STYLE
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
WD_STYLE_TYPE
CHARACTER
LIST
PARAGRAPH
TABLE
XmlEnumeration
Los nombres que vemos aquí están relacionados con los estilos que podemos ver, por ejemplo, en la UI de Microsoft Word y también podemos ver los contextos en los que se pueden aplicar los estilos, a nivel de párrafo, de carácter, de tabla,...
El siguiente, table, se usa para definir temas relacionados con las tablas. La ayuda nos dice:
print(enum.table.__doc__)
Enumerations related to tables in WordprocessingML files
Miramos lo que hay:
for name in dir(enum.table):
_enum = getattr(enum.table, name)
if isinstance(_enum, enum.base.MetaEnumeration):
print(name)
contents = dir(getattr(enum.table, name))
for content in contents:
_value = getattr(_enum, content)
if isinstance(_value, enum.base.EnumValue):
print("\t", content)
Lo anterior mostrará:
Enumeration
WD_ALIGN_VERTICAL
BOTH
BOTTOM
CENTER
TOP
WD_CELL_VERTICAL_ALIGNMENT
BOTH
BOTTOM
CENTER
TOP
WD_ROW_HEIGHT
AT_LEAST
AUTO
EXACTLY
WD_ROW_HEIGHT_RULE
AT_LEAST
AUTO
EXACTLY
WD_TABLE_ALIGNMENT
CENTER
LEFT
RIGHT
WD_TABLE_DIRECTION
LTR
RTL
XmlEnumeration
Toda una serie de cosas para poder trabajar con tablas y definir la altura de celdas, la alineación,...
El siguiente, text, se usa para definir temas relacionados con texto. La ayuda nos dice:
print(enum.text.__doc__)
La documentación dice:
Enumerations related to text in WordprocessingML files
Si inspeccionamos lo que hay:
for name in dir(enum.text):
_enum = getattr(enum.text, name)
if isinstance(_enum, enum.base.MetaEnumeration):
print(name)
contents = dir(getattr(enum.text, name))
for content in contents:
_value = getattr(_enum, content)
if isinstance(_value, enum.base.EnumValue):
print("\t", content)
Veremos algo como:
WD_ALIGN_PARAGRAPH
CENTER
DISTRIBUTE
JUSTIFY
JUSTIFY_HI
JUSTIFY_LOW
JUSTIFY_MED
LEFT
RIGHT
THAI_JUSTIFY
WD_COLOR
AUTO
BLACK
BLUE
BRIGHT_GREEN
DARK_BLUE
DARK_RED
DARK_YELLOW
GRAY_25
GRAY_50
GREEN
PINK
RED
TEAL
TURQUOISE
VIOLET
WHITE
YELLOW
WD_COLOR_INDEX
AUTO
BLACK
BLUE
BRIGHT_GREEN
DARK_BLUE
DARK_RED
DARK_YELLOW
GRAY_25
GRAY_50
GREEN
PINK
RED
TEAL
TURQUOISE
VIOLET
WHITE
YELLOW
WD_LINE_SPACING
AT_LEAST
DOUBLE
EXACTLY
MULTIPLE
ONE_POINT_FIVE
SINGLE
WD_PARAGRAPH_ALIGNMENT
CENTER
DISTRIBUTE
JUSTIFY
JUSTIFY_HI
JUSTIFY_LOW
JUSTIFY_MED
LEFT
RIGHT
THAI_JUSTIFY
WD_TAB_ALIGNMENT
BAR
CENTER
CLEAR
DECIMAL
END
LEFT
LIST
NUM
RIGHT
START
WD_TAB_LEADER
DASHES
DOTS
HEAVY
LINES
MIDDLE_DOT
SPACES
WD_UNDERLINE
DASH
DASH_HEAVY
DASH_LONG
DASH_LONG_HEAVY
DOTTED
DOTTED_HEAVY
DOT_DASH
DOT_DASH_HEAVY
DOT_DOT_DASH
DOT_DOT_DASH_HEAVY
DOUBLE
NONE
SINGLE
THICK
WAVY
WAVY_DOUBLE
WAVY_HEAVY
WORDS
XmlEnumeration
Por último, aquí podemos ver un montón de cosas relacionadas con el texto.
Recapitulando
La biblioteca está pensada para que tenga un único punto de entrada. Si nuestro documento va a ser algo sencillo no necesitamos más que usar doc = docx.Document() y desde esa instancia podemos ir creándolo todo.
Si necesitamos meternos en harina y toquetear cosas tenemos toda una cantidad de nombres (enumeraciones) que nos deberían ayudar a hacer lo que tenemos en mente, siempre que el formato docx lo permita.
Pybonacci