这个 ***可移植文档格式(PDF)***并不是一种 ***所见即所得(WYSIWYG)***格式。它被开发为与平台无关,独立于底层操作系统和渲染引擎。
为了实现这一点,PDF的构造是通过更像编程语言的东西进行交互,并依靠一系列的指令和操作来实现一个结果。事实上,PDF是基于一种脚本语言--PostScript,它是第一个独立于设备的页面描述语言。
在本指南中,我们将使用 borb- 一个专门用于阅读、操作和生成 PDF 文档的 Python 库。它提供了一个低级别的模型(如果你选择使用精确的坐标和布局,允许你访问这些)和一个高级别的模型(你可以将边距、位置等的精确计算委托给一个布局管理器)。
在本指南中,我们将看看如何生成一张包含自定义图形(由PDF操作符表示)的传单。
安装borb
borb可以从GitHub上的源代码下载,或通过pip 。
$ pip install borb
我们要做的东西
通常情况下,画一个草图,并朝着它的方向努力,比盲目建造更容易,所以请随意在你身边的一张纸上画出传单的草图,并让创意流向画布。
我们将制作一张这样的传单,来宣传属于一个所谓的公司的产品。
用borb创建一个PDF文档
在borb ,建立一个PDF文档通常遵循同样的几个步骤。
- 创建一个空的
Document - 创建一个空的
Page,并将其附加到Document - 设置一个
PageLayout上的内容。Page - 将内容添加到
PageLayout - 坚持下去
Document
让我们看看这在代码中是什么样子的。
from borb.pdf.document import Document
from borb.pdf.page.page import Page
from borb.pdf.canvas.layout.page_layout.multi_column_layout import SingleColumnLayout
from borb.pdf.canvas.layout.page_layout.page_layout import PageLayout
from borb.pdf.pdf import PDF
def main():
# Create empty Document
pdf = Document()
# Create empty Page
page = Page()
# Add Page to Document
pdf.append_page(page)
# Create PageLayout
layout: PageLayout = SingleColumnLayout(page)
# Future content-rendering-code to be inserted here
# Attempt to store PDF
with open("output.pdf", "wb") as pdf_file_handle:
PDF.dumps(pdf_file_handle, pdf)
if __name__ == '__main__':
main()
用borb创建一个PDF传单
现在我们有一个空的画布可以使用,让我们来添加基本的内容。我们将从添加标题开始,例如*"你的公司"*。
# New imports
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.color.color import HexColor
from decimal import Decimal
# Contact information
layout.add(
Paragraph("Your Company",
font_color=HexColor("#6d64e8"),
font_size=Decimal(20)
)
)
下一步是添加QR码和联系信息。为了方便地并排展示这些内容,我们将使用Table 。
我们还需要二维码的坐标(我们将在后面为它添加一些特殊的东西)。因此,让我们先从声明这个开始。
# New imports
from borb.pdf.canvas.layout.image.barcode import Barcode, BarcodeType
from borb.pdf.canvas.layout.layout_element import LayoutElement
# Code to generate a QR code LayoutElement
qr_code: LayoutElement = Barcode(
data="https://www.borbpdf.com",
width=Decimal(64),
height=Decimal(64),
type=BarcodeType.QR,
)
现在我们可以建立并添加我们的Table 。
# New imports
from borb.pdf.canvas.layout.table.flexible_column_width_table import FlexibleColumnWidthTable
layout.add(
FlexibleColumnWidthTable(number_of_columns=2, number_of_rows=1)
.add(qr_code)
.add(
Paragraph(
"""
500 South Buena Vista Street
Burbank CA
91521-0991 USA
""",
padding_top=Decimal(12),
respect_newlines_in_text=True,
font_color=HexColor("#666666"),
font_size=Decimal(10),
)
)
.no_borders()
)
让我们运行该代码,看看生成的PDF是什么样子的。我发现这是调整UI/UX小细节的最好方法。
看起来不错!二维码位于公司名称的正下方,包含正确的联系信息,并实际编码了我们提供的联系数据。
接下来,我们将添加一个远程去向注释。这只是PDF的说法,即*"一个可点击的链接,将你带到PDF之外"*。
我们要确保整个QR码实际上是一个链接,将读者带到我们的网站。这样,如果他们有这个PDF的印刷版本,他们可以简单地扫描QR码。如果他们有数字版本,他们可以点击QR码。
这是一个简单的补充,但使用户端的导航成为一个更愉快的体验。
page.append_remote_go_to_annotation(
qr_code.get_bounding_box(), uri="https://www.borbpdf.com"
)
添加产品信息
我们现在可以添加下一个标题和副标题,与我们正在创建一个传单的产品有关。
# Title
layout.add(
Paragraph(
"Productbrochure", font_color=HexColor("#283592"), font_size=Decimal(34)
)
)
# Subtitle
layout.add(
Paragraph(
"September 4th, 2021",
font_color=HexColor("#e01b84"),
font_size=Decimal(11),
)
)
同样地,我们将添加产品概述的标题,以及一些假的文本。
# product overview
layout.add(
Paragraph(
"Product Overview", font_color=HexColor("000000"), font_size=Decimal(21)
)
)
layout.add(
Paragraph(
"""
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.
Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.
A small river named Duden flows by their place and supplies it with the necessary regelialia.
"""
)
)
layout.add(
Paragraph(
"""
It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life.
One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
""",
margin_bottom=Decimal(12)
)
)
**注意:**请注意最后一个Paragraph ,在那里我们明确地添加了一个底边。这只是一个小小的视觉调整,以确保在Paragraph 和下一块内容之间有更多的空间,这将是一个图片。
当我们运行这段代码时,我们应该得到像这样的东西。
最后,我们可以添加产品信息。我们可以在产品的一些特点的列表旁边有一个Image 。因此,我们可以再次使用Table 来实现并排的外观。
通常情况下,功能列表上方有一个标题,所以我们要有一个Table ,有两列(图片和功能)和两行(一个是标题,一个是功能)。
由于这个表格不是作为一个表格使用,而只是为了实现并排的外观,所以我们不会给这个表格添加边框。
# New imports
from borb.pdf.canvas.layout.image.image import Image
from borb.pdf.canvas.layout.table.table import TableCell
from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable
from borb.pdf.canvas.layout.list.unordered_list import UnorderedList
# Table with image and key features
layout.add(
FixedColumnWidthTable(
number_of_rows=2,
number_of_columns=2,
column_widths=[Decimal(0.3), Decimal(0.7)],
)
.add(
TableCell(
Image(
"https://www.att.com/catalog/en/skus/images/apple-iphone%2012-purple-450x350.png",
width=Decimal(128),
height=Decimal(128),
),
row_span=2,
)
)
.add(
Paragraph(
"Key Features",
font_color=HexColor("e01b84"),
font="Helvetica-Bold",
padding_bottom=Decimal(10),
)
)
.add(
UnorderedList()
.add(Paragraph("Nam aliquet ex eget felis lobortis aliquet sit amet ut risus."))
.add(Paragraph("Maecenas sit amet odio ut erat tincidunt consectetur accumsan ut nunc."))
.add(Paragraph("Phasellus eget magna et justo malesuada fringilla."))
.add(Paragraph("Maecenas vitae dui ac nisi aliquam malesuada in consequat sapien."))
)
.no_borders()
)
同样,我们在Table 的一些单元格中添加了一个padding_bottom ,只是为了提供一些额外的空间。最终的PDF几乎已经完成。
剩下的最后步骤是在右上角和页脚添加艺术品。
使用borb中的 "形状 "对象
borb 可以将任何 到 。 代表一个任意的点序列(表示为 ),所有这些点都形成一条连续的线。这意味着你可以很有创意地创建你想要的形状。Shape Page Shape typing.Tuple[Decimal, Decimal]
我们将首先定义一个方法来渲染Page 右上角的三角形和正方形。
# New imports
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.canvas.layout.image.shape import Shape
from borb.pdf.page.page_size import PageSize
import typing
import random
def add_gray_artwork_upper_right_corner(page: Page) -> None:
"""
This method will add a gray artwork of squares and triangles in the upper right corner
of the given Page
"""
grays: typing.List[HexColor] = [
HexColor("A9A9A9"),
HexColor("D3D3D3"),
HexColor("DCDCDC"),
HexColor("E0E0E0"),
HexColor("E8E8E8"),
HexColor("F0F0F0"),
]
ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
N: int = 4
M: Decimal = Decimal(32)
# Draw triangles
for i in range(0, N):
x: Decimal = ps[0] - N * M + i * M
y: Decimal = ps[1] - (i + 1) * M
rg: HexColor = random.choice(grays)
Shape(
points=[(x + M, y), (x + M, y + M), (x, y + M)],
stroke_color=rg,
fill_color=rg,
).layout(page, Rectangle(x, y, M, M))
# Draw squares
for i in range(0, N - 1):
for j in range(0, N - 1):
if j > i:
continue
x: Decimal = ps[0] - (N - 1) * M + i * M
y: Decimal = ps[1] - (j + 1) * M
rg: HexColor = random.choice(grays)
Shape(
points=[(x, y), (x + M, y), (x + M, y + M), (x, y + M)],
stroke_color=rg,
fill_color=rg,
).layout(page, Rectangle(x, y, M, M))
现在我们可以在主方法中调用这个方法,给我们的PDF带来一些额外的炫耀。
同样地,我们可以在页面底部添加一些图形。
- 一条线,将页脚与页面的主要内容分开
- 一个小的几何元素来平衡页面上方的几何图形
让我们再写一个方法来完成这一切。
from borb.pdf.canvas.line_art.line_art_factory import LineArtFactory
def add_colored_artwork_bottom_right_corner(page: Page) -> None:
"""
This method will add a blue/purple artwork of lines
and squares to the bottom right corner
of the given Page
"""
ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
# Square
Shape(
points=[
(ps[0] - 32, 40),
(ps[0], 40),
(ps[0], 40 + 32),
(ps[0] - 32, 40 + 32),
],
stroke_color=HexColor("d53067"),
fill_color=HexColor("d53067"),
).layout(page, Rectangle(ps[0] - 32, 40, 32, 32))
# Square
Shape(
points=[
(ps[0] - 64, 40),
(ps[0] - 32, 40),
(ps[0] - 32, 40 + 32),
(ps[0] - 64, 40 + 32),
],
stroke_color=HexColor("eb3f79"),
fill_color=HexColor("eb3f79"),
).layout(page, Rectangle(ps[0] - 64, 40, 32, 32))
# Triangle
Shape(
points=[
(ps[0] - 96, 40),
(ps[0] - 64, 40),
(ps[0] - 64, 40 + 32),
],
stroke_color=HexColor("e01b84"),
fill_color=HexColor("e01b84"),
).layout(page, Rectangle(ps[0] - 96, 40, 32, 32))
# Line
r: Rectangle = Rectangle(Decimal(0), Decimal(32), ps[0], Decimal(8))
Shape(
points=LineArtFactory.rectangle(r),
stroke_color=HexColor("283592"),
fill_color=HexColor("283592"),
).layout(page, r)
同样,我们可以从主方法中调用这个方法。最终的页面应该是这样的。
结论
在本指南中,我们已经使用borb ,看了一些PDF文档的基本构建模块。我们已经配置了padding和margin,以及字体大小和字体颜色。我们还使用Shape 对象生成了图形,以及一个可点击的QR码。
通过这些构件,我们为一个假想的公司的所谓产品创建了一份传单,使创建交互式PDF文档的过程自动化。