Dmitry Arkhipenko
Dmitry Arkhipenko

Reputation: 527

How to rotate text in table cells?

I'm trying to make table like this:

Table with vertical header cells

As you can see, the header is vertically orientated. How can I achieve this using python-docx?

P.S. Sorry for non-translated table.

Upvotes: 4

Views: 2377

Answers (2)

Nikolay Markov
Nikolay Markov

Reputation: 31

In response to your request regarding the need to implement text rotation in a cell, I would like to share the solution to this task that I have obtained.

import docx
from lxml import etree
from docx.shared import Inches


def rotate_text_in_cell(cell):
    tcPr = cell._element.find(
        "./w:tcPr",
        namespaces={
            "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
        },
    )
    tcW = tcPr.find(
        "./w:tcW",
        namespaces={
            "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
        },
    )
    tcW.set("{http://schemas.openxmlformats.org/wordprocessingml/2006/main}w", "4672")
    etree.SubElement(
        tcPr,
        "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}textDirection",
        attrib={
            "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val": "btLr"
        },
    )


document = docx.Document()

table = document.add_table(rows=5, cols=3)

row_cells = table.rows[0].cells
row_cells[0].text = "Name"
row_cells[1].text = "Age"
row_cells[2].text = "City"

for row in range(1, 5):
    row_cells = table.rows[row].cells
    row_cells[0].text = f"Name {row}"
    row_cells[1].text = str(20 + row)
    row_cells[2].text = f"City {row}"

for table in document.tables:
    for index, row in enumerate(table.rows):

        if index == 0:
            row.height = Inches(0.5)
            for cell in row.cells:
                rotate_text_in_cell(cell)
        else:
            row.height = Inches(0.1)

document.save("test1.docx")

Upvotes: 0

MadisonTrash
MadisonTrash

Reputation: 5614

Snippet for those who are too tired to seek:

from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.table import _Cell


def set_vertical_cell_direction(cell: _Cell, direction: str):
    # direction: tbRl -- top to bottom, btLr -- bottom to top
    assert direction in ("tbRl", "btLr")
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()
    textDirection = OxmlElement('w:textDirection')
    textDirection.set(qn('w:val'), direction)  # btLr tbRl
    tcPr.append(textDirection)

Upvotes: 5

Related Questions