reportlab 制作pdf
最近需要使用python制作一个pdf,这是苦于没有好的库,就在github上面找,找来找去,觉得没有很合适的,就想着死马当活马医随便用一个吧,就找到了一个可以使用markdown语法来生成pdf的工程,但是clone下来之后,看手册,发现需要reportlab的版本>3.0以上,瞬间感觉是不是reportlab是我的救星,然后就去了reportlab的官网,发现真的是救星级别的库了,于是就看reportlab的文档,用一天时间看文档,但是reportlab的文档我觉得做得太简单了,功能这么强大的库,给的例子太简单。当然在本文的最后我会放上从官网上down下来的例子的文档,大家可以看一看,我觉得看一遍手册,然后再看一遍例子,还有官网的Code Snippets可以更好地了解这个库的使用。
-------------------------------上面都是废话------------------
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light'))
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph, Spacer, Table, LongTable, TableStyle, tableofcontents, PageBreak
当时我引入了这么些库,其中有很多都是我下面要使用,简单介绍一下:
canvas:reportlab将一个pdf看成是一个画布,这个就是那个画布类型,就相当于在画上画画的感觉,如果你们有什么图要画,可以使用reportlab的画画工具,挺强大的,画布是一个坐标轴,页面的左下角为原点。
cm:引入cm,方便以后的坐标标记,不懂英尺,就low一点用厘米吧,页面大小默认是A4大小,也就是宽21cm, 高29.7cm
pdfmetrics:为了后面的中文字体使用而饮用的,当我们使用其他的非标准字体时,可以使用这个库
UnicodeCIDFont:这个库中包含STSong-Light这个Font,所以我们引入
下一句就是registerFont,一遍之后我们使用这个字体,构建pdf时认识这种字体
getSampleStyleSheet:一个样例风格卡片,翻译水平有限,里面放了很多的风格样例供我们使用,使用方式
from reportlab.lib.styles import getSampleStyleSheet
stylesheet=getSampleStyleSheet()
normalStyle = stylesheet['Normal']
而且不光有Normal,还有Title,Heading1, 等等的风格样例。
ParagraphStyle:这是一个包含了许多通用格式化的需求的类,
alignment = 0
allowOrphans = 0
allowWidows = 1
backColor = None
borderColor = None
borderPadding = 0
borderRadius = None
borderWidth = 0
bulletAnchor = start
bulletFontName = Helvetica
bulletFontSize = 10
bulletIndent = 0
embeddedHyphenation = 1
endDots = None
firstLineIndent = 0
fontName = Helvetica
fontSize = 10
hyphenationLang = en_GB
justifyBreaks = 0
justifyLastLine = 0
leading = 16
leftIndent = 0
linkUnderline = 0
rightIndent = 0
spaceAfter = 6
spaceBefore = 6
spaceShrinkage = 0.05
splitLongWords = 1
strikeGap = 1
strikeOffset = 0.25*F
strikeWidth =
textColor = Color(0,0,0,1)
textTransform = None
underlineGap = 1
underlineOffset = -0.125*F
underlineWidth =
uriWasteReduce = 0.3
wordWrap = None
里面包含了这么多的属性,我们可以在定义ParagraphStyle时,指定这些属性,从而生成不同的Paragraph样例。
最后一行就不一一讲解了,platypus简单介绍一下,说白了就是一个个的container,将文本信息放入其中,可以按照reportlab提供的模板来生成各种各种的样例,例如Paragraph:段落,Spacer:空白区间,Table:表格等。
2.主要代码:
doc = BaseDocTemplate(filename, topMargin = 3.5*cm) #声明一个文档模版类,filename就是存放pdf的地址,
frame_footer = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal') #声明一块Frame,存放页码
template = PageTemplate(id='test', frames=frame_footer, onPage=header, onPageEnd=footer) #设置页面模板,在加载页面时先运行herder函数,在加载完页面后运行footer函数
doc.addPageTemplates([template])
现在我们已经声明了页面的类型,默认A4大小的纸,更改了topMargin等属性。
之后再声明一块Frame,之后再设置页面模版,放入文档模版中。
def footer(canvas, doc):
"""
设置页脚
:param canvas:Canvas类型 pdf画布
:param doc:doc类型 整个pdf文件
"""
canvas.saveState() #先保存当前的画布状态
pageNumber = ("%s" %canvas.getPageNumber()) #获取当前的页码
p = Paragraph(pageNumber, styleN)
w, h = p.wrap(1*cm, 1*cm) #申请一块1cm大小的空间,返回值是实际使用的空间
p.drawOn(canvas, foot_coordinate_x, foot_coordinate_y) #将页码放在指示坐标处
canvas.restoreState()
def header(canvas, doc):
"""
设置页眉
:param canvas:Canvas类型 pdf画布
:param doc:doc类型 整个pdf文件
"""
canvas.saveState()
p = Paragraph("<img src='%s' width='%d' height='%d'/>" %(img_address, header_img_width, header_img_height), styleN) #使用一个Paragraph Flowable存放图片
w, h = p.wrap(doc.width, doc.bottomMargin)
p.drawOn(canvas, doc.leftMargin, doc.topMargin + doc.height - 0.5*cm) #放置图片
p = Paragraph("<font size=10 face='STSong-Light'>报告</font>", styleN)
w,h = p.wrap(doc.width, doc.bottomMargin)
p.drawOn(canvas, doc.leftMargin+doc.width-2.2*cm, doc.topMargin+ doc.height-0.3*cm) #放置报告这句话
canvas.line(doc.leftMargin, doc.bottomMargin+doc.height + 0.5*cm, doc.leftMargin+doc.width, doc.bottomMargin+doc.height + 0.5*cm) #画一条横线
canvas.restoreState()
这个是我们在页面加载是,首先加载header函数中,之后描绘完整个页面会加载footer函数,这时我们的页眉和页脚已经设置完毕了。
最后加一句
text = []
doc.build(text)
我们在text中加载你想放置的其他信息。这样就成功了。