Python 在 PDF 中绘制线条、矩形与自定义图形:Spire.PDF 用法梳理

不晚
不晚
发布时间:2026-08-23| 178人浏览过
原创

前言

很多 PDF 自动化任务并不只是“把字写上去”这么简单。做报表时要画分隔线,做设计标注时要框选区域,做模板文档时还可能需要加椭圆、路径图形甚至半透明叠加效果。要把这些操作放进批量生成流程里,核心不是会不会画,而是能不能把坐标、样式和复用方式控制稳定。 这篇文章按“环境准备 → 基础图形 → 复杂路径 → 透明度 → 综合示例”的顺序整理 Spire.PDF 的主要绘图能力。看完之后,你可以判断这个库适不适合自己的 PDF 标注、报表生成或模板排版场景,也能直接拿代码改成可用脚本。

很多 PDF 自动化任务并不只是“把字写上去”这么简单。做报表时要画分隔线,做设计标注时要框选区域,做模板文档时还可能需要加椭圆、路径图形甚至半透明叠加效果。要把这些操作放进批量生成流程里,核心不是会不会画,而是能不能把坐标、样式和复用方式控制稳定。

这篇文章按“环境准备 → 基础图形 → 复杂路径 → 透明度 → 综合示例”的顺序整理 Spire.PDF 的主要绘图能力。看完之后,你可以判断这个库适不适合自己的 PDF 标注、报表生成或模板排版场景,也能直接拿代码改成可用脚本。

为什么要用代码绘制 PDF 图形

相比手动在 PDF 或设计工具里拖拽图形,用 Python 生成图形更适合重复性强、参数明确的场景,原因主要有三点:

  • 精确控制:坐标、尺寸、颜色、线宽、透明度都由参数定义,适合对齐要求严格的版式。
  • 批量生成:结合循环和条件逻辑,可以一次性生成大量带标注、边框或装饰元素的 PDF。
  • 动态适配:图形可以随数据变化自动调整,例如根据数值改变矩形高度,或按内容区域重新计算分隔线位置。

如果你的需求是报表分区、模板标注、证书装饰线、可视化标记层,这类方式通常比手工处理更稳。

先准备库和画布坐标系

文中使用的库是 Spire.PDF。安装命令如下:

pip install Spire.PDF

这个库不只负责绘图,也提供页面管理、文字渲染等能力。对绘图来说,最关键的是理解它的画布模型:

  • 所有绘图操作都在页面的 PdfCanvas 对象上完成。
  • 坐标原点位于页面左下角。
  • 单位是点(point),1点 = 1/72英寸。

后面无论是画线、画矩形还是做路径变换,都是基于这一套坐标系工作。

基础图形怎么画

绘制直线

直线使用 DrawLine() 完成,只需要指定起点和终点坐标。下面这段代码同时画了一条水平线和一条斜线:

PDF 画布坐标系与基础图形方法对应关系图
PDF 画布与基础图形对应关系用一张图把 PdfCanvas 坐标系、画笔画刷。
from spire.pdf.common import *
from spire.pdf import *

# 创建 PDF 文档
doc = PdfDocument()
page = doc.Pages.Add()

# 保存画布状态
state = page.Canvas.Sa ve()

# 创建画笔(黑色,线宽 1 点)
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)

# 绘制一条从 (50, 100) 到 (400, 100) 的水平线
page.Canvas.DrawLine(pen, 50.0, 100.0, 400.0, 100.0)

# 绘制一条从 (50, 100) 到 (225, 300) 的斜线
pen2 = PdfPen(PdfRGBColor(Color.get_Red()), 1.0)
page.Canvas.DrawLine(pen2, 50.0, 100.0, 225.0, 300.0)

# 恢复画布状态
page.Canvas.Restore(state)

# 保存文档
doc.Sa veToFile("DrawLines.pdf")
doc.Close()

PdfPen 用来控制线条颜色和宽度;DrawLine() 的前两个数值是起点坐标,后两个数值是终点坐标。这里还保留了 Sa ve() 和 Restore() 的调用方式,虽然只是简单示例,但在实际项目里这是很值得保留的习惯,能减少后续样式设置互相影响的问题。

绘制虚线

虚线常用于区域分隔和范围标注。Spire.PDF 里可以通过 DashStyle 和 DashPattern 控制:

