python生成PDF报告
前言
最近接到了一个需求-将项目下的样本信息汇总并以PDF的形式展示出来,第一次接到这种PDF的操作的功能,还是有点慌的,还好找到了reportlab这个包,可以定制化向PDF写内容!
让我们由简入深进行讲解
一、reportlab是什么?
reportlab是久经考验的,超强大的开源引擎,用于创建复杂的,数据驱动的 PDF 文档和自定义矢量图形。它是免费的,开源的,并且是用 Python 编写的。
二、canvas绘制图形文字元素
- 页面绘制是以坐标系为基准,左下角坐标为(0, 0)
2.1 样式预览

2.2、代码
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()
三、页面布局platypus应用
在第一章中,所有的元素都基于坐标进行绘制,每次的排版都需要计算,应用起来有点复杂及繁琐,所以为了减少这种重复劳动,引入模板和样式platypus(Page Layout and Typography Using Scripts),它致力于把文档的样式和内容分开,段落、表格都直接套用相应的格式,页面也可以套用页面模版。
- 明晰platypus几大层面划分,包含关系由小到大。页面元素(flowables)、页面框架(Frame)、页面模板(PageTemplate)、文档模板(DocTemplate)
- 页面元素(flowables),如段落、表格、空白、分页符、图片等
3.1、段落Paragraph
3.1.1、样式预览

3.1.2、代码
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)
3.2、表格Table
3.2.1、样式预览

