or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

charts.mdformatting.mdindex.mdpresentation.mdshapes.mdslides.mdtables.mdtext.mdutilities.md
tile.json

tables.mddocs/

Tables

Creating and styling tables with cells, rows, and columns. Includes cell merging, text formatting, and table-wide styling options for structured data presentation.

Capabilities

Table Creation

Add tables to slides with specified dimensions and positioning.

# Table creation through shapes collection
def add_table(rows: int, cols: int, left: int, top: int, width: int, height: int) -> GraphicFrame:
    """
    Add table to slide.
    
    Parameters:
    - rows: Number of table rows
    - cols: Number of table columns  
    - left, top: Position in EMU
    - width, height: Table dimensions in EMU
    
    Returns:
    GraphicFrame containing Table object
    """

Table Operations

Access and configure table structure and properties.

class Table:
    """Table with rows, columns, and cells."""
    
    @property
    def rows(self) -> _RowCollection:
        """Collection of table rows."""
    
    @property
    def columns(self) -> _ColumnCollection:
        """Collection of table columns."""
    
    def cell(self, row_idx: int, col_idx: int) -> _Cell:
        """
        Get cell at specified position.
        
        Parameters:
        - row_idx: Row index (0-based)
        - col_idx: Column index (0-based)
        
        Returns:
        _Cell object at specified position
        """
    
    @property
    def first_row(self) -> bool:
        """True if first row has special formatting."""
    
    @first_row.setter
    def first_row(self, first_row: bool):
        """Set first row special formatting."""
    
    @property
    def first_col(self) -> bool:
        """True if first column has special formatting."""
    
    @first_col.setter
    def first_col(self, first_col: bool):
        """Set first column special formatting."""
    
    @property
    def last_row(self) -> bool:
        """True if last row has special formatting."""
    
    @last_row.setter
    def last_row(self, last_row: bool):
        """Set last row special formatting."""
    
    @property
    def last_col(self) -> bool:
        """True if last column has special formatting."""
    
    @last_col.setter
    def last_col(self, last_col: bool):
        """Set last column special formatting."""
    
    @property
    def horz_banding(self) -> bool:
        """True if horizontal banding is applied."""
    
    @horz_banding.setter
    def horz_banding(self, banding: bool):
        """Set horizontal banding."""
    
    @property
    def vert_banding(self) -> bool:
        """True if vertical banding is applied."""
    
    @vert_banding.setter
    def vert_banding(self, banding: bool):
        """Set vertical banding."""

Row Operations

Manage table rows including height and cell access.

class _RowCollection:
    """Collection of table rows."""
    
    def __getitem__(self, index: int) -> _Row:
        """Get row by index."""
    
    def __len__(self) -> int:
        """Number of rows."""
    
    def __iter__(self):
        """Iterate over rows."""

class _Row:
    """Individual table row."""
    
    @property
    def height(self) -> int:
        """Row height in EMU."""
    
    @height.setter
    def height(self, height: int):
        """Set row height."""
    
    @property
    def cells(self) -> list:
        """List of cells in this row."""
    
    def __getitem__(self, index: int) -> _Cell:
        """Get cell by column index."""

Column Operations

Manage table columns including width properties.

class _ColumnCollection:
    """Collection of table columns."""
    
    def __getitem__(self, index: int) -> _Column:
        """Get column by index."""
    
    def __len__(self) -> int:
        """Number of columns."""
    
    def __iter__(self):
        """Iterate over columns."""

class _Column:
    """Individual table column."""
    
    @property
    def width(self) -> int:
        """Column width in EMU."""
    
    @width.setter
    def width(self, width: int):
        """Set column width."""

Cell Operations

Work with individual table cells including content, formatting, and merging.