# 创建红色画笔,线宽 3 点
pen = PdfPen(PdfRGBColor(Color.get_Red()), 3.0)

# 设置虚线样式
pen.DashStyle = PdfDashStyle.Dash
pen.DashPattern = [1, 4, 1]  # 虚线模式:1点实线、4点空白、1点实线

# 绘制虚线
page.Canvas.DrawLine(pen, 50.0, 200.0, 400.0, 200.0)

PdfDashStyle 提供了 Dash、Dot、DashDot 等预设样式;如果预设不够用,再通过 DashPattern 自定义节奏。像 [1, 4, 1] 这种数组,本质上就是按“实线长度 - 空白长度 - 实线长度”的方式循环绘制。

绘制矩形

矩形是 PDF 标注场景里使用频率最高的图形之一。它既可以只画边框,也可以同时填充颜色:

# 绘制矩形边框
pen = PdfPen(PdfRGBColor(Color.get_Black()), 0.5)
# 参数:画笔、x、y、宽度、高度
page.Canvas.DrawRectangle(pen, 100.0, 150.0, 200.0, 120.0)

# 绘制带填充色的矩形
pen2 = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
brush = PdfSolidBrush(PdfRGBColor(Color.get_OrangeRed()))
rect = RectangleF(PointF(100.0, 300.0), SizeF(200.0, 120.0))
page.Canvas.DrawRectangle(pen2, brush, rect)

DrawRectangle() 常见有两种用法:一种直接传入 x、y、宽度和高度,只画轮廓;另一种配合 PdfBrush 一起使用,既画边框又填充内部颜色。这里的 PdfSolidBrush 是最基础也最常用的填充方式。

绘制椭圆和圆形

椭圆通常用于辅助标注、流程节点或局部高亮。对应的方法是 DrawEllipse():

# 绘制椭圆边框(以矩形边界定义椭圆范围)
pen = PdfPen(PdfRGBColor(Color.get_CadetBlue()), 1.0)
# 参数定义外接矩形的范围,椭圆会被绘制在该矩形内部
page.Canvas.DrawEllipse(pen, 220.0, 320.0, 100.0, 90.0)

# 绘制填充椭圆
brush = PdfSolidBrush(PdfRGBColor(Color.get_CadetBlue()))
page.Canvas.DrawEllipse(brush, 380.0, 325.0, 80.0, 80.0)

# 第三个和第四个参数分别控制水平半径和垂直半径
# 当两者相等时即为正圆
page.Canvas.DrawEllipse(brush, 100.0, 450.0, 50.0, 50.0)  # 这行会绘制一个正圆

这里可以直接抓住一个要点:椭圆不是单独定义出来的,而是放在外接矩形内部。外接矩形越接近正方形,图形就越接近正圆。

复杂图形怎么用路径拼出来

当直线、矩形和椭圆不够用时,就需要借助 PdfPath。它适合处理五角星、多边形或其他需要由多条线段和曲线组合的图形。

自定义路径与坐标变换关系图
PdfPath 路径构建与复用流程展示 PdfPath 从顶点计算到路径拼接,再到缩放和平移后复用的过程。
import math

# 计算五边形的五个顶点
points = [None] * 5
for i in range(5):
    x = float(math.cos(i * 2 * math.pi / 5))
    y = float(math.sin(i * 2 * math.pi / 5))
    points[i] = PointF(x, y)

# 创建路径并添加线段
path = PdfPath()
path.AddLine(points[2], points[0])
path.AddLine(points[0], points[3])
path.AddLine(points[3], points[1])
path.AddLine(points[1], points[4])
path.AddLine(points[4], points[2])

# 绘制路径轮廓
pen = PdfPen(PdfRGBColor(Color.get_DeepSkyBlue()), 0.02)
page.Canvas.ScaleTransform(50.0, 50.0)
page.Canvas.TranslateTransform(5.0, 5.0)
page.Canvas.DrawPath(pen, path)

# 绘制填充路径
brush = PdfSolidBrush(PdfRGBColor(Color.get_DeepSkyBlue()))
page.Canvas.DrawPath(pen, brush, path)

PdfPath 的价值在于“先定义路径,再统一绘制”。除了 AddLine(),还可以继续使用 AddArc()、AddCurve() 等方法拼出更复杂的轮廓。

这一段代码还顺带展示了两个很重要的变换操作:

  • ScaleTransform():缩放当前坐标系,让小尺寸路径按比例放大。
  • TranslateTransform():平移坐标系,把同一个图形移动到新位置。

如果你要在一页里重复放置同一种图标或标记,这种做法会比手工重算每个点坐标更省事。

图形叠加时如何控制透明度

多个图形叠加时,透明度控制会直接影响可读性。Spire.PDF 通过 SetTransparency() 处理这个问题:

PDF 图形透明度叠加效果对比图
透明度参数与叠加效果对比对比 1.0、0.5、0.2 不同透明度下的图形覆盖效果,并标出适合的应用场景。
# 设置透明度(参数范围 0.0~1.0,0.0 完全透明,1.0 不透明)
page.Canvas.SetTransparency(0.5, 0.5)

# 在此之后绘制的图形将以 50% 透明度显示
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
brush = PdfSolidBrush(PdfRGBColor(Color.get_Red()))
page.Canvas.DrawRectangle(pen, brush, RectangleF(PointF(200.0, 300.0), SizeF(200.0, 100.0)))

# 设置不同的透明度
page.Canvas.SetTransparency(0.2, 0.2)
page.Canvas.DrawRectangle(pen, brush, RectangleF(PointF(300.0, 250.0), SizeF(200.0, 100.0)))

这里的参数范围是 0.0~1.0:0.0 表示完全透明,1.0 表示完全不透明。它特别适合做高亮遮罩、重叠标注区、设计审阅层这类需要“看得到下面内容”的场景。

完整示例:把常见图形放到同一个 PDF 页面

下面这段示例把前面的直线、虚线、矩形、椭圆组合到一个页面中,适合直接作为起步模板:

from spire.pdf.common import *
from spire.pdf import *
import math

# 创建文档
doc = PdfDocument()
page = doc.Pages.Add()

# 保存画布状态
state = page.Canvas.Sa ve()

# 1. 绘制直线
pen = PdfPen(PdfRGBColor(Color.get_Black()), 1.0)
page.Canvas.DrawLine(pen, 50.0, 50.0, 200.0, 50.0)

# 2. 绘制虚线
pen_dash = PdfPen(PdfRGBColor(Color.get_Red()), 2.0)
pen_dash.DashStyle = PdfDashStyle.Dash
page.Canvas.DrawLine(pen_dash, 50.0, 80.0, 200.0, 80.0)

# 3. 绘制矩形边框
pen_rect = PdfPen(PdfRGBColor(Color.get_Blue()), 1.0)
page.Canvas.DrawRectangle(pen_rect, 50.0, 120.0, 150.0, 100.0)

# 4. 绘制填充矩形
pen_fill = PdfPen(PdfRGBColor(Color.get_Black()), 0.5)
brush_fill = PdfSolidBrush(PdfRGBColor(Color.get_OrangeRed()))
page.Canvas.DrawRectangle(pen_fill, brush_fill, 
    RectangleF(PointF(50.0, 250.0), SizeF(150.0, 100.0)))

# 5. 绘制椭圆
brush_ellipse = PdfSolidBrush(PdfRGBColor(Color.get_CadetBlue()))
page.Canvas.DrawEllipse(brush_ellipse, 300.0, 120.0, 100.0, 80.0)

# 6. 绘制正圆
page.Canvas.DrawEllipse(brush_ellipse, 300.0, 250.0, 60.0, 60.0)

# 恢复画布状态
page.Canvas.Restore(state)

# 保存
doc.Sa veToFile("ShapesDemo.pdf")
doc.Close()

如果你只是想快速验证环境是否正常,这段综合代码比逐个方法单独测试更有效。能顺利输出 ShapesDemo.pdf,通常就说明基础绘图流程已经打通。

总结:哪些场景最适合用这套方法

从能力边界看,Spire.PDF 已经覆盖了大部分常见 PDF 图形绘制需求:基础线条、虚线样式、矩形与填充、椭圆与圆形、自定义路径,以及叠加时的透明度控制。

如果你的工作偏向报表生成、模板标注、证书装饰、审阅批注层,这套方法足够直接;如果后续还要做更复杂的视觉效果,可以继续往渐变填充、更多路径方法、坐标变换和图层组织方向深入。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。