Python系列 之 ReportLab库 pdfgen模块Canvas对象绘制图形和文本

本文介绍了如何使用Python的ReportLab库中的pdfgen模块创建PDF文档,特别是Canvas对象的使用,包括注册字体解决中文显示问题、设置字体、绘制字符串、直线、形状、图片,以及颜色、线条样式等的操作。详细阐述了各种绘制方法和对象,如drawString、line、rect、drawImage等,并展示了实际应用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ReportLab库

pdfgen模块

pdfgen包是生成PDF文档的最低级别接口,用于将文档“绘制”到一系列页面上。提供绘制操作的接口对象是pdfgen.canvas.Canvas对象

Canvas对象

Canvas对象可以把它当做一张白纸,纸上的点使用笛卡尔(X,Y)坐标进行标识,默认情况下,(0,0)原点位于页面的左下角。另外,默认情况下,第一个坐标x向右移动,第二个坐标y向上移动。
实例化一个Canvas对象:

from reportlab.pdfgen import canvas
# 参数
# filename 最终的PDF文件名
# pagesize 两个点数的tuple 用来定义页面大小,默认是A4大小
# 在reportlab.lib.pagesize中定义了letter,A4等页面大小
# bottomup将来可能会被放弃 为了转换坐标
# pageCompression 是否对PDF操作进行压缩,默认情况下不被压缩,压缩会减慢运行速度\
# 如果页面有大量的文本和矢量图形的话压缩会节省空间
# encrypt 如果赋值一个字符串的话 将会作为PDF的用户密码使用
cav = canvas.Canvas(
            filename=filename, pagesize=None, bottomup=1,
            pageCompression=1, encrypt=None)

有了Canvas对象,就可以使用对象的绘制方法将内容绘制在PDF文档的页面中,下面介绍Canvas对象的一些绘制方法

关于注册字体(中文显示问题)

如果想要写入中文文本是必须要注册支持中文的字体,要不然是无法显示绘制的中文的:

from reportlab.pdfbase import pdfmetrics, ttfonts
# simsun字体文件的存放路径
simsun_FONT_PATH = "./fonts/simsun.ttc"
# 注册字体解决中文显示问题
# TTFont方法的参数:
# name 需要注册字体的名称(psfontname) 
# filename 字体存放的路径
font = ttfonts.TTFont(name="simsun", filename=simsun_FONT_PATH)
pdfmetrics.registerFont(font=font)
# 后续使用setFont方法设置字体显示
# setFont方法的psfontname参数调用TTFont的name也就是'simsun'

Canvas对象的绘制操作

showPage方法

showPage方法用来结束一个页面的绘制;
在完成当前页面绘制的同时,保存Canvas对象绘制的当前页面内容,如果后续有新的绘制将在下一个页面进行;
需要注意的是当前设置的字体 颜色 旋转等样式在一下一个页面都会进行重置,也就是这些样式在各个页面之间都是不进行传递的

cav.showPage()

save方法

当所有的PDF页面都绘制完成后需要调用Canvas对象的save方法来进行保存到本地磁盘,保存的文件就是Canvas对象的filename参数

cav.save()

设置字体

setFont方法
setFont方法可以设置字体的字体名称以及大小

# 设置字体方法
# setFont(psfontname, size, leading=None)
# psfontname 字体名称 size 字体大小 leading 行间距
# psfontname 可以使用 registerFont方法注册的TTFont对象的name
cav.setFont(psfontname="simsun", size=10, leading=1)

绘制字符串

在PDF页面上绘制字符串内容,drawString,drawRightString和drawCentredString等方法,都是用来绘制字符串内容的方法

方法 说明
drawString 以X坐标为起点进行绘制
drawRightString 以X坐标为终点进行绘制
drawCentredString 以X坐标为中心进行绘制

drawString方法
drawString方法用来在页面的指定位置进行绘制字符串内容
字符以X坐标为起点进行绘制

# 设置字体 字体名称和字体大小
cav.setFont(psfontname="simsun", size=10, leading=1)
# drawString(x, y, text, mode=None, charSpace=0, direction=None, wordSpace=None)
# 参数 x=x坐标 y=y坐标 text=绘制的内容 str
text = "ReportLab库的学习"
x = 300
y = 420
cav.drawString(x=x, y=y, text=text)

drawRightString方法
drawRightString 绘制与X坐标右对齐的字符串;也就是以X坐标为终点

# drawRightString(x, y, text, mode=None, charSpace=0, direction=None, wordSpace=None)
cav.drawRightString(x, y-10, "drawRightString "+text)

drawCentredString方法
drawCentredString 绘制以X坐标为中心的字符串

# drawCentredString(x, y, text, mode=None, charSpace=0, direction=None, wordSpace=None)
cav.drawCentredString(x, y-20, "drawCentredString "+text)

在这里插入图片描述

绘制直线

绘制直线的方法line和lines

方法 说明
line 提供两个点的坐标,绘制一条直线
lines 提供一组坐标list,绘制多条直线

line方法
每次绘制一条直线

# line(x1, y1, x2, y2)
# x1和y1 作为起点坐标 x2和y2 作为终点坐标 画一条直线
cav.line(x1=300, y1=400, x2=300, y2=550)
cav.drawCentredString(x=300, y=390, text="line方法")

lines方法
可以绘制多条直线

# 存放多条线的坐标
crosshairs = [(350, 550, 400, 550),
              (350, 500, 450, 500),
              (350, 450, 500, 450),
              (350, 400, 550, 400), ]
# 画多条线 参数 linelist 存放多条线的坐标
cav.lines(linelist=crosshairs)
cav.drawCentredString(x=450, y=380, text="lines方法")

以上就是Canvas对象绘制直线的方法:
再执行showPage()和save()方法就会对PDf文件进行保存

cav.showPage()
cav.save()

在这里插入图片描述

绘制形状

方法 说明
grid 根据一组X坐标和一组Y坐标绘制网格
rect 绘制矩形
circle 绘制一个圆形
roundRect 绘制一个圆角的矩形
arc 根据矩形坐标内绘制一个指定角度的椭圆
ellipse 在一个封闭的矩形坐标内绘制一个椭圆
wedge 绘制一个楔形

grid方法
grid 方法 绘制网格 ; 根据xlist=X轴坐标list 和 ylist=Y轴坐标list;
其中 xlist和ylist都必须至少2个元素

# 设置字体 字体名称和字体大小
cav.setFont(psfontname="simsun", size=10, leading=1)
# grid(xlist, ylist)
# grid 绘制网格  xlist X轴坐标list  ylist Y轴坐标list
# 源码:grid方法主要逻辑:
#-------+++++++++++----------
# lines = []
# y0, y1 = ylist[0], ylist[-1]
# x0, x1 = xlist[0], xlist[-1]
# for x in xlist:
#     lines.append((x, y0, x, y1))
# for y in ylist:
#     lines.append((x0, y, x1, y))
# Canvas.lines(lines)
#-------+++++++++++----------

xlist = [50, 150, 200, 300]
ylist = [800, 750, 700, 650]
cav.grid(xlist=xlist, ylist=ylist)
cav.drawCentredString(x=175, y=810, text="grid方法")

在这里插入图片描述

rect方法
rect方法绘制矩形,根据一个坐标点,以及给出的宽度和高度绘制,根据给出的宽度和高度的数值可以决定左右和上下的绘制方向

# rect 绘制矩形
# rect(x, y, width, height, stroke=1, fill=0)
# x, y 坐标点
# width 矩形宽度 正数 向右绘制,负数 向左绘制
# height 矩形高度 正数 向上绘制,负数 向下绘制
# stroke 是否显示边框 1 显示 0 不显示 默认显示
# fill 是否对矩形区域填充 1 填充 0 不填充 默认不填充
cav.rect(x=350, y=800, width=200, height=-150, stroke=1, fill=0)
cav.drawCentredString(x=450, y=810, text="rect方法")

在这里插入图片描述

circle方法
circle方法根据给定的圆心坐标以及圆的半径绘制一个圆形

# circle 绘制一个圆形 x_cen 圆心的X坐标 y_cen圆心的Y坐标 r 圆的半径
# circle( x_cen, y_cen, r, stroke=1, fill=0)
# x_cen, y_cen 圆心的X Y 坐标
# r 圆的半径 
# stroke 边框
# fill 填充
cav.circle(x_cen=175, y_cen=500, r=120, stroke=1, fill=0)
cav.drawCentredString(x=175, y=630, text="circle方法")

在这里插入图片描述

roundRect方法
roundRect 绘制一个圆角的矩形

# roundRect 绘制一个圆角的矩形 radius参数是矩形四个角圆形的半径 类似CSS的border-radius?
# roundRect(x, y, width, height, radius, stroke=1, fill=0)
# 参数 同 rect方法
cav.roundRect(x=350, y=620, width=200, height=-240, radius=50, stroke=1, fill=0)
cav.drawCentredString(x=450, y=630, text="roundRect方法")

在这里插入图片描述

arc方法
arc 在矩形x1,y1,x2,y2内画一个指定角度的椭圆

# arc 在矩形x1,y1,x2,y2内画一个椭圆 从startAng度开始逆时针画extent度
# arc(x1, y1, x2, y2, startAng=0, extent=90)
# 由x1, y1, x2, y2组成的矩形,从startAng(默认0)开始逆时针画extent度(默认90)
cav.arc(x1=50, y1=10, x2=300, y2=330, startAng=90, extent=270)
cav.drawCentredString(x=175, y=340, text="arc方法")
<think>好的,我现在需要帮助用户了解如何使用ReportLabpdfgen模块生成PDF文件。根据用户提供的引用问题,我需要先整理已有的信息,并按照系统指令的要求来构建回答。 首先,用户提供的引用中有几个关键点: 1. 引用[1]给出了一个示例函数create_pdf,使用了Canvas类来生成PDF。 2. 引用[2]提到需要从reportlab.pdfgen导入Canvas类。 3. 引用[3]提供了ReportLab的文档链接,可能对用户有帮助。 4. 引用[4]解释了pdfgen包是底层接口,使用Canvas对象进行绘制。 接下来,我需要按照用户的要求,结构清晰地分步骤说明如何使用pdfgen模块。同时,要确保所有数学表达式代码块符合格式要求,比如行内数学式用$...$,独立公式用$$...$$,代码块用三个反引号包裹,并标明语言。 首先,我应该从安装开始,但用户可能已经安装了,不过为了全面性,还是可以提到安装步骤。但根据引用中的信息,用户可能已经导入了Canvas,所以可能更关注基本用法。 然后,步骤可能包括: 1. 导入Canvas类。 2. 创建Canvas实例,指定文件名。 3. 使用Canvas的方法绘制内容,比如drawString。 4. 保存PDF文件。 在示例代码中,用户给出的引用[1]有一个函数示例,但参数是inputoutput,而代码中并未使用input,可能需要调整。例如,正确的用法可能是直接创建Canvas对象,设置参数,然后调用绘制方法。 另外,需要注意代码中的参数是否正确。例如,在引用[1]的代码示例中,函数定义可能有误,因为Canvas的初始化通常需要文件名作为参数。可能需要修正示例代码,比如将output传递给Canvas的构造函数。 然后,用户可能需要更详细的步骤,比如设置页面大小、添加不同元素(文本图形、图像),设置字体等。根据引用[4],pdfgen提供了绘制操作,所以需要涵盖这些方面。 同时,回答中需要引用用户提供的引用,比如在提到创建Canvas对象时引用[4],在导入时引用[2]等。 还需要生成相关问题,可能涉及高级功能、处理中文、调整布局等。 现在需要组织这些信息,确保结构清晰,步骤正确,代码示例无误,并且自然引用提供的引用链接。 可能的步骤: 1. 安装ReportLab(如果用户没有提到,但可能有用) 2. 导入Canvas类 3. 创建Canvas对象,指定文件名页面大小(引用[4]) 4. 绘制文本,设置字体位置(引用[2][4]) 5. 绘制图形,如线条、矩形等 6. 保存PDF文件 检查代码示例是否正确,比如用户引用中的代码是否有误。例如,引用[1]中的函数可能存在问题,因为创建Canvas应该用canvas.Canvas(output),而不是作为参数传递给函数。需要纠正这一点,给出正确示例。 例如,正确的示例应该是: from reportlab.pdfgen import canvas def create_pdf(output="disk_report.pdf"): c = canvas.Canvas(output) c.drawString(100, 800, "Hello World") c.save() 这样更符合ReportLab的标准用法,而用户引用[1]中的函数可能需要调整,因此在回答中给出正确的代码示例,并指出可能的问题。 同时,确保每个引用被正确标注,例如在提到Canvas对象时引用[4],在导入时引用[2]。 最后,生成相关问题,如处理中文、添加图片、分页等。</think>### 如何使用 ReportLab pdfgen 模块生成 PDF 文件 #### 1. 安装 ReportLab ```bash pip install reportlab ``` #### 2. 基本文件生成步骤 1. **导入 Canvas 类** ```python from reportlab.pdfgen import canvas # [^2] ``` 2. **创建 Canvas 对象** 指定输出文件名页面大小(默认 A4): ```python c = canvas.Canvas("output.pdf", pagesize=(595, 842)) # [^4] ``` 3. **添加文本内容** 使用 `drawString(x, y, text)` 方法,坐标原点在页面左下角: ```python c.setFont("Helvetica", 12) # 设置字体 c.drawString(100, 800, "Hello World") # 在 (100,800) 位置绘制文本 ``` 4. **绘制图形** 支持线条、矩形、圆形等: ```python c.line(100, 780, 300, 780) # 绘制水平线 c.rect(100, 700, 200, 50) # 绘制矩形(x,y,宽,高) ``` 5. **保存文件** ```python c.save() # 必须调用 save() 才会生成文件 [^1] ``` #### 3. 完整示例代码 ```python from reportlab.pdfgen import canvas def create_pdf(output="demo.pdf"): c = canvas.Canvas(output) c.setFont("Helvetica-Bold", 16) c.drawString(100, 800, "ReportLab PDF 示例") c.setFont("Helvetica", 12) c.drawString(100, 750, "生成时间:2023-10-01") c.line(100, 740, 300, 740) c.rect(100, 650, 400, 80, fill=1) # 填充矩形 c.save() ``` #### 4. 关键参数说明 | 方法 | 功能说明 | 示例参数 | |---------------------|----------------------------|-----------------------------| | `setFont(font,size)`| 设置字体样式 | ("Times-Roman", 12) | | `drawImage(path,x,y)`| 插入图片 | "chart.png", 100, 600 | | `showPage()` | 新建页面 | 无参数 | | `setFillColor(color)`| 设置填充颜色 | "red" 或十六进制值 "#FF0000" |
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值