class _Cell:
    """Individual table cell with content and formatting."""
    
    @property
    def text(self) -> str:
        """Plain text content of cell."""
    
    @text.setter
    def text(self, text: str):
        """Set cell text content."""
    
    @property
    def text_frame(self) -> TextFrame:
        """Text frame for rich text formatting."""
    
    @property
    def fill(self) -> FillFormat:
        """Cell background fill formatting."""
    
    @property
    def margin_left(self) -> int:
        """Left margin in EMU."""
    
    @margin_left.setter
    def margin_left(self, margin: int):
        """Set left margin."""
    
    @property
    def margin_top(self) -> int:
        """Top margin in EMU."""
    
    @margin_top.setter
    def margin_top(self, margin: int):
        """Set top margin."""
    
    @property
    def margin_right(self) -> int:
        """Right margin in EMU."""
    
    @margin_right.setter
    def margin_right(self, margin: int):
        """Set right margin."""
    
    @property
    def margin_bottom(self) -> int:
        """Bottom margin in EMU."""
    
    @margin_bottom.setter
    def margin_bottom(self, margin: int):
        """Set bottom margin."""
    
    @property
    def vertical_anchor(self) -> MSO_VERTICAL_ANCHOR:
        """Vertical alignment of cell content."""
    
    @vertical_anchor.setter
    def vertical_anchor(self, anchor: MSO_VERTICAL_ANCHOR):
        """Set vertical alignment."""
    
    def merge(self, other_cell: '_Cell') -> _Cell:
        """
        Merge this cell with another cell.
        
        Parameters:
        - other_cell: Cell to merge with (must be adjacent)
        
        Returns:
        Merged cell object
        """
    
    @property
    def is_merge_origin(self) -> bool:
        """True if cell is origin of merged cell range."""
    
    @property
    def is_spanned(self) -> bool:
        """True if cell is part of merged range but not origin."""

Usage examples:

from pptx import Presentation
from pptx.util import Inches
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT, MSO_VERTICAL_ANCHOR

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[6])  # Blank layout

# Create table
rows, cols = 4, 3
left, top = Inches(1), Inches(1)
width, height = Inches(8), Inches(4)

table_shape = slide.shapes.add_table(rows, cols, left, top, width, height)
table = table_shape.table

# Set table formatting options
table.first_row = True      # Header row formatting
table.horz_banding = True   # Alternating row colors

# Add header row content
header_texts = ['Product', 'Q1 Sales', 'Q2 Sales']
for col_idx, text in enumerate(header_texts):
    cell = table.cell(0, col_idx)
    cell.text = text
    
    # Format header cells
    cell.fill.solid()
    cell.fill.fore_color.rgb = RGBColor(68, 114, 196)
    
    # Format header text
    paragraph = cell.text_frame.paragraphs[0]
    paragraph.font.color.rgb = RGBColor(255, 255, 255)
    paragraph.font.bold = True
    paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
    
    cell.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE

# Add data rows
data = [
    ['Product A', '$12,000', '$15,000'],
    ['Product B', '$8,500', '$11,200'],
    ['Product C', '$6,800', '$9,100']
]

for row_idx, row_data in enumerate(data, start=1):
    for col_idx, text in enumerate(row_data):
        cell = table.cell(row_idx, col_idx)
        cell.text = text
        
        # Center align numeric columns
        if col_idx > 0:
            paragraph = cell.text_frame.paragraphs[0]
            paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
        
        cell.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE

# Adjust column widths
table.columns[0].width = Inches(2.5)  # Product name column
table.columns[1].width = Inches(2.0)  # Q1 column
table.columns[2].width = Inches(2.0)  # Q2 column

# Adjust row heights
for row in table.rows:
    row.height = Inches(0.8)

# Create table with merged cells
slide2 = prs.slides.add_slide(prs.slide_layouts[6])
table2_shape = slide2.shapes.add_table(5, 4, Inches(1), Inches(1), Inches(8), Inches(4))
table2 = table2_shape.table

# Add title spanning multiple columns
title_cell = table2.cell(0, 0)
title_cell.text = "Annual Sales Report"

# Merge cells across columns for title
for col in range(1, 4):
    title_cell.merge(table2.cell(0, col))

# Format merged title cell
title_cell.fill.solid() 
title_cell.fill.fore_color.rgb = RGBColor(0, 100, 0)
title_para = title_cell.text_frame.paragraphs[0]
title_para.font.color.rgb = RGBColor(255, 255, 255)
title_para.font.bold = True
title_para.font.size = Pt(16)
title_para.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
title_cell.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE

# Add quarter headers
quarters = ['', 'Q1', 'Q2', 'Q3']
for col_idx, quarter in enumerate(quarters):
    cell = table2.cell(1, col_idx)
    cell.text = quarter
    if col_idx > 0:  # Quarter cells
        cell.fill.solid()
        cell.fill.fore_color.rgb = RGBColor(200, 200, 200)
        cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.CENTER

# Add product data
products = ['Product X', 'Product Y', 'Product Z']
for row_idx, product in enumerate(products, start=2):
    # Product name
    table2.cell(row_idx, 0).text = product
    
    # Sales data
    for col_idx in range(1, 4):
        cell = table2.cell(row_idx, col_idx)
        cell.text = f"${(row_idx-1) * col_idx * 1000:,}"
        cell.text_frame.paragraphs[0].alignment = PP_PARAGRAPH_ALIGNMENT.RIGHT

# Demonstrate cell border formatting
for row_idx in range(table2.rows.__len__()):
    for col_idx in range(table2.columns.__len__()):
        cell = table2.cell(row_idx, col_idx)
        # Note: Cell border formatting would require accessing
        # cell.border properties if available in implementation

prs.save('tables-example.pptx')

Advanced Table Operations

from pptx.util import Pt

# Complex cell merging example
def create_complex_table():
    table = slide.shapes.add_table(6, 5, Inches(1), Inches(1), Inches(8), Inches(5)).table
    
    # Create merged header spanning multiple rows and columns
    top_left = table.cell(0, 0)
    top_left.text = "Department Summary"
    
    # Merge cells in L-shape
    top_left.merge(table.cell(0, 1))  # Merge right
    top_left.merge(table.cell(1, 0))  # Merge down
    top_left.merge(table.cell(1, 1))  # Complete 2x2 merge
    
    # Set cell margins for better text positioning
    for row in table.rows:
        for cell in row.cells:
            cell.margin_left = Inches(0.1)
            cell.margin_right = Inches(0.1)
            cell.margin_top = Inches(0.05)
            cell.margin_bottom = Inches(0.05)
    
    return table

# Table styling with alternating colors
def apply_zebra_striping(table):
    """Apply alternating row colors to table."""
    for row_idx, row in enumerate(table.rows):
        if row_idx % 2 == 1:  # Odd rows
            for cell in row.cells:
                cell.fill.solid()
                cell.fill.fore_color.rgb = RGBColor(245, 245, 245)

# Dynamic table sizing based on content
def auto_size_columns(table, content_data):
    """Adjust column widths based on content length."""
    max_lengths = []
    
    # Calculate maximum content length per column
    for col_idx in range(len(table.columns)):
        max_len = 0
        for row_data in content_data:
            if col_idx < len(row_data):
                max_len = max(max_len, len(row_data[col_idx]))
        max_lengths.append(max_len)
    
    # Set column widths proportionally
    total_width = Inches(8)
    total_chars = sum(max_lengths)
    
    for col_idx, max_len in enumerate(max_lengths):
        proportion = max_len / total_chars if total_chars > 0 else 1/len(max_lengths)
        table.columns[col_idx].width = int(total_width * proportion)

Table Formatting Best Practices

# Header row styling
def format_header_row(table):
    """Apply consistent header formatting."""
    header_row = table.rows[0]
    header_row.height = Inches(0.6)
    
    for cell in header_row.cells:
        # Background
        cell.fill.solid()
        cell.fill.fore_color.rgb = RGBColor(31, 78, 120)
        
        # Text formatting
        paragraph = cell.text_frame.paragraphs[0]
        paragraph.font.color.rgb = RGBColor(255, 255, 255)
        paragraph.font.bold = True
        paragraph.font.size = Pt(12)
        paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
        
        # Cell alignment
        cell.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE

# Data row formatting
def format_data_rows(table, start_row=1):
    """Apply consistent data row formatting."""
    for row_idx in range(start_row, len(table.rows)):
        row = table.rows[row_idx]
        row.height = Inches(0.4)
        
        for cell in row.cells:
            paragraph = cell.text_frame.paragraphs[0]
            paragraph.font.size = Pt(10)
            cell.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE