python reportlab: pdfgen(二)
颜色
PDF中常用的颜色有两个类型:
- RGB:常用于屏幕显示
- CMYK:常用于专业的印刷场景
RGB颜色
RGB即红(red),绿(green)和蓝(blue)。用这三种颜色的参数形成各种不同的颜色,比如 (1,1,1) 就代表白色。
在pdfgen中有3中方法可以生成颜色:
- 使用color模块
- 使用RGB值
- 使用灰度
下面的例子展示了这些方法:
from reportlab.pdfgen import canvas
def colorsRGB(canvas):
from reportlab.lib import colors
from reportlab.lib.units import inch
# 使用color模块生成颜色
black = colors.black
y = x = 0; dy=inch*3/4.0; dx=inch*5.5/5; w=h=dy/2; rdx=(dx-w)/2
rdy=h/5.0; texty=h+2*rdy
canvas.setFont("Helvetica",10)
for [namedcolor, name] in (
[colors.lavenderblush, "lavenderblush"],
[colors.lawngreen, "lawngreen"],
[colors.lemonchiffon, "lemonchiffon"],
[colors.lightblue, "lightblue"],
[colors.lightcoral, "lightcoral"]):
canvas.setFillColor(namedcolor)
canvas.rect(x+rdx, y+rdy, w, h, fill=1)
canvas.setFillColor(black)
canvas.drawCentredString(x+dx/2, y+texty, name)
x = x+dx
y = y + dy; x = 0
# 使用RGB值生成颜色
for rgb in [(1,0,0), (0,1,0), (0,0,1), (0.5,0.3,0.1), (0.4,0.5,0.3)]:
r,g,b = rgb
canvas.setFillColorRGB(r,g,b)
canvas.rect(x+rdx, y+rdy, w, h, fill=1)
canvas.setFillColor(black)
canvas.drawCentredString(x+dx/2, y+texty, "r%s g%s b%s"%rgb)
x = x+dx
y = y + dy; x = 0
# 使用灰度生成颜色
for gray in (0.0, 0.25, 0.50, 0.75, 1.0):
canvas.setFillGray(gray)
canvas.rect(x+rdx, y+rdy, w, h, fill=1)
canvas.setFillColor(black)
canvas.drawCentredString(x+dx/2, y+texty, "gray: %s"%gray)
x = x+dx
c= canvas.Canvas("colorsRGB.pdf")
colorsRGB(c)
c.showPage()
c.save()
效果如下:
RGB颜色透明度
在pdfgen中有两种方式设置颜色透明度:
- 在CMYK中可以使用overPrint,这在之后会详细介绍。
- 在RGB中可以通过调节α参数来设置透明度,默认的α值是1,即完全不透明,其取值范围为[0,1]。
两种方法的效果类似。下面是调节α参数的例子:
from reportlab.pdfgen import canvas
def alpha(canvas):
from reportlab.lib.colors import Color, black, blue, red
#透明度为50%的红色
red50transparent = Color( 100, 0, 0, alpha=0.5)
c = canvas
c.setFillColor(black)
c.setFont('Helvetica', 10)
c.drawString(25,180, 'solid')
c.setFillColor(blue)
c.rect(25,25,100,100, fill=True, stroke=False)
c.setFillColor(red)
c.rect(100,75,100,100, fill=True, stroke=False)
c.setFillColor(black)
c.drawString(225,180, 'transparent')
c.setFillColor(blue)
c.rect(225,25,100,100, fill=True, stroke=False)
c.setFillColor(red50transparent)
c.rect(300,75,100,100, fill=True, stroke=False)
c= canvas.Canvas("alpha.pdf")
alpha(c)
c.showPage()
c.save()
效果如下图:
CMYK颜色
CMYK(印刷四色模式)是四种标准颜色混合叠加形成各种印刷颜色的模式。四种标准颜色是:C:Cyan = 青色,又称为‘天蓝色’或是‘湛蓝’;M:Magenta = 品红色,又称为‘洋红色’;Y:Yellow = 黄色;K:blacK=黑色。生成CMYK中各种颜色的值可以用[0,1](真值)表示,也可以用[0,100](整值)表示。0表示没有颜料,即白色;1或100表示某种颜色的最大值。下面是使用CMYK颜色的例子:
from reportlab.pdfgen import canvas
def colorsCMYK(canvas):
from reportlab.lib.colors import CMYKColor
from reportlab.lib.units import inch
# 使用CMYK真值生成黑色
black = CMYKColor(0,0,0,1)
# 使用CMYK整值生成青色
# cyan = PCMYKColor(100,0,0,0)
y = x = 0; dy=inch*3/4.0; dx=inch*5.5/5; w=h=dy/2; rdx=(dx-w)/2
rdy=h/5.0; texty=h+2*rdy
canvas.setFont("Helvetica",10)
y = y + dy; x = 0
# 分别生成青色、品红色、黄色、黑色和白色
for cmyk in [(1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1), (0,0,0,0)]:
c,m,y1,k = cmyk
canvas.setFillColorCMYK(c,m,y1,k)
canvas.rect(x+rdx, y+rdy, w, h, fill=1)
canvas.setFillColor(black)
canvas.drawCentredString(x+dx/2, y+texty, "c%s m%s y%s k%s"%cmyk)
x = x+dx
c= canvas.Canvas("colorsCMYK.pdf")
colorsCMYK(c)
c.showPage()
c.save()
效果如下:
颜色overPrint
在CMYK中如果两种颜色重叠,就不能像RGB中那样使用α值来调节透明度了,只能使用overPrint
,使重叠的部分的颜色混合。注意overprint的效果要用Adobe Acrobat Reader才能看得出来,其他pdf软件看不出混合效果。
使用白色形成在色块上抠字的效果
from reportlab.pdfgen import canvas
def spumoni(canvas):
from reportlab.lib.units import inch
from reportlab.lib.colors import pink, green, brown, white
x = 0; dx = 0.4*inch
# 生成底层色块
for i in range(4):
for color in (pink, green, brown):
canvas.setFillColor(color)
canvas.rect(x,0,dx,3*inch,stroke=0,fill=1)
x = x+dx
# 在色块上绘制白色的文字
canvas.setFillColor(white)
canvas.setStrokeColor(white)
canvas.setFont("Helvetica-Bold", 85)
canvas.drawCentredString(2.75*inch, 1.3*inch, "SPUMONI")
c= canvas.Canvas("spumoni.pdf")
spumoni(c)
c.showPage()
c.save()
效果如下图:
最后一个字母没有显示,是因为它已经在色块外面,和白色的页面融为一体了。
这个例子主要说明,在绘制有颜色的对象的时候要注意图层的先后顺序,后绘制的会覆盖先绘制的。
标准字体和文本对象
setFont
函数可以设置字体和字号,setFillColor
函数可以为文字添加颜色。例子如下:
from reportlab.pdfgen import canvas
def textsize(canvas):
from reportlab.lib.units import inch
from reportlab.lib.colors import magenta, red
# 设置字体和字号
canvas.setFont("Times-Roman", 20)
# 设置颜色
canvas.setFillColor(red)
canvas.drawCentredString(2.75*inch, 2.5*inch, "Font size examples")
canvas.setFillColor(magenta)
size = 7
y = 2.3*inch
x = 1.3*inch
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
canvas.setFont("Helvetica", size)
canvas.drawRightString(x,y,"%s points: " % size)
canvas.drawString(x,y, line)
y = y-size*1.2
size = size+1.5
c= canvas.Canvas("textsize.pdf")
textsize(c)
c.showPage()
c.save()
效果如下:
下面这个例子展现不同的字体效果:
from reportlab.pdfgen import canvas
def fonts(canvas):
from reportlab.lib.units import inch
text = "Now is the time for all good men to..."
x = 1.8*inch
y = 2.7*inch
# 获取所有内置字体
for font in canvas.getAvailableFonts():
canvas.setFont(font, 10)
canvas.drawString(x,y,text)
canvas.setFont("Helvetica", 10)
canvas.drawRightString(x-10,y, font+":")
y = y-13
c= canvas.Canvas("fonts.pdf")
fonts(c)
c.showPage()
c.save()
运行结果如下:
其中Symbol和ZapfDingbats因为不能显示正常的文字,所以在这里显示不出来,它们只能显示特定的符号。
文本对象工具
使用drawString
生成文本时最快的,除此之外还有很多设置文本对象的工具。pdfgen中的文本对象都包括一个游标,代表文本绘制或更改的位置,这个游标可以在文本行中移动。
**注意:**每次绘制文本,都必须以canvas.beginText()
开始,并以canvas.drawText()
结束。
下面举一个绘制文本的例子:
from reportlab.pdfgen import canvas
def cursormoves2(canvas):
from reportlab.lib.units import inch
# 开始绘制文本指令
textobject = canvas.beginText()
# 设置游标起始位置
textobject.setTextOrigin(2, 2.5*inch)
textobject.setFont("Helvetica-Oblique", 14)
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
# 绘制单行文本但不换行
textobject.textOut(line)
# 移动游标,注意y轴的正数代表下移点数
textobject.moveCursor(14,14)
textobject.setFillColorRGB(0.4,0,1)
# 绘制多行文本
textobject.textLines('''
With many apologies to the Beach Boys
and anyone else who finds this objectionable
''')
# 结束绘制文本指令
canvas.drawText(textobject)
c= canvas.Canvas("cursormoves2.pdf")
cursormoves2(c)
c.showPage()
c.save()
运行效果如下:
循环中,游标每次下移一个字号单位,并且右移一个字号单位。
pdfgen中的文本对象工具总结如下:
# 设置游标起始位置
textobject.setTextOrigin(x,y)
textobject.setTextTransform(a,b,c,d,e,f)
# 移动游标
textobject.moveCursor(dx, dy)
(x,y) = textobject.getCursor()
x = textobject.getX(); y = textobject.getY()
textobject.setFont(psfontname, size, leading = None)
# 绘制单行文本,但不换行
textobject.textOut(text)
# 绘制单行文本,并且换行
textobject.textLine(text='')
# 绘制多行文本
textobject.textLines(stuff, trim=1)
注意:textOut
和textLine
的区别。使用textLine
的时候不需要移动游标来实现换行。
字符间距
setCharSpace
可以调整单个字符间的间距。且看下例:
from reportlab.pdfgen import canvas
def charspace(canvas):
from reportlab.lib.units import inch
textobject = canvas.beginText()
textobject.setTextOrigin(3, 2.5*inch)
textobject.setFont("Helvetica-Oblique", 10)
# 设置字距大小
charspace = 0
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
# 应用间距
textobject.setCharSpace(charspace)
textobject.textLine("%s: %s" %(charspace,line))
# 该表间距
charspace = charspace+0.5
textobject.setFillGray(0.4)
textobject.textLines('''
With many apologies to the Beach Boys
and anyone else who finds this objectionable
''')
canvas.drawText(textobject)
c= canvas.Canvas("charspace.pdf")
charspace(c)
c.showPage()
c.save()
效果如下:
单词间距
setWordSpace
可以调整单词间的间距。且看下例:
from reportlab.pdfgen import canvas
def wordspace(canvas):
from reportlab.lib.units import inch
textobject = canvas.beginText()
textobject.setTextOrigin(3, 2.5*inch)
textobject.setFont("Helvetica-Oblique", 12)
# 设置词距大小
wordspace = 0
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
# 应用词距
textobject.setWordSpace(wordspace)
textobject.textLine("%s: %s" %(wordspace,line))
# 改变词距
wordspace = wordspace+2.5
textobject.setFillColorCMYK(0.4,0,0.4,0.2)
textobject.textLines('''
With many apologies to the Beach Boys
and anyone else who finds this objectionable
''')
canvas.drawText(textobject)
c= canvas.Canvas("wordspace.pdf")
wordspace(c)
c.showPage()
c.save()
效果如下:
水平比例
setHorizScale
可以调整文本行的伸缩比例。且看下例:
from reportlab.pdfgen import canvas
def horizontalscale(canvas):
from reportlab.lib.units import inch
textobject = canvas.beginText()
textobject.setTextOrigin(3, 2.5*inch)
textobject.setFont("Helvetica-Oblique", 12)
# 设置伸缩比例,默认值是100
horizontalscale = 80
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
# 应用伸缩比例
textobject.setHorizScale(horizontalscale)
textobject.textLine("%s: %s" %(horizontalscale,line))
# 改变伸缩比例
horizontalscale = horizontalscale+10
textobject.setFillColorCMYK(0.0,0.4,0.4,0.2)
textobject.textLines('''
With many apologies to the Beach Boys
and anyone else who finds this objectionable
''')
canvas.drawText(textobject)
c= canvas.Canvas("horizontalscale.pdf")
horizontalscale(c)
c.showPage()
c.save()
效果如下:
行距
setLeading
可以调整文本行距。且看下例:
from reportlab.pdfgen import canvas
def leading(canvas):
from reportlab.lib.units import inch
textobject = canvas.beginText()
textobject.setTextOrigin(3, 2.5*inch)
textobject.setFont("Helvetica-Oblique", 14)
# 设置行距大小,单位为点
leading = 8
lyrics = ['well she hit Net Solutions',
'and she registered her own .com site now',
'and filled it up with yahoo profile pics',
'she snarged in one night now',
'and she made 50 million when HUgh Hefner',
'boutght up the rights now',
'and she\'ll have fun fun fun',
'til her Daddy takes the keyboard away']
for line in lyrics:
# 应用行距
textobject.setLeading(leading)
textobject.textLine("%s: %s" %(leading,line))
# 改变行距
leading = leading+2.5
textobject.setFillColorCMYK(0.8,0,0,0.3)
textobject.textLines('''
With many apologies to the Beach Boys
and anyone else who finds this objectionable
''')
canvas.drawText(textobject)
c= canvas.Canvas("leading.pdf")
leading(c)
c.showPage()
c.save()
效果如下:
上下标
setRise
可以将文本设置为上下标。