背景

因我们在工作中需要用到pdf文件, 而对于复杂的定制的pdf文件往往不好处理. 所以本文介绍如何使用Reportlab生成定制pdf文件。

Reportlab是Python的一个标准库, 可以根据图形命令直接创建PDF. 没有干预步骤。应用程序可以非常快速地生成PDF。

基本组件

pdfgen之canvas

pdfgen包是生成PDF文档的最低级别接口。一个pdfgen引擎本质上是一个将文档"绘制"到页面序列上的指令序列。提供绘画操作的接口对象是pdfgen canvas。canvas 也是我们在绘制PDF中最重要的组件。它将从文档页面的左下角为原点, 使用 X/Y 坐标将元素绝对放置在页面中。

模板

  1. PageTemplate类是一个语义相当简单的容器类。每个实例都包含一个Frames的列表,并且有一些 方法应该在每个页面的开始和结束时被调用, 可以使用此参数绘制我们的页眉和页脚. 绘制复杂Pdf文件时 我们可以为每页设置单独的页面模板。

  2. BaseDocTemplate 创建一个适合创建基本文档的文档模板。它带有相当多的内部机制,但没有默认的页面模板. 所以需要添加定制好的页面模板(PageTemplate)。

实现

from reportlab.graphics import shapes
from reportlab.graphics import widgetbase
from reportlab.graphics.charts.piecharts import Pie
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics.shapes import Drawing
from reportlab.lib import colors
from reportlab.lib.colors import HexColor
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
from reportlab.lib.pagesizes import A5
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import BaseDocTemplate, Paragraph, Table, Spacer, PageBreak, Image, PageTemplate, \Frame, NextPageTemplate, FrameBreakdoc = BaseDocTemplate('test.pdf', pagesize=(A5[0], A5[1]), topMargin=15 * mm, bottomMargin=30)pdfmetrics.registerFont(TTFont('song', r'./STSONG.TTF'))# 因为reportlab 碰到中文字体会乱码, 所以这里向reportlab注册宋体, 以正常显示中文字体
# 单栏页面对象
frameT = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')# 双栏页面对象
frame1 = Frame(doc.leftMargin, doc.bottomMargin, doc.width / 2 - 6, doc.height - doc.bottomMargin, id='col1')
frame2 = Frame(doc.leftMargin + doc.width / 2 + 6, doc.bottomMargin, doc.width / 2 - 6,doc.height - doc.bottomMargin, id='col2', showBoundary=1)
doc.addPageTemplates([PageTemplate(id='OneCol', frames=frameT, onPage=header, onPageEnd=footer),PageTemplate(id='TwoCol', frames=[frame1, frame2], onPage=header, onPageEnd=foot2),])
  1. 添加页眉页脚, 为了区分单双页面, 添加两个页脚
def footer(canvas, doc):canvas.saveState()page_num = canvas.getPageNumber()content = Paragraph(f"单栏第{page_num}页", styleC)w, h = content.wrap(doc.width, doc.bottomMargin)content.drawOn(canvas, doc.leftMargin, h)canvas.restoreState()def foot2(canvas, doc):canvas.saveState()page_num = canvas.getPageNumber()content = Paragraph(f"双栏第{page_num}页", styleC)w, h = content.wrap(doc.width, doc.bottomMargin)content.drawOn(canvas, doc.leftMargin, h)canvas.restoreState()def header(canvas, doc):canvas.saveState()header_content = Paragraph("这是页眉", styleC)w, h = header_content.wrap(doc.width, doc.topMargin)header_content.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)canvas.restoreState()
  1. 单栏页面填充文本信息, 饼图和reportlab的小组件
def draw_pie(data=[], labels=[], use_colors=[]):pie = Pie()pie.x = 30  # x,y饼图在框中的坐标pie.y = 10pie.slices.label_boxStrokeColor = colors.white  # 标签边框的颜色pie.data = data  # 饼图上的数据pie.labels = labels  # 数据的标签pie.simpleLabels = 0  # 0 标签在标注线的右侧;1 在线上边pie.sameRadii = 1  # 0 饼图是椭圆;1 饼图是圆形pie.slices.strokeColor = colors.red  # 圆饼的边界颜色pie.strokeWidth = 1  # 圆饼周围空白区域的宽度pie.strokeColor = colors.white  # 整体饼图边界的颜色pie.slices.label_pointer_piePad = 5  # 圆饼和标签的距离pie.slices.label_pointer_edgePad = 15  # 标签和外边框的距离pie.width = 220pie.direction = 'clockwise'pie.pointerLabelMode = 'LeftRight'for i, col in enumerate(use_colors):pie.slices[i].fillColor = colreturn piedata = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
labs = ['0000000', '1111111', '2222222', '3333333', '4444444','5555555', '6666666', '7777777', '8888888', '9999999']
color = [HexColor("#696969"), HexColor("#A9A9A9"), HexColor("#D8BFD8"),HexColor("#DCDCDC"), HexColor('#E6E6FA'), HexColor("#B0C4DE"),HexColor("#778899"), HexColor('#B0C4DE'), HexColor("#6495ED"),HexColor("#483D8B")]def auto_legender(chart, title='饼图'):width = 300height = 150d = Drawing(width, height)lab = Label()lab.x = 140  # x和y是文字的位置坐标lab.y = 130lab.setText(title)lab.fontName = 'song'  # 增加对中文字体的支持lab.fontSize = 10d.add(lab)d.add(chart)return ddef add_face():d = shapes.Drawing(200, 100)f = widgetbase.Face()f.skinColor = colors.yellowd.add(f)return dElements = []Elements.append(Paragraph("单栏第一页 " * 5, styleN))
pie = auto_legender(draw_pie(data, labs, color))
face = add_face()
Elements.append(pie)
Elements.append(face)
  1. 双栏填充文本信息, 图片和表格
 Elements.append(PageBreak())Elements.append(Paragraph("这是双栏第一个区域", styleC))Elements.append(Spacer(width=doc.width, height=30 * mm))  # 添加空行Elements.append(Image('default.png', width=40 * mm, height=40 * mm))  # 添加图片Elements.append(FrameBreak())  # 切换FrameElements.append(Paragraph("这是双栏第二个区域<br/>", styleC))Elements.append(Spacer(width=doc.width, height=10 * mm))# 添加一个表格data = [[1, 2, 3, 4, 5],['a', 'b', 'c', 'd', 'e'],[1, 2, 3, 4, 5],['a', 'b', 'c', 'd', 'e'],]Elements.append(Table(data, style=[('ALIGN', (0, 0), (-1, -1), 'CENTER'),('FONT', (0, 0), (-1, -1), 'song'),('GRID', (0, 0), (-1, -1), 1, colors.black),]))

总结

Reportlab 支持高度自定义生成Pdf文档, 支持HTML, XML文本, 绘制各种图形, 自定义表格等。

