最近接到了一个需求-将项目下的样本信息汇总并以PDF的形式展示出来,第一次接到这种PDF的操作的功能,还是有点慌的,还好找到了reportlab这个包,可以定制化向PDF写内容!
reportlab是久经考验的,超强大的开源引擎,用于创建复杂的,数据驱动的 PDF 文档和自定义矢量图形。它是免费的,开源的,并且是用 Python 编写的。
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics, ttfonts
from reportlab.lib.colors import red, blue
# pagesize可以指定创建的画布尺寸
pdfObj = canvas.Canvas("test.pdf", pagesize=A4) # 也可以自定义尺寸,如pdfObj.setPageSize((1200,800))
#################################START字符串绘制#################################
# 绘制字符串左对齐,以给定坐标为起始点
pdfObj.drawString(300, 750, "Welcome! Ladies and gentlemen 0")
# 绘制字符串居中,以给定坐标系为字符串中心
pdfObj.drawCentredString(300, 700, "Welcome! Ladies and gentlemen 1")
# 绘制字符串右对齐,以给定坐标系为字符串结束点
pdfObj.drawRightString(300, 650, "Welcome! Ladies and gentlemen 2")
# 绘制<<中文>>字母,需要注册字体并配置字号,注simsun.ttc文件的存储位置可以是绝对或相对路径
pdfmetrics.registerFont(ttfonts.TTFont("宋体", "simsun.ttc"))
# 配置字号
pdfObj.setFont("宋体", 30)
pdfObj.drawString(300, 600, "大学生开学季")
#################################END字符串绘制#################################
#################################START图片的绘制#################################
# 绘制图片
pdfObj.drawImage(r"D:\test\baidu.png", 300, 400, 190, 72)
#################################END图片的绘制#################################
#################################START图形的绘制#################################
# 绘制中横线,参数为起点,终点坐标
pdfObj.line(50, 350, 300, 350)
pdfObj.setLineWidth(1) # 中横线厚度
# 绘制长方形
pdfObj.setFillColor(red) # 颜色对象
pdfObj.rect(300, 300, 190, 20, stroke=0, fill=1) # 长方形区域属性
# 附加属性
pdfObj.setFillColor(blue) # 颜色对象
# pdfObj.setFillGray(0.75) # 灰度配置,用的少,先关掉了
pdfObj.setFillAlpha(0.3) # 透明度配置
pdfObj.rect(300, 650, 200, 50, stroke=0, fill=1) # 长方形区域属性
#################################END图形的绘制#################################
#################################START继承的绘制#################################
# 将form内包含的绘制保存,以便再下一页继续应用。可用在页眉、页脚、背景色等处
pdfObj.beginForm("new") # 创建继承体
pdfObj.line(50, 200, 300, 200)
pdfObj.setLineWidth(1) # 中横线厚度
pdfObj.endForm() # 结束并保存继承体
for i in range(2):
pdfObj.doForm("new") # 应用继承体
pdfObj.showPage() # 结束本页翻转下一页
#################################END继承的绘制#################################
# 保存生效
pdfObj.save()
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics, ttfonts
from reportlab.platypus import Paragraph
# 文本数据
txt1 = "尊敬的家长,亲爱的同学们:"
txt2 = "在硕果累累的金秋时节,伴着纤云翩翩,伴着枫红菊香,你们怀揣着无限的憧憬,来到了xx学校。你们的到来,犹如徐徐清风,让我们的校园更为清新宜人,璀璨多姿。xx学院全体师生期盼着你们的到来,我们用比较诚挚的心意衷心的祝福你们,欢迎你们!"
txt3 = "当你跨进这所美丽的校园,你就成了我们大伙庭的一员,在这个大伙庭里,充满着真情,充满着友爱,充满着对一切美好事物的追求。在这个大伙庭里,你将在这优美的校园环境中陶冶你的情操,情发挥你的特长,丰富你的学识,攀登科学的高峰,实现你的梦想。"
txt4 = "新的.面孔、新的价值观念和标准,新的生活方式,需要你用理性的目光和胆识、用辛勤的劳动和汗水,去实现你走向人生成功与辉煌的又一起点。"
txt5 = "谢谢大家!"
# 创建样式对象
styleObj = getSampleStyleSheet()
# <<中文>>需要注册字体并配置字号,注simsun.ttc文件的存储位置可以是绝对或相对路径
pdfmetrics.registerFont(ttfonts.TTFont("宋体", "simsun.ttc"))
# 配置段落标题与正文属性,方式一
styleObj["Title"].fontName, styleObj["Title"].fontSize = "宋体", 15
styleObj["Title"].paragraphObjpaceAfter, styleObj["Normal"].paragraphObjpaceBefore = 30, 10
styleObj["Normal"].fontName, styleObj["Normal"].fontSize = "宋体", 10
styleObj["Normal"].leading = 30
styleObj["Normal"].firparagraphObjtLineIndent = 40
# # 也可以用下面的方式配置段落属性,方式二
# # 中文写入不识别,未查明怎么不生效
# from reportlab.lib.styles import ParagraphStyle
# paragraphStyle = ParagraphStyle(name="A1",fontName="宋体",fontSize=10, firstLineIndent=0)
# styleObj.add(paragraphStyle)
# 创建段落对象
paragraphObj1 = Paragraph(txt1, styleObj["Title"])
paragraphObj2 = Paragraph(txt2, styleObj["Normal"])
paragraphObj3 = Paragraph(txt3, styleObj["Normal"])
paragraphObj4 = Paragraph(txt4, styleObj["Normal"])
paragraphObj5 = Paragraph(txt5, styleObj["Normal"])
# 此处不再使用canvas创建pdf对象,改为文档模板doctemplate模块的SimpleDocTemplate类
doc = SimpleDocTemplate(r"test1.pdf", pagesize=A4)
story_text = [paragraphObj1, paragraphObj2, paragraphObj3, paragraphObj4, paragraphObj5]
doc.build(story_text)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Table
from reportlab.lib.units import inch, cm, pica
from reportlab.platypus import TableStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics, ttfonts
pdfmetrics.registerFont(ttfonts.TTFont("宋体", "simsun.ttc"))
# table数据,二维数组
data = [
["姓名", "语文", "数学", "英语", "体育"],
["张三", 91, 97, 79, "良好"],
["李四", 99, 87, 73, "优秀"],
["王五", 86, 89, 83, "良好"],
["赵六", 95, 88, 86, "良好"],
# 当需要将数据在一个单元格分两列的话,可以用下面的语法
["孙七", 79, 95, 98, "良"+"\n"+"好"],
]
# 配置行高(第一、第二、第三...行高)、列宽(第一、第二、第三...列宽),如有需要,也可以配置单位,如5 * [3 * cm]
col_widths, row_heights = [80, 100, 100, 100, 100], [60, 50, 50, 50, 50, 50]
# 表格行列的表达形式为,同excel,左上方第一个单元格为(0, 0), 右下角单元格为(-1, -1),围起来就是整个表格
table_style = TableStyle([
("FONT", (0, 0), (0, -1), "宋体", 30), # 配置字体
("FONT", (0, 0), (-1, 0), "宋体", 30),
("FONT", (1, 1), (-1, -1), "宋体", 15),
("ALIGN", (0, 0), (-1, -1), "CENTER"), # 水平居中
("VALIGN", (0, 0), (-1, -1), "MIDDLE"), # 垂直居中
("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black), # 单元格分割线
("BOX", (0, 0), (-1, -1), 0.25, colors.black), # 边框
("BACKGROUND", (0, 0), (-1, -1), colors.lightgrey), # 背景色
("TEXTCOLOR", (0, 0), (-1, 0), colors.red), # 区域字体颜色
("LINEABOVE", (0, 1), (-1, 1), 1, colors.orange), # 横线线段
('LINEBEFORE', (1, 0), (1, -1), 1, colors.blue) # 竖线线段
# ("GRID", (0, 0), (-1, -1), 0.5, colors.black), #
# ("SPAN", (0, 3), (-1, 3)), # 合并单元格
])
table = Table(data, colWidths=col_widths, rowHeights=row_heights, style=table_style)
# 编辑表格标题及样式
tabletitle = """表1: 学生成绩表 """
# 可以配置上下左右页边距,topMargin=1*cm,bottomMargin=1*cm,leftMargin=1*cm,rightMargin=1*cm
doc = SimpleDocTemplate(r"test2.pdf", pagesize=A4)
story_table = [Paragraph(tabletitle, getSampleStyleSheet()["Normal"]), table]
doc.build(story_table)