Reportlab生成PDF文件

Reportlab的互动式form官方技术说明(interactive form)语焉不详,只简单的列了参数。网上能找到的资料也有限,这篇博客:http://www.blog.pythonlibrary.org/2018/05/29/creating-interactive-pdf-forms-in-reportlab-with-python/满满的干货,很有启发,我们在其基础上做些修改和本地化,尝试着把交互式form的用法理清楚。

这个帖子我们来看单选项radio,主函数部分跟上一个多选项checkbox的帖子基本相同,都是设置字体和调用画单选项radio的函数create_simple_radios():

if __name__ == '__main__':
    # 生成画布对象
    from reportlab.pdfgen import canvas
    c = canvas.Canvas('speCap.pdf')
    
    from reportlab.pdfbase.ttfonts import TTFont
    from reportlab.pdfbase import pdfmetrics
    # 注册要使用的中文字体文件,并给这个中文字体起名字zoomla
    pdfmetrics.registerFont(TTFont('zoomla', 
                '/Library/Fonts/Chinese/MoMoXiuLiTi-2.ttf'))
   
    # 调用函数往画布上加多选项
    create_simple_radios(c)
    c.showPage()  # 标识一页的结束
    c.save()      # 将画布内容保存成pdf文件

单选项跟多选项不同,单选项一组只能有一个选项被选中,所以单选项要明确分组。先来看两组单选项的显示效果:

伤怀日是一组group1,寂寥时是另一组group2,在组内只有一个选项能被选中:

def create_simple_radios(c):
    c.setFont("zoomla", 24)    # 设置字体和大小
    c.drawCentredString(300, 750, 'Radio')  # 写标题
    form = c.acroForm          # 在程序中用form代替c.acroForm

    c.setFont("zoomla", 20)
    c.drawCentredString(200, 700, '伤怀日')
    
    c.setFont("zoomla", 16)
    c.drawString(150, 650, '史湘云:')
    form.radio(name='group1', tooltip='憨情',
    # 用name=参数表明是否为同一组的按钮,name不同为不同组
    # tooltip=鼠标悬停时会显示,但同一组只能有一个显示,显示组内第一个按钮的tooltip
               value='cloud', selected=False,
    # value=同一组按钮的value值不能相同,否则选中一个另一个也会显示选中的
    # selected=初始情况下是不是被选中,False为不选中
               x=210, y=650, buttonStyle='check',
    # x=,y=表明位置;buttonStyle=选中时画对勾
               borderStyle='solid', shape='square',
    # borderStyle=按钮边的样式,下一个帖子会把各个样式集合起来一起对比
    # shape=按钮的形状,这一组是方形,寂寥时那一组是圆形
               borderColor=blue, fillColor=magenta,
    # borderColor=, fillColor=鼠标悬停在这个按钮时的边界和填充色
               textColor=blue, forceBorder=True)
    # textColor=选中标识的颜色,这里是对勾
    # forceBorder=理论上是是否显示按钮的边界,可实际上True或False按钮初始的红色边界都显示
    c.drawString(150, 600, '妙玉:')
    form.radio(name='group1', tooltip='度情',
    # 这个tooltip=不起作用,鼠标悬停显示的是第一个按钮的tooltip
               value='jade', selected=False,
               x=210, y=600, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=blue, fillColor=green,
               textColor=black, forceBorder=True)

    c.drawString(150, 550, '巧姐:')
    form.radio(name='group1', tooltip='恩情',
               value='qiao', selected=False,
               x=210, y=550, buttonStyle='check',
               borderStyle='solid', shape='square',
               borderColor=blue, fillColor=blue,
               textColor=blue, forceBorder=True)

    c.setFont("zoomla", 20)
    c.drawCentredString(400, 700, '寂寥时:')

    c.setFont("zoomla", 16)
    c.drawString(350, 650, '元春:')
    form.radio(name='group2', tooltip='原应叹息',
    # 注意这组按钮的name=与伤怀日那一组不同
               value='first', selected=False,
               x=450, y=650, buttonStyle='circle',
               borderStyle='solid', shape='circle',
    # shape='circle'指明选中的标记是圆点
               borderColor=blue, fillColor=magenta,
               textColor=blue, forceBorder=False)

  c.drawString(350, 600, '迎春:')
  form.radio(name='group2', tooltip='原应叹息',
         value='second', selected=False,
         x=450, y=600, buttonStyle='circle',
         borderStyle='solid', shape='circle',
         borderColor=blue, fillColor=magenta,
         textColor=blue, forceBorder=False)

  c.drawString(350, 550, '探春:')
  form.radio(name='group2', tooltip='原应叹息',
         value='third', selected=False,
         x=450, y=550, buttonStyle='circle',
         borderStyle='solid', shape='circle',
         borderColor=blue, fillColor=magenta,
         textColor=blue, forceBorder=False)

  c.drawString(350, 500, '惜春:')
  form.radio(name='group2', tooltip='原应叹息',
         value='fourth', selected=False,
         x=450, y=500, buttonStyle='circle',
         borderStyle='solid', shape='circle',
         borderColor=blue, fillColor=magenta,
         textColor=blue, forceBorder=False)