使用 ReportLab 绘制 PDF相关推荐

  1. Python绘制PDF文件~超简单的小程序

    Python绘制PDF文件 项目简介 这次项目很简单,本次项目课,代码不超过40行,主要是使用 urllib和reportlab模块,来生成一个pdf文件. reportlab官方文档 http:// ...

  2. 【Python办公自动化】使用reportlab制作pdf报告

    原文作者:我辈李想 版权声明:文章原创,转载时请务必加上原文超链接.作者信息和本声明. Python使用folium制作地图并生成png图片 第一章 folium的方法和类的介绍(思维导图) 第二章 ...

  3. 基于matlab的能级_波函数及几率密度图形的绘制,基于MATLAB的能级波函数及几率密度图形的绘制.pdf...

    基于MATLAB的能级波函数及几率密度图形的绘制.pdf 第 卷 第 期 大 学 物 理 实 验 年 月 出版 壬 刃协 卫 印 文 章编 号 一 ' 一 一 基 于 的能级 . 波 函数 及 几 率 ...

  4. C# 绘制PDF图形——基本图形、自定义图形、色彩透明度

    引言 在PDF中我们可以通过C#程序代码来添加非常丰富的元素来呈现我们想要表达的内容,如绘制表格.文字,添加图形.图像等等.在本篇文章中,我将介绍如何在PDF中绘制图形,并设置图形属性的操作. 文章中 ...

  5. python 生成pdf页面大小_使用具有自定义大小页面和最佳图像分辨率的Reportlab生成PDF...

    诀窍是先缩放reportlab的画布,然后再将图像绘制到画布上.它似乎无法正确地从文件中获取DPI信息.在 下面的示例代码对于我的激光打印机非常适用:from PIL import Image, Im ...

  6. Python使用Reportlab处理PDF数据 - 图形和图表

    简述 reportlab.graphics子程序包是作为一组独立程序开始的. 今天,它已完全集成到ReportLab工具包的其余部分中. 图形子软件包为开发人员提供了一组强大的功能,可用于创建图表和图 ...

  7. ReportLab for PDF

    Install ReportLab 方法一: python pip install reporlab 方法二: https://pypi.python.org/pypi/reportlab 去下载py ...

  8. 绘制pdf表格 (二) 通过itext实现在pdf中绘制excel表格样式设置中文字体、水印、logo、页眉、页码

    前言 在<通过itext实现在pdf中绘制excel表格样式并且实现下载>实现了表格的基本渲染,本文将继续进行水印.logo.页眉.页码的设置,本文的部分代码包含<通过itext实现 ...

  9. 使用pdfjs-dist绘制pdf文件

    版本声明: vue@3.2.1pdfjs-dist@2.5.207 ps:如果使用 vue 3.x 的版本,切记不要使用太高的 pdfjs-dist 版本,会有语法报错 函数引入: import * ...

  10. Python使用Reportlab处理PDF数据 - 其他可流动(flowable)

    简述 ReportLab还可以使用其他几个Flowable. 在本本中,我们将研究以下Flowable: Preformatted XPreformatted Image Spacer PageBre ...

最新文章

  1. R 语言中的高级图像处理包
  2. [转]海量查询的数据优化
  3. elasticsearch版本不同,批量查询也不相同
  4. 2016计算机有哪些专业知识点,2016计算机专业知识:精选知识点练习(99)
  5. HarmonyOS之常用组件ToastDialog的功能和使用
  6. java input回车,用java怎样编写加减乘除,从键盘输入,例如:1+2按回车得到
  7. golang错误:The process cannot access the file because it is being used by another process
  8. 怎么判断噎到没噎到_嚼半天吐出来,稍硬的食物都不吃,1岁的孩子咀嚼能力差怎么办?...
  9. elasticsearch-5.6.12 单点安装包括 HEAD插件安装
  10. Linux下MySQL数据库的备份与还原
  11. 模式识别(五)聚类的几种算法
  12. java程序员面试宝典第四版pdf下载
  13. 高频量化交之李:在华尔街狼舞岁
  14. 如何更改html的默认应用,win10如何修改默认应用
  15. PHP手册-use关键字
  16. IP问问区县级别IP地址库---使用帮助(上篇)
  17. 2 c++编程-核心
  18. 组合最优化——线性规划基本定理
  19. MySQL如何查询表中重复的数据
  20. 尽信书不如无书之获取枚举值代码优化

热门文章

  1. 《操作系统实验》C++实现时间片轮转调度算法
  2. SVN客户端详细说明
  3. 开放有限元分析计算平台介绍
  4. Mac系统最强虚拟机(支持Big Sur)
  5. 最强内存稳定性测试软件,内存稳定性测试软件Memtest正式版——HyperX FURY DDR4成绩喜人...
  6. 在多个浏览器中添加IDM插件
  7. html js获取本地ip,在js获取本地IP地址
  8. c# 实现圆形的进度条(ProgressBar)
  9. 简述 矩阵-DirectX 原理,并详解世界坐标转屏幕坐标,附C++实现。
  10. 计算机网络毕业论文格式模板范文,计算机网络论文范文 计算机网络方面有关毕业论文的格式范文2万字...