Images and Shapes API

pyopenxlsx allows you to embed images directly into worksheets. The image anchoring and scaling logic relies on the Pillow (PIL) library, which must be installed for auto-sizing to work.

Inserting an Image

Images are inserted using the add_image() method on a Worksheet object.

from pyopenxlsx import Workbook

with Workbook() as wb:
    ws = wb.active
    
    # 1. Simple Insertion (Auto-detected dimensions)
    # The top-left corner of the image will be at cell B2.
    # Note: Pillow (pip install pillow) must be installed to auto-detect width and height.
    ws.add_image("logo.png", anchor="B2")
    
    # 2. Resized Insertion (Maintain aspect ratio based on width)
    ws.add_image("photo.jpg", anchor="D5", width=300)
    
    # 3. Exact Dimensions Insertion (Overrides original aspect ratio)
    ws.add_image("banner.png", anchor="A10", width=600, height=100)
    
    wb.save("images.xlsx")

Extracting Images

You can extract all embedded images from an existing workbook.

from pyopenxlsx import load_workbook

wb = load_workbook("images.xlsx")

# Retrieve a list of ImageInfo objects describing the embedded images
image_infos = wb.get_embedded_images()
for img in image_infos:
    print(f"Found image: {img.name} (Type: {img.extension})")

# Extract all images to a specific directory on disk
extracted_paths = wb.extract_images("output_folder/")
print(f"Extracted to: {extracted_paths}")

Advanced Binary Data Access

If you need to process images in memory (e.g., uploading to a cloud bucket or sending over an API) without saving to disk:

for img in wb.get_embedded_images():
    # Fetch raw bytes of the image
    raw_bytes = wb.get_image_data(img.path)
    # Process raw_bytes...

Inserting Vector Shapes

pyopenxlsx provides support for adding native Excel vector shapes (like Rectangles, Arrows, Diamonds, etc.) using add_shape(). Unlike raster images, shapes are drawn natively by Excel and scale perfectly.

from pyopenxlsx import Workbook

with Workbook() as wb:
    ws = wb.active
    
    # 1. Add an Arrow pointing right
    ws.add_shape(
        row=2, col=2, 
        shape_type="Arrow", 
        name="MyArrow", text="Important!", 
        fill_color="FF0000", line_width=2.5,
        rotation=90
    )
    
    # 2. Add a styled Cloud
    ws.add_shape(
        row=5, col=5, 
        shape_type="Cloud",
        name="Cloudy", text="Data",
        width=200, height=150,
        flip_h=True
    )
    
    wb.save("shapes.xlsx")

Supported Shape Options (**kwargs)

You can extensively configure your shape using the following arguments:

  • Dimensions & Anchor: row, col, width, height, offset_x, offset_y.

  • Two-Cell Anchor: end_row, end_col, end_offset_x, end_offset_y (allow the shape to resize automatically as cells scale).

  • Appearance: fill_color (ARGB without #), line_color (ARGB without #), line_width (float).

  • Transformations: rotation (degrees), flip_h (bool), flip_v (bool).

  • Outline Styles: line_dash (“dash”, “sysDash”, “dot”, etc.), arrow_start, arrow_end (“triangle”, “stealth”, “diamond”).

  • Text & Alignment: text (str), horz_align (“l”, “ctr”, “r”), vert_align (“t”, “ctr”, “b”).