3.2.2、代码
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, ttfontspdfmetrics.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 = """<para alignment=center fontName="宋体" fontSize=20 spaceAfter=30>表1: 学生成绩表</para>"""
# 可以配置上下左右页边距,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)
3.2、图表
项目没用到,搁置先不写了
3.4、空白
3.5、图片
3.6、升华Frame
四、结束!
相关文章:
python生成PDF报告
前言 最近接到了一个需求-将项目下的样本信息汇总并以PDF的形式展示出来,第一次接到这种PDF的操作的功能,还是有点慌的,还好找到了reportlab这个包,可以定制化向PDF写内容! 让我们由简入深进行讲解 一、reportlab是…...
在visual studio里安装Python并创建python工程
在2009年,云计算开始发力,Python、R、Go这些天然处理批量计算的语言也迅猛发展。微软在2010年,把Python当成一个语言包插件,集成到了visual studio 2010里。在"云优先,移动优先"的战略下,于2015年…...
AIGC(生成式AI)试用 6 -- 从简单到复杂
从简单到复杂,这样的一个用例该如何设计? 之前浅尝试用,每次尝试也都是由浅至深、由简单到复杂。 一点点的“喂”给生成式AI主题,以测试和验证生成式AI的反馈。 AIGC(生成式AI)试用 1 -- 基本文本_Role…...
竞赛 基于深度学习的人脸识别系统
前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的人脸识别系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/…...
uniapp:APP开发,后台保活
前言: 在ios中,软件切换至后台、手机息屏,过了十来秒软件就会被系统挂起,APP内的任务就不能继续执行;在android中,默认情况下,软件在后台运行的时候,触发某些特定条件的情况下&…...
vue2 项目中嵌入视频
案例: 代码: <template><div class"schematicDiagramIndex"><el-container><el-aside width"20rem"> <!-- <h4 style"font-size: 18px">视频演示</h4>--><div styl…...
第二章 进程与线程 十二、进程同步与进程互斥
目录 一、进程同步 1、定义 二、进程互斥 1、定义 2、四个部分 3、原则 一、进程同步 1、定义 进程同步是指在多个进程之间协调执行顺序的一种机制,使得进程按照一定的顺序执行,以避免出现不一致的情况。常见的实现方式有信号量、管程、屏障等。…...
Linux内核链表(list)移植到任意平台
一、前言 linux内核链表在include/linux/list.h文件中,内核中实现的链表比较简洁,实用性很强,因此想把它单独移植出来使用。 内核中的代码只能使用gnuc编译器编译,stdc编译器编译是会报错的,主要是因为typeof这个宏是…...
【操作系统】聊聊什么是CPU上下文切换
对于linux来说,本身就是一个多任务运行的操作系统,运行远大于CPU核心数的程序,从用户视角来看是并发执行,而在CPU视角看其实是将不同的CPU时间片进行分割,每个程序执行一下,就切换到别的程序执行。那么这个…...
CMake教程-第 2 步 添加一个库
CMake教程-第 2 步 添加一个库 1 CMake教程介绍2 学习步骤Step 1: A Basic Starting PointStep 2: Adding a LibraryStep 3: Adding Usage Requirements for a LibraryStep 4: Adding Generator ExpressionsStep 5: Installing and TestingStep 6: Adding Support for a Testin…...
DS 顺序表--类实现(C++数据结构题)
实现顺序表的用 C 语言和类实现顺序表 属性包括:数组、实际长度、最大长度(设定为 1000 ) 操作包括:创建、插入、删除、查找 类定义参考 #include<iostream> using namespace std; #define ok 0 #define error -1 // 顺…...
0.UML
1.图 1.1类图含义 第一层显示类的名称,如果是抽象类,则就用斜体显示。第二层是类的特性,通常就是字段和属性。第三层是类的操作,通常是方法或行为。注意前面的符号, ,表示public,-,表示private,#,表示protected。 1.2接口图 与类图的区别主要是顶端有<< interface >…...
PostgreSQL设置主键为自增
1、创建自增序列 CREATE SEQUENCE table_name_id_seq START 1; 2、设置字段默认值 字段默认值中设置 nextval(table_name_id_seq) 3、常用查询 -- 查询所有序列 select * from information_schema.sequences where sequence_schema public; -- 查询自增序列的当前值 select cu…...
input修改checkbox复选框默认选中样式
问题描述: <input type"checkbox" /> input修改checkbox默认选中样式,直接设置选中后的样式不生效,需要先给复选框设置-webkit-appearance: none(取消默认样式), 再设置样式才会生效。 …...
高云FPGA系列教程(10):letter-shell移植
文章目录 letter-shell简介letter-shell源码获取letter-shell移植函数和变量应用示例 本文是高云FPGA系列教程的第10篇文章。 shell,中文是外壳的意思,就是操作系统的外壳。通过shell命令可以操作和控制操作系统,比如Linux中的Shell命令就包括…...
【C语言学习笔记---指针进阶02】
C语言程序设计笔记---017 C语言进阶之回调函数1、函数指针数组2、回调函数3、 回调函数的应用 --- qsort库函数4、模拟qsort函数5、结语 C语言进阶之回调函数 前言: 通过C语言进阶前篇的指针进阶01的知识,继续学习。这篇引用一个简易计算器的程序进行深…...
低功耗蓝牙物联网:未来连接的无限可能
物联网是连接各种设备和传感器的网络,其目的是实现信息的交换和共享,提高效率并优化生活。在这个领域,低功耗蓝牙(BLE)正在发挥着越来越重要的作用。 低功耗蓝牙是一种无线通信技术,它的主要特点是低功耗和…...
安装社区版本OB
获取一键安装包 https://www.oceanbase.com/softwarecenter 离线安装 [admintest001 ~]$ tar -xzf oceanbase-all-in-one-*.tar.gz [admintest001 ~]$ cd oceanbase-all-in-one/bin/ [admintest001 bin]$ ./install.sh [admintest001 bin]$ source ~/.oceanbase-all-in-one/…...
JSON 串和 Java 对象的相互转换
JSON 串和 Java 对象的相互转换 以 json 格式的数据进行前后端交互 前端发送请求时,如果是复杂的数据就会以 json 提交给后端; 而后端如果需要响应一些复杂的数据时,也需要以 json 格式将数据响应回给浏览器 为达到以上目的就需要重点学习…...
爬虫 — App 爬虫(一)
目录 一、介绍二、APP 爬虫常见反爬三、APP 抓包常用工具四、模拟器五、安装 APP1、下载 APP2、安装 APP 六、fiddler1、工作原理2、安装3、基本介绍 七、环境配置1、fiddler 的配置2、夜神模拟器的配置 八、案例 一、介绍 爬虫分类——数据来源 1、PC 端爬虫(网页…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
