使用Python创建交互式PDF表单
Python提供了不同的功能,可以用来操作PDF文件,我们在之前的两篇使用Python处理PDF文件的教程中已经讨论了很多内容。在本教程中,我们将了解如何使用Python编程语言在PDF文件中创建交互式表单。
但在我们开始之前,我们还将讨论一个Python工具包,它可以让我们创建一个交互式表单,该工具包称为 ReportLab 工具包。
理解Python中的ReportLab工具包
Python ReportLab 工具包允许程序员创建交互式和可填写的表单。PDF标准通常包含一组丰富的交互元素。尽管 ReportLab 工具包不支持所有这些元素,但它覆盖了大部分元素。在下一节中,我们将介绍以下小部件:
- 复选框
- 单选按钮
- 选择框
- 列表框
- 文本框
所有这些小部件都是通过在 canvas.acroform 属性上调用不同的方法来开发的。请注意,每个文档只能有一个表单。让我们了解一下 ReportLab 工具包的这些小部件。
理解复选框小部件
复选框小部件就是其名字所示的。它是一个小方框,用于在表单中选择实体。 Reportlab 支持不同样式的复选框,因此当复选框被选中时,可以根据设置的样式显示不同。
现在,让我们了解一个简单的示例,说明这些参数的一些行为:
示例:
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green
def createSimpleCheckboxes():
my_Canvas = canvas.Canvas('checkboxes.pdf')
my_Canvas.setFont("Courier", 24)
my_Canvas.drawCentredString(300, 700, 'Programming Languages')
my_Canvas.setFont("Courier", 16)
form = my_Canvas.acroForm
my_Canvas.drawString(10, 650, 'Python:')
form.checkbox(
name = 'cb1',
tooltip = 'Field cb1',
x = 110,
y = 645,
buttonStyle = 'check',
borderColor = magenta,
fillColor = pink,
textColor = blue,
forceBorder = True
)
my_Canvas.drawString(10, 600, 'Java:')
form.checkbox(
name = 'cb2',
tooltip = 'Field cb2',
x = 110,
y = 595,
buttonStyle = 'cross',
borderWidth = 2,
forceBorder = True
)
my_Canvas.drawString(10, 550, 'C++:')
form.checkbox(
name = 'cb3',
tooltip = 'Field cb3',
x = 110,
y = 545,
buttonStyle = 'star',
borderWidth = 1,
forceBorder = True
)
my_Canvas.drawString(10, 500, 'C:')
form.checkbox(
name = 'cb4',
tooltip = 'Field cb4',
x = 110,
y = 495,
buttonStyle = 'circle',
borderWidth = 3,
forceBorder = True
)
my_Canvas.drawString(10, 450, 'JavaScript:')
form.checkbox(
name = 'cb5',
tooltip = 'Field cb5',
x = 110,
y = 445,
buttonStyle = 'diamond',
borderWidth = None,
checked = True,
forceBorder = True
)
my_Canvas.save()
if __name__ == '__main__':
createSimpleCheckboxes()
输出:
解释:
如我们在上面的代码片段中所观察到的,我们从 ReportLab 库的不同模块中导入了不同的函数。然后我们设置了名称并设置了工具提示以匹配小部件的名称。然后我们设置了它的位置和其他一些事情。我们可以调整复选框边框的宽度或关闭边框。但是,如果我们关闭它,复选框可能会变得不可见,因此我们可能希望通过 fillColor 设置其背景颜色来解决这个问题。我们为每个复选框设置了 buttonStyle 。
理解单选按钮小部件
radio 小部件与复选框类似,尽管单选按钮是在组中选择一个单选按钮。复选框很少限制为每个组允许一个复选框。但是,ReportLab工具包没有提供一种显式将一组单选框分组的方法。工具包仅提供了隐式分组的方式。这意味着如果我们依次创建一系列单选按钮,它们将被组合在一起。
现在,让我们使用下面的简单示例来理解:
示例:
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green
def createSimpleRadios():
my_canvas = canvas.Canvas('radiosFile.pdf')
my_canvas.setFont("Courier", 22)
my_canvas.drawCentredString(300, 700, 'Radio demo')
my_canvas.setFont("Courier", 16)
form = my_canvas.acroForm
my_canvas.drawString(10, 650, 'Python:')
form.radio(
name = 'radio1',
tooltip = 'Field radio1',
value = 'value1',
selected = False,
x = 110,
y = 645,
buttonStyle = 'check',
borderStyle = 'solid',
shape = 'square',
borderColor = magenta,
fillColor = pink,
textColor = blue,
forceBorder = True
)
form.radio(
name = 'radio1',
tooltip = 'Field radio1',
value = 'value2',
selected = True,
x = 110,
y = 645,
buttonStyle = 'check',
borderStyle = 'solid',
shape = 'square',
borderColor = magenta,
fillColor = pink,
textColor = blue,
forceBorder = True)
my_canvas.drawString(10, 600, 'Java:')
form.radio(
name = 'radio2',
tooltip = 'Field radio2',
value = 'value1',
selected = True,
x = 110,
y = 595,
buttonStyle = 'cross',
borderStyle = 'solid',
shape = 'circle',
borderColor = green,
fillColor = blue,
borderWidth = 2,
textColor = pink,
forceBorder = True
)
form.radio(
name = 'radio2',
tooltip = 'Field radio2',
value = 'value2',
selected = False,
x = 110,
y = 595,
buttonStyle = 'cross',
borderStyle = 'solid',
shape = 'circle',
borderColor = green,
fillColor=blue,
borderWidth=2,
textColor = pink,
forceBorder=True
)
my_canvas.drawString(10, 550, 'C++:')
form.radio(
name = 'radio3',
tooltip = 'Field radio3',
value = 'value1',
selected = False,
x = 110,
y = 545,
buttonStyle = 'star',
borderStyle = 'bevelled',
shape = 'square',
borderColor = blue,
fillColor = green,
borderWidth = 2,
textColor = magenta,
forceBorder = False
)
form.radio(
name = 'radio3',
tooltip = 'Field radio3',
value = 'value2',
selected = True,
x = 110,
y = 545,
buttonStyle = 'star',
borderStyle = 'bevelled',
shape = 'circle',
borderColor = blue,
fillColor = green,
borderWidth = 2,
textColor = magenta,
forceBorder = True
)
my_canvas.save()
if __name__ == '__main__':
createSimpleRadios()
输出:
说明:
在上面的代码片段中,我们从不同的模块中导入了所需的函数 ReportLab 工具包。然后,我们定义了一个函数并创建了一个新的PDF文件。然后,我们定义了不同的PDF文件的单选按钮并保存了文件。最后,我们调用了该函数。
一旦执行上面的代码片段,我们可以观察到程序只返回三个单选按钮。这是因为我们需要创建每个单选按钮的两个对象,这些对象具有相同的名称,但值和部分不同。文档没有说明背后的原因,但我们可以假设这样做是为了支持 ReportLab 工具包跟踪小部件的“已选定”状态。这也允许我们在选择或取消选择单选按钮时改变其外观。
了解选择小部件
选择 小部件基本上是一个组合框,当用户点击它时会显示下拉列表。这使得用户可以从下拉列表中选择一个或多个选项,依赖于我们设置的 fieldFlags 。如果我们插入编辑到 fieldFlags ,那么用户可以编辑选择小部件中的元素。
让我们了解以下示例,演示在PDF文档中使用 选择 小部件:
示例:
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green, red
def createSimpleChoices():
my_canvas = canvas.Canvas('choicesFile.pdf')
my_canvas.setFont("Courier", 24)
my_canvas.drawCentredString(300, 700, 'Sample Choices')
my_canvas.setFont("Courier", 16)
form = my_canvas.acroForm
my_canvas.drawString(10, 650, 'Choose a Letter:')
my_options = [('A', 'Av'), 'B', ('C', 'Cv'), ('D', 'Dv'), 'E',('F', ), ('G', 'Gv')]
form.choice(
name = 'choice1',
tooltip = 'Field choice1',
value = 'A',
x = 165,
y = 645,
width = 72,
height = 20,
borderColor = magenta,
fillColor = pink,
textColor = blue,
forceBorder = True,
options = my_options)
my_canvas.drawString(10, 600, 'Choose a Programming language:')
my_options = [('Python', 'python'), ('Java', 'java'), ('C++', 'C++')]
form.choice(
name = 'choice2',
tooltip = 'Field choice2',
value = 'Python',
options = my_options,
x = 305,
y = 595,
width = 72,
height = 20,
borderStyle = 'solid',
borderWidth = 1,
forceBorder = True
)
my_canvas.save()
if __name__ == '__main__':
createSimpleChoices()
输出:
说明:
在上面的代码片段中,我们从ReportLab工具包的不同模块中导入了所需的函数。然后,我们定义了一个函数并创建了一个新的PDF文件。然后,我们创建了两个具有稍微不同样式的 choice 小部件,并保存了文件。记得在函数中包含value参数,否则程序将返回一个与参数丢失无关的奇怪错误。最后,我们调用了这个函数。
理解列表框小部件
列表框(listbox) 小部件与 choice 小部件有些相似,不同之处在于 列表框 被视为可滚动的框而不是组合框。我们可以使用 fieldFlags 参数来支持用户从列表框中选择一个或多个元素。
现在,让我们看一个示例,说明如何在制作交互式PDF表单时使用 列表框 小部件:
示例:
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green, red
def createSimpleListboxes():
my_canvas = canvas.Canvas('listboxesFile.pdf')
my_canvas.setFont("Courier", 24)
my_canvas.drawCentredString(300, 700, 'Sample Listboxes')
my_canvas.setFont("Courier", 16)
form = my_canvas.acroForm
my_canvas.drawString(10, 650, 'Choose a letter:')
my_options = [('A','Av'),'B',('C','Cv'),('D','Dv'),'E',('F',),('G','Gv')]
form.listbox(
name = 'listbox1',
value = 'A',
x = 165,
y = 590,
width = 72,
height = 72,
borderColor = magenta,
fillColor = pink,
textColor = blue,
forceBorder = True,
options = my_options,
fieldFlags = 'multiSelect'
)
my_canvas.drawString(10, 500, 'Choose a Programming language:')
my_options = [('Python', 'python'), ('Java', 'java'), ('C++', 'C++')]
form.listbox(
name = 'choice2',
tooltip = 'Field choice2',
value = 'Python',
options = my_options,
x = 165,
y = 440,
width = 72,
height = 72,
borderStyle = 'solid',
borderWidth = 1,
forceBorder = True
)
my_canvas.save()
if __name__ == '__main__':
createSimpleListboxes()
输出:
解释:
在上面的代码片段中,我们从不同模块的ReportLab工具包中导入了所需的函数。然后,我们定义了一个函数并创建了一个新的PDF文件。然后,我们创建了稍微不同样式的listbox小部件,并保存了文件。上面的示例与之前创建选择小部件的示例非常相似。这里的主要区别是listbox小部件与选择小部件的外观;除此之外,两个小部件几乎是一样的。
理解Textfield小部件
textfield是一个文本输入小部件。我们可以在表单中看到这些textfield小部件,用于填写诸如姓名、地址等条目。大多数textfield小部件的参数与我们之前观察到的小部件的参数相同。
让我们来看下面的示例以理解这个示例:
示例:
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfform
from reportlab.lib.colors import magenta, pink, blue, green
def createSimpleForm():
my_canvas = canvas.Canvas('PDFform.pdf')
my_canvas.setFont("Courier", 24)
my_canvas.drawCentredString(300, 700, 'Application Form')
my_canvas.setFont("Courier", 16)
form = my_canvas.acroForm
my_canvas.drawString(10, 650, 'First Name:')
form.textfield(
name = 'fname',
tooltip = 'First Name',
x = 110,
y = 635,
borderStyle = 'inset',
borderColor = magenta,
fillColor = pink,
width = 300,
textColor = blue,
forceBorder = True
)
my_canvas.drawString(10, 600, 'Last Name:')
form.textfield(
name = 'lname',
tooltip = 'Last Name',
x = 110,
y = 585,
borderStyle = 'inset',
borderColor = green,
fillColor = magenta,
width = 300,
textColor = blue,
forceBorder = True
)
my_canvas.drawString(10, 550, 'Address:')
form.textfield(
name = 'address',
tooltip = 'Address',
x = 110,
y = 535,
borderStyle = 'inset',
width = 400,
forceBorder = True
)
my_canvas.drawString(10, 500, 'City:')
form.textfield(
name = 'city',
tooltip = 'City',
x = 110,
y = 485,
borderStyle = 'inset',
forceBorder = True
)
my_canvas.drawString(250, 500, 'State:')
form.textfield(
name = 'state',
tooltip = 'State',
x = 350,
y = 485,
borderStyle = 'inset',
forceBorder = True
)
my_canvas.drawString(10, 450, 'Zip Code:')
form.textfield(
name = 'zip_code',
tooltip = 'Zip Code',
x = 110,
y = 435,
borderStyle = 'inset',
forceBorder = True
)
my_canvas.save()
if __name__ == '__main__':
createSimpleForm()
输出:
说明:
在上面的代码片段中,我们从不同模块中导入了所需的函数,这些函数来自于 ReportLab 工具包。然后,我们定义了一个函数并创建了一个新的PDF文件。接着,我们创建了具有稍微不同样式的 textfield 小部件,并保存了文件。正如我们所观察到的那样,我们创建了一系列具有不同设置的文本字段。此外,我们还改变了某些字段的边框和背景颜色。然后,我们还包括了一些相当标准的字段。我们还使用了 width 参数来改变文本字段的宽度。