
在 Excel 中,形状常用来做流程指示、重点标注、仪表盘装饰,或把零散的数据组织成一张直观的示意图。相比纯文字和单元格边框,形状能更自由地表达层级和关系。但如果需要在多张工作表、多个文件中重复添加同样的形状,手工拖拽既慢又难以保证一致。
用 Python 可以批量、精确地在工作表上插入形状,并对填充、边框、阴影、层级等属性进行控制。本文以 Spire.XLS for Python 为例,介绍插入形状以及常用的管理操作。
环境准备
安装 Spire.XLS 库:
bash
pip install Spire.XLS
在脚本中引入模块:
python
from spire.xls import *
from spire.xls.common import *
插入形状
工作表提供了几个形状集合,对应不同类型的形状。最通用的是 PrstGeomShapes,它可以通过 PrstGeomShapeType 枚举创建数十种预设图形。AddPrstGeomShape() 的参数依次是起始行、起始列、宽度和高度:
python
workbook = Workbook()
sheet = workbook.Worksheets[0]
# 插入三角形并填充纯色
triangle = sheet.PrstGeomShapes.AddPrstGeomShape(2, 2, 100, 100, PrstGeomShapeType.Triangle)
triangle.Fill.ForeColor = Color.get_Yellow()
triangle.Fill.FillType = ShapeFillType.SolidColor
# 插入心形并填充渐变
heart = sheet.PrstGeomShapes.AddPrstGeomShape(2, 5, 100, 100, PrstGeomShapeType.Heart)
heart.Fill.ForeColor = Color.get_Red()
heart.Fill.FillType = ShapeFillType.Gradient
# 插入箭头和云形
arrow = sheet.PrstGeomShapes.AddPrstGeomShape(10, 2, 100, 100, PrstGeomShapeType.CurvedRightArrow)
cloud = sheet.PrstGeomShapes.AddPrstGeomShape(10, 5, 100, 100, PrstGeomShapeType.Cloud)
workbook.SaveToFile("形状.xlsx", ExcelVersion.Version2013)
workbook.Dispose()
PrstGeomShapeType 提供 Triangle、Heart、CurvedRightArrow、Cloud、Ellipse、RoundRect 等多种取值,覆盖了流程图、标注、装饰等常见需求。
对于矩形和椭圆这两种最常用的形状,还有专门的方法可以调用,参数更简洁:
python
# 插入矩形,RectangleShapeType 可选 Rect(直角)或 RoundRect(圆角)
rect = sheet.RectangleShapes.AddRectangle(11, 2, 60, 100, RectangleShapeType.RoundRect)
rect.Fill.FillType = ShapeFillType.SolidColor
rect.Fill.ForeColor = Color.get_DarkCyan()
# 插入椭圆
oval = sheet.OvalShapes.AddOval(11, 5, 100, 100)
oval.Fill.FillType = ShapeFillType.SolidColor
oval.Fill.ForeColor = Color.get_DarkCyan()
设置填充、边框和阴影
形状的填充方式由 Fill.FillType 决定,ShapeFillType 提供 SolidColor、Gradient、Picture 等取值。其中图片填充需要先通过 CustomPicture() 指定图片,再把类型设为 Picture:
python
# 用图片填充形状
cloud = sheet.PrstGeomShapes.AddPrstGeomShape(2, 5, 100, 100, PrstGeomShapeType.Cloud)
cloud.Fill.CustomPicture(Stream("logo.png"), "logo.png")
cloud.Fill.FillType = ShapeFillType.Picture
# 也可以用路径直接指定
oval = sheet.OvalShapes.AddOval(11, 5, 100, 100)
oval.Fill.CustomPicture("logo.png")
边框通过 Line 属性设置,可以控制线宽和虚实:
python
rect.Line.Weight = 1
oval.Line.DashStyle = ShapeDashLineStyleType.Solid
阴影能让形状更有立体感,Shadow 属性提供了角度、距离、大小、颜色、模糊和透明度等参数:
python
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
注意最后一步:只有把 HasCustomStyle 设为 True,前面设置的自定义阴影参数才会生效。
组合形状
当多个形状需要作为一个整体移动或缩放时,可以把它们组合起来。先通过 GetGroupShapeCollection() 取得组合集合,再传入需要组合的形状列表:
python
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])
组合后两个形状共享同一个外框,调整位置时不会彼此错位。
调整层级
当形状互相重叠时,显示顺序由层级决定。ChangeLayer() 方法接受 ShapeLayerChangeType 枚举,可以在图层中前后移动:
python
# 向前移动一层
shape.ChangeLayer(ShapeLayerChangeType.BringForward)
# 移到最前
shape.ChangeLayer(ShapeLayerChangeType.BringToFront)
# 向后移动一层
shape.ChangeLayer(ShapeLayerChangeType.SendBackward)
# 移到最后
shape.ChangeLayer(ShapeLayerChangeType.SendToBack)
图片对象同样支持 ChangeLayer(),用法与形状一致。
删除和隐藏形状
删除单个形状调用 Remove();批量删除时需要倒序遍历,否则删除后索引会变化导致漏删:
python
workbook.LoadFromFile("模板.xlsx")
sheet = workbook.Worksheets[0]
# 删除第一个形状
sheet.PrstGeomShapes[0].Remove()
# 删除所有形状:倒序遍历
for i in range(sheet.PrstGeomShapes.Count - 1, -1, -1):
sheet.PrstGeomShapes[i].Remove()
workbook.SaveToFile("删除形状.xlsx", ExcelVersion.Version2013)
workbook.Dispose()
如果只是临时不想显示,可以隐藏而不是删除,方便后续恢复:
python
sheet.PrstGeomShapes[1].Visible = False
导出形状与读取内容
形状本身可以导出为图片,便于在其他地方复用:
python
shape = sheet.PrstGeomShapes[0]
img = shape.SaveToImage()
img.Save("shape.png")
反过来,也可以通过 Text 属性读取形状中的文字,或从图片填充中取出原始图片:
python
# 读取形状中的文本
print(sheet.PrstGeomShapes[2].Text)
# 提取形状的图片填充
image = sheet.PrstGeomShapes[1].Fill.Picture
image.Save("extracted.png", ImageFormat.get_Png())
实用提示
AddPrstGeomShape()的前两个参数是行、列位置,后两个是宽高,形状会锚定到对应单元格附近;调整行列布局时形状位置会随之变化。- 设置自定义阴影时容易遗漏
HasCustomStyle = True,导致参数不生效。 - 批量删除形状务必倒序遍历,正序删除会因为集合索引实时变化而跳过元素。
- 处理完及时调用
Dispose()释放资源。
总结
本文介绍了用 Python 在 Excel 中操作形状的完整流程:用 AddPrstGeomShape()、AddRectangle()、AddOval() 插入不同形状,用 Fill、Line、Shadow 控制外观,用 Group() 组合形状、ChangeLayer() 调整层级,以及用 Remove() 删除、Visible 隐藏、SaveToImage() 导出。掌握这些操作后,可以把仪表盘装饰、示意图标注这类重复性排版工作交给脚本完成。