带交互式form的pdf允许用户做选择和填写资料,关闭时会询问要不要保护交互结果,以后我们会介绍怎么在另外模块的帮助下自动完成选择和填写。下一个帖子介绍表格和列表,我感觉看懂后用到时,直接把互动式form的代码拷贝进来,修修补补可以用就行了。

全部代码:

def create_simple_radios(c):
	c.setFont("zoomla", 24)
	c.drawCentredString(300, 750, 'Radio')
	form = c.acroForm

	# 一个group只能有一个tooltip
	#GROUP ONE, name='group1'
	c.setFont("zoomla", 20)
	c.drawCentredString(200, 700, '伤怀日')
	c.setFont("zoomla", 16)

	c.drawString(150, 650, '史湘云:')
	form.radio(name='group1', tooltip='憨情',
			   value='cloud', selected=False,
			   x=210, y=650, buttonStyle='check',
			   borderStyle='solid', shape='square',
			   borderColor=blue, fillColor=magenta,
			   textColor=blue, forceBorder=True)

	c.drawString(150, 600, '妙玉:')
	form.radio(name='group1', tooltip='度情',
			   value='jade', selected=False,
			   x=210, y=600, buttonStyle='check',
			   borderStyle='solid', shape='square',
			   borderColor=blue, fillColor=green,
			   textColor=black, forceBorder=True)

	c.drawString(150, 550, '巧姐:')
	form.radio(name='group1', tooltip='恩情',
			   value='qiao', selected=True,
			   x=210, y=550, buttonStyle='check',
			   borderStyle='solid', shape='square',
			   borderColor=blue, fillColor=blue,
			   textColor=blue, forceBorder=True)

	#GROUP TWO, name='group2'
	c.setFont("zoomla", 20)
	c.drawCentredString(400, 700, '寂寥时:')

	c.setFont("zoomla", 16)
	c.drawString(350, 650, '元春:')
	form.radio(name='group2', tooltip='原应叹息',
			   value='first', selected=True,
			   x=450, y=650, buttonStyle='circle',
			   borderStyle='solid', shape='circle',
			   borderColor=blue, fillColor=magenta,
			   textColor=blue, forceBorder=True)

	c.drawString(350, 600, '迎春:')
	form.radio(name='group2', tooltip='原应叹息',
			   value='second', selected=False,
			   x=450, y=600, buttonStyle='circle',
			   borderStyle='solid', shape='circle',
			   borderColor=blue, fillColor=magenta,
			   textColor=blue, forceBorder=False)

	c.drawString(350, 550, '探春:')
	form.radio(name='group2', tooltip='原应叹息',
			   value='third', selected=False,
			   x=450, y=550, buttonStyle='circle',
			   borderStyle='solid', shape='circle',
			   borderColor=blue, fillColor=magenta,
			   textColor=blue, forceBorder=False)

	c.drawString(350, 500, '惜春:')
	form.radio(name='group2', tooltip='原应叹息',
			   value='fourth', selected=False,
			   x=450, y=500, buttonStyle='circle',
			   borderStyle='solid', shape='circle',
			   borderColor=blue, fillColor=magenta,
			   textColor=blue, forceBorder=False)

if __name__ == '__main__':

	c = canvas.Canvas('speCap.pdf')

	from reportlab.pdfbase.ttfonts import TTFont
	from reportlab.pdfbase import pdfmetrics
	pdfmetrics.registerFont(TTFont('zoomla', '/Library/Fonts/Chinese/MoMoXiuLiTi-2.ttf'))

	create_simple_radios(c)

	c.showPage()
	c.save()