Claude Code Plugins

Community-maintained marketplace

Feedback

Create and manipulate Microsoft Word documents programmatically using python-docx. Use when generating Word reports, creating templated documents, producing editable business documents, or building DOCX files with tables and images.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name docx
description Create and manipulate Microsoft Word documents programmatically using python-docx. Use when generating Word reports, creating templated documents, producing editable business documents, or building DOCX files with tables and images.

DOCX

Provides patterns for creating Word documents using python-docx.

Basic Document Creation

from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH

def create_document() -> Document:
    """Create a new Word document."""
    return Document()

def save_document(doc: Document, filepath: str):
    """Save document to file."""
    doc.save(filepath)

def add_title(doc: Document, title: str) -> None:
    """Add document title."""
    doc.add_heading(title, level=0)

def add_heading(doc: Document, text: str, level: int = 1) -> None:
    """Add heading at specified level (1-9)."""
    doc.add_heading(text, level=level)

def add_paragraph(doc: Document, text: str) -> None:
    """Add a paragraph."""
    doc.add_paragraph(text)

Styled Text

from docx.shared import RGBColor

def add_styled_paragraph(
    doc: Document,
    text: str,
    bold: bool = False,
    italic: bool = False,
    font_size: int = 11,
    color: str = None
) -> None:
    """
    Add a paragraph with styling.

    Usage:
        add_styled_paragraph(doc, "Important note", bold=True, color="#FF0000")
    """
    para = doc.add_paragraph()
    run = para.add_run(text)

    run.bold = bold
    run.italic = italic
    run.font.size = Pt(font_size)

    if color:
        # Convert hex to RGB
        color = color.lstrip('#')
        r, g, b = tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
        run.font.color.rgb = RGBColor(r, g, b)

def add_bullet_list(doc: Document, items: list[str]) -> None:
    """Add a bullet list."""
    for item in items:
        doc.add_paragraph(item, style='List Bullet')

def add_numbered_list(doc: Document, items: list[str]) -> None:
    """Add a numbered list."""
    for item in items:
        doc.add_paragraph(item, style='List Number')

Tables

from docx.table import Table as DocxTable
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

def add_table(
    doc: Document,
    headers: list[str],
    rows: list[list],
    style: str = 'Table Grid'
) -> DocxTable:
    """
    Add a table to the document.

    Usage:
        table = add_table(doc,
            headers=["Name", "Amount", "Date"],
            rows=[
                ["Invoice 1", "$100", "2024-01-15"],
                ["Invoice 2", "$250", "2024-01-20"]
            ]
        )
    """
    table = doc.add_table(rows=1, cols=len(headers))
    table.style = style

    # Add headers
    header_cells = table.rows[0].cells
    for i, header in enumerate(headers):
        header_cells[i].text = header

    # Add data rows
    for row_data in rows:
        row = table.add_row().cells
        for i, cell_data in enumerate(row_data):
            row[i].text = str(cell_data)

    return table

def dict_to_table(doc: Document, data: list[dict]) -> DocxTable:
    """Convert list of dictionaries to table."""
    if not data:
        return None

    headers = list(data[0].keys())
    rows = [[row.get(h, "") for h in headers] for row in data]
    return add_table(doc, headers, rows)

def style_table_header(table: DocxTable, bg_color: str = "4472C4"):
    """Style table header row with background color."""
    for cell in table.rows[0].cells:
        shading = OxmlElement('w:shd')
        shading.set(qn('w:fill'), bg_color)
        cell._tc.get_or_add_tcPr().append(shading)

Images

def add_image(
    doc: Document,
    image_path: str,
    width: float = None,
    caption: str = None
) -> None:
    """
    Add an image to the document.

    Usage:
        add_image(doc, "charts/sales.png", width=5.0, caption="Sales Chart")
    """
    if width:
        doc.add_picture(image_path, width=Inches(width))
    else:
        doc.add_picture(image_path)

    if caption:
        para = doc.add_paragraph(caption)
        para.alignment = WD_ALIGN_PARAGRAPH.CENTER

Page Breaks and Sections

def add_page_break(doc: Document) -> None:
    """Add a page break."""
    doc.add_page_break()

def add_section_break(doc: Document) -> None:
    """Add a section break."""
    doc.add_section()

Report Template

def create_report(
    filepath: str,
    title: str,
    sections: list[dict]
) -> None:
    """
    Create a complete report.

    Usage:
        create_report(
            filepath="quarterly_report.docx",
            title="Q4 2024 Report",
            sections=[
                {"title": "Executive Summary", "content": "Summary text..."},
                {"title": "Financial Data", "table": data_list},
                {"title": "Analysis", "content": "Analysis text...", "image": "chart.png"}
            ]
        )
    """
    doc = Document()

    # Title
    add_title(doc, title)

    # Sections
    for section in sections:
        add_heading(doc, section["title"], level=1)

        if "content" in section:
            add_paragraph(doc, section["content"])

        if "table" in section:
            dict_to_table(doc, section["table"])
            add_paragraph(doc, "")  # Spacing

        if "image" in section:
            add_image(doc, section["image"], width=5.0)

        if "bullets" in section:
            add_bullet_list(doc, section["bullets"])

    save_document(doc, filepath)

Reading Existing Documents

def read_document(filepath: str) -> Document:
    """Open existing Word document."""
    return Document(filepath)

def get_all_text(doc: Document) -> str:
    """Extract all text from document."""
    return "\n".join(para.text for para in doc.paragraphs)

def get_all_tables(doc: Document) -> list[list[list[str]]]:
    """Extract all tables as nested lists."""
    tables = []
    for table in doc.tables:
        table_data = []
        for row in table.rows:
            row_data = [cell.text for cell in row.cells]
            table_data.append(row_data)
        tables.append(table_data)
    return tables

Helper Script

Use helper.py for the DocxGenerator class with comprehensive Word document generation features.