Python系列 之 ReportLab库 pdfgen模块Canvas对象绘制图形和文本
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