DEV Community

Allen Yang
Allen Yang

Posted on

Inserting and Managing Shapes in Excel Using Python

Inserting and Managing Shapes in Excel Using Python

In Excel, shapes are often used for process indicators, callouts, dashboard decoration, or turning scattered data into a clear diagram. Compared with plain text and cell borders, shapes express hierarchy and relationships more freely. But when the same shapes need to be added across many worksheets or files, dragging them by hand is slow and hard to keep consistent.

Python can insert shapes into worksheets in batch and with precision, and control properties such as fill, border, shadow, and layer order. Using Spire.XLS for Python, this article covers shape insertion and the management operations you are most likely to need.

Setting Up the Environment

Install the Spire.XLS library:

pip install Spire.XLS
Enter fullscreen mode Exit fullscreen mode

Then import the required modules in your script:

from spire.xls import *
from spire.xls.common import *
Enter fullscreen mode Exit fullscreen mode

Inserting Shapes

A worksheet exposes several shape collections for different kinds of shapes. The most general is PrstGeomShapes, which creates dozens of preset graphics through the PrstGeomShapeType enum. The arguments of AddPrstGeomShape() are the starting row, starting column, width, and height:

workbook = Workbook()
sheet = workbook.Worksheets[0]

# Insert a triangle with a solid fill
triangle = sheet.PrstGeomShapes.AddPrstGeomShape(2, 2, 100, 100, PrstGeomShapeType.Triangle)
triangle.Fill.ForeColor = Color.get_Yellow()
triangle.Fill.FillType = ShapeFillType.SolidColor

# Insert a heart with a gradient fill
heart = sheet.PrstGeomShapes.AddPrstGeomShape(2, 5, 100, 100, PrstGeomShapeType.Heart)
heart.Fill.ForeColor = Color.get_Red()
heart.Fill.FillType = ShapeFillType.Gradient

# Insert an arrow and a cloud
arrow = sheet.PrstGeomShapes.AddPrstGeomShape(10, 2, 100, 100, PrstGeomShapeType.CurvedRightArrow)
cloud = sheet.PrstGeomShapes.AddPrstGeomShape(10, 5, 100, 100, PrstGeomShapeType.Cloud)

workbook.SaveToFile("shapes.xlsx", ExcelVersion.Version2013)
workbook.Dispose()
Enter fullscreen mode Exit fullscreen mode

PrstGeomShapeType includes values such as Triangle, Heart, CurvedRightArrow, Cloud, Ellipse, and RoundRect, covering common needs in flowcharts, callouts, and decoration.

For rectangles and ovals — the two most common shapes — dedicated methods offer simpler arguments:

# Insert a rectangle; RectangleShapeType can be Rect or RoundRect
rect = sheet.RectangleShapes.AddRectangle(11, 2, 60, 100, RectangleShapeType.RoundRect)
rect.Fill.FillType = ShapeFillType.SolidColor
rect.Fill.ForeColor = Color.get_DarkCyan()

# Insert an oval
oval = sheet.OvalShapes.AddOval(11, 5, 100, 100)
oval.Fill.FillType = ShapeFillType.SolidColor
oval.Fill.ForeColor = Color.get_DarkCyan()
Enter fullscreen mode Exit fullscreen mode

Setting Fill, Border, and Shadow

A shape's fill is controlled by Fill.FillType, where ShapeFillType provides values such as SolidColor, Gradient, and Picture. A picture fill requires the image to be supplied through CustomPicture() first, then the type set to Picture:

# Fill a shape with a picture
cloud = sheet.PrstGeomShapes.AddPrstGeomShape(2, 5, 100, 100, PrstGeomShapeType.Cloud)
cloud.Fill.CustomPicture(Stream("logo.png"), "logo.png")
cloud.Fill.FillType = ShapeFillType.Picture

# A file path can also be used directly
oval = sheet.OvalShapes.AddOval(11, 5, 100, 100)
oval.Fill.CustomPicture("logo.png")
Enter fullscreen mode Exit fullscreen mode

Borders are configured through the Line property, which controls weight and dash style:

rect.Line.Weight = 1
oval.Line.DashStyle = ShapeDashLineStyleType.Solid
Enter fullscreen mode Exit fullscreen mode

Shadows add depth, and the Shadow property exposes angle, distance, size, color, blur, and transparency:

ellipse = sheet.PrstGeomShapes.AddPrstGeomShape(5, 5, 150, 100, PrstGeomShapeType.Ellipse)
ellipse.Shadow.Angle = 90
ellipse.Shadow.Distance = 10
ellipse.Shadow.Size = 150
ellipse.Shadow.Color = Color.get_Gray()
ellipse.Shadow.Blur = 30
ellipse.Shadow.Transparency = 1
ellipse.Shadow.HasCustomStyle = True
Enter fullscreen mode Exit fullscreen mode

Note the last step: the custom shadow settings only take effect once HasCustomStyle is set to True.

Grouping Shapes

When several shapes should move or scale as a single unit, group them. Get the group collection with GetGroupShapeCollection(), then pass the list of shapes to group:

shape1 = sheet.PrstGeomShapes.AddPrstGeomShape(1, 3, 50, 50, PrstGeomShapeType.RoundRect)
shape2 = sheet.PrstGeomShapes.AddPrstGeomShape(5, 3, 50, 50, PrstGeomShapeType.Triangle)

groupShapeCollection = sheet.GetGroupShapeCollection()
groupShapeCollection.Group([shape1, shape2])
Enter fullscreen mode Exit fullscreen mode

Once grouped, the shapes share a single bounding box and stay aligned when repositioned.

Adjusting Layer Order

When shapes overlap, their display order is determined by the layer. The ChangeLayer() method accepts the ShapeLayerChangeType enum to move a shape forward or backward:

# Move forward one level
shape.ChangeLayer(ShapeLayerChangeType.BringForward)
# Bring to the very front
shape.ChangeLayer(ShapeLayerChangeType.BringToFront)
# Send backward one level
shape.ChangeLayer(ShapeLayerChangeType.SendBackward)
# Send to the very back
shape.ChangeLayer(ShapeLayerChangeType.SendToBack)
Enter fullscreen mode Exit fullscreen mode

Picture objects support ChangeLayer() as well, with the same usage.

Deleting and Hiding Shapes

Delete a single shape with Remove(). For bulk deletion, iterate backward — otherwise the indices shift as items are removed and elements get skipped:

workbook.LoadFromFile("template.xlsx")
sheet = workbook.Worksheets[0]

# Remove the first shape
sheet.PrstGeomShapes[0].Remove()

# Remove all shapes: iterate backward
for i in range(sheet.PrstGeomShapes.Count - 1, -1, -1):
    sheet.PrstGeomShapes[i].Remove()

workbook.SaveToFile("shapes_deleted.xlsx", ExcelVersion.Version2013)
workbook.Dispose()
Enter fullscreen mode Exit fullscreen mode

If a shape should only be hidden temporarily rather than deleted, toggle its visibility instead, so it can be restored later:

sheet.PrstGeomShapes[1].Visible = False
Enter fullscreen mode Exit fullscreen mode

Exporting Shapes and Reading Their Contents

A shape can be exported as an image for reuse elsewhere:

shape = sheet.PrstGeomShapes[0]
img = shape.SaveToImage()
img.Save("shape.png")
Enter fullscreen mode Exit fullscreen mode

Conversely, the Text property reads the text inside a shape, and a picture fill can be extracted as the original image:

# Read the text inside a shape
print(sheet.PrstGeomShapes[2].Text)

# Extract the picture fill of a shape
image = sheet.PrstGeomShapes[1].Fill.Picture
image.Save("extracted.png", ImageFormat.get_Png())
Enter fullscreen mode Exit fullscreen mode

Practical Tips

  • The first two arguments of AddPrstGeomShape() are the row and column position, followed by width and height; the shape anchors near the corresponding cells, so it shifts when the row or column layout changes.
  • When setting a custom shadow, it is easy to forget HasCustomStyle = True, which leaves the parameters without effect.
  • Always delete shapes in reverse order for bulk operations; forward deletion skips elements because the collection indices change in real time.
  • Call Dispose() when finished to release resources.

Conclusion

This article covered the full workflow of working with shapes in Excel using Python: inserting different shapes with AddPrstGeomShape(), AddRectangle(), and AddOval(); controlling appearance through Fill, Line, and Shadow; grouping shapes with Group() and reordering them with ChangeLayer(); and deleting via Remove(), hiding via Visible, and exporting via SaveToImage(). With these operations, repetitive layout work such as dashboard decoration and diagram annotation can be handed off to a script.

Top comments (0)