当前位置: 首页 > news >正文

Python中的PDF处理工具:PyPDF2和ReportLab使用指南

Python中的PDF处理工具:PyPDF2和ReportLab使用指南

在日常工作和项目中,PDF 文件处理是个常见需求,不论是合并报告、加密文档、填充表单,还是生成发票。Python 中有许多用于操作 PDF 文件的库,其中 PyPDF2ReportLab 是两个广泛使用的工具:前者用于 PDF 文档的读取和修改,后者用于从头生成 PDF 文件。在这篇博客中,我们将介绍如何使用 PyPDF2 和 ReportLab 完成一些常见的 PDF 处理任务。

一、安装 PyPDF2 和 ReportLab

要开始使用 PyPDF2 和 ReportLab,首先需要安装它们。可以在终端或命令提示符中执行以下命令:

pip install PyPDF2 reportlab

安装完成后,即可使用它们进行 PDF 的读写和生成操作。


二、使用 PyPDF2 操作 PDF 文件

PyPDF2 是一个强大的 PDF 处理库,它提供了多种功能,可以让我们读取、合并、拆分、加密和解密 PDF 文件。以下是 PyPDF2 的一些常见操作。

1. 读取 PDF 文件

首先,让我们看看如何用 PyPDF2 打开并读取 PDF 文件的内容。

from PyPDF2 import PdfReader# 打开 PDF 文件
reader = PdfReader("example.pdf")# 获取页面数
num_pages = len(reader.pages)
print(f"Total pages: {num_pages}")# 读取每一页的内容
for page_num in range(num_pages):page = reader.pages[page_num]text = page.extract_text()print(f"Page {page_num + 1}:\n{text}")

在这个例子中,我们使用 PdfReader 类打开 PDF 文件,并通过 extract_text() 方法提取每一页的文本内容。这种方式适合从 PDF 中读取纯文本内容,比如报告和文档。

2. 合并 PDF 文件

合并多个 PDF 文件是 PyPDF2 的强项之一。以下是将两个 PDF 文件合并成一个 PDF 文件的示例:

from PyPDF2 import PdfWriter, PdfReader# 创建 PDF 写入器
writer = PdfWriter()# 读取两个 PDF 文件并将它们的页面添加到写入器中
pdf_files = ["file1.pdf", "file2.pdf"]
for pdf_file in pdf_files:reader = PdfReader(pdf_file)for page in reader.pages:writer.add_page(page)# 保存合并后的 PDF 文件
with open("merged_output.pdf", "wb") as output_pdf:writer.write(output_pdf)

在这个示例中,我们创建了一个 PdfWriter 实例,依次读取每个 PDF 文件,并将其页面添加到写入器中。最终,合并后的 PDF 文件会保存为 merged_output.pdf

3. 拆分 PDF 文件

如果需要将 PDF 文件中的某些页面提取出来,也可以通过 PyPDF2 实现。例如,提取 PDF 文件中的第 1 页到第 3 页:

from PyPDF2 import PdfWriter, PdfReaderreader = PdfReader("example.pdf")
writer = PdfWriter()# 提取特定页
for i in range(3):  # 这里表示提取第1页到第3页writer.add_page(reader.pages[i])# 保存拆分后的文件
with open("split_output.pdf", "wb") as output_pdf:writer.write(output_pdf)

此代码将 example.pdf 的前 3 页提取并保存为 split_output.pdf

4. 加密和解密 PDF 文件

对于机密文件,PyPDF2 提供了加密和解密功能。我们可以使用 encrypt 方法设置密码保护 PDF 文件:

writer = PdfWriter()
reader = PdfReader("example.pdf")# 添加所有页面
for page in reader.pages:writer.add_page(page)# 加密并设置密码
writer.encrypt("password123")# 保存加密的文件
with open("encrypted_output.pdf", "wb") as output_pdf:writer.write(output_pdf)

在这个例子中,encrypted_output.pdf 文件只能通过密码“password123”打开,确保了文件的安全性。


三、使用 ReportLab 生成 PDF 文件

ReportLab 是另一个强大的 PDF 库,适合从头生成 PDF 文件,并支持复杂的布局和样式。ReportLab 使用 画布(Canvas)进行 PDF 内容的绘制,可以生成包含文本、图形和表格的 PDF 文件。

1. 创建 PDF 文件并添加文本

首先,让我们看如何使用 ReportLab 创建一个简单的 PDF 文件并添加文本:

from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas# 创建 PDF 文件
pdf_path = "generated_example.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)# 添加文本
pdf_canvas.drawString(100, 750, "Hello, ReportLab!")
pdf_canvas.drawString(100, 730, "This is a simple PDF file created using Python.")# 保存并关闭 PDF
pdf_canvas.save()
print(f"PDF saved as {pdf_path}")

在此代码中,drawString 方法可以指定文本位置,单位为点(pt),A4 页面的尺寸是 595x842 pt。在 100, 750 位置写入文本 “Hello, ReportLab!”。

2. 添加图片和图形

ReportLab 允许将图片插入到 PDF 中,并能绘制各种形状,这对于生成图表或带有图像的报告非常有用。

from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas# 创建 PDF 文件
pdf_path = "pdf_with_image.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)# 添加图片
pdf_canvas.drawImage("example_image.jpg", 100, 500, width=200, height=150)# 绘制矩形
pdf_canvas.setStrokeColorRGB(0, 0, 1)  # 蓝色边框
pdf_canvas.setFillColorRGB(0.8, 0.8, 1)  # 浅蓝填充
pdf_canvas.rect(100, 450, 200, 100, fill=True)# 保存 PDF
pdf_canvas.save()
print(f"PDF with image and shapes saved as {pdf_path}")

在这里,我们插入了一张图片,并绘制了一个蓝色矩形,位置在 (100, 450),尺寸为 200x100drawImage 方法可以用来插入图像文件,支持 JPG 和 PNG 格式。

3. 添加表格

ReportLab 的 Table 类可以方便地创建和格式化表格。以下示例展示了如何在 PDF 中插入一个包含数据的表格:

from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors# 创建 PDF 文件
pdf_path = "pdf_with_table.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)# 表格数据
data = [["Product", "Price", "Quantity"],["Widget", "$25.00", "10"],["Gadget", "$15.00", "30"],["Doohickey", "$5.00", "50"]
]# 创建表格
table = Table(data)
table.setStyle(TableStyle([("BACKGROUND", (0, 0), (-1, 0), colors.grey),("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),("ALIGN", (0, 0), (-1, -1), "CENTER"),("GRID", (0, 0), (-1, -1), 0.5, colors.black),("BACKGROUND", (0, 1), (-1, -1), colors.beige),
]))# 将表格添加到 PDF
table.wrapOn(pdf_canvas, 400, 300)
table.drawOn(pdf_canvas, 100, 600)# 保存 PDF
pdf_canvas.save()
print(f"PDF with table saved as {pdf_path}")

在此代码中,我们创建了一个包含产品、价格和数量信息的表格,并设置了样式,包括背景颜色、对齐方式和边框线。


四、汇总

PyPDF2 和 ReportLab 是处理 PDF 文件的两大主要工具,各有其强项:

  • PyPDF2:适用于读取、合并、拆分和加密 PDF 文件,主要用于处理现有的 PDF 文件。
  • ReportLab:用于从头生成 PDF 文件,可以精确控制布局,适合创建发票、报表和其他定制文档。

这两个库的结合可以帮助我们实现全面的 PDF 处理需求,从简单的文件合并到复杂的图表和表格创建,Python 都能轻松完成。希望这篇指南能帮您更好地掌握这两个库的使用方法,实现 PDF 的自动化处理。


五、综合应用:生成发票 PDF 示例

在这里,我们将 PyPDF2 和 ReportLab 结合使用,生成一个包含公司信息、客户信息和项目列表的发票 PDF。这种场景在实际应用中非常常见。

1. 创建发票模板

首先,我们使用 ReportLab 创建一个发票模板文件 invoice_template.pdf,包括公司标志、发票标题和必要的表格格式:

from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colorsdef create_invoice_template():pdf_path = "invoice_template.pdf"pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)# 设置页面标题pdf_canvas.setFont("Helvetica-Bold", 16)pdf_canvas.drawString(220, 800, "Invoice")# 公司信息pdf_canvas.setFont("Helvetica", 12)pdf_canvas.drawString(50, 780, "Company Name: XYZ Ltd.")pdf_canvas.drawString(50, 765, "Address: 123 Example St., City")pdf_canvas.drawString(50, 750, "Phone: (123) 456-7890")pdf_canvas.drawString(50, 735, "Email: contact@xyz.com")# 客户信息部分pdf_canvas.drawString(50, 700, "Bill To:")pdf_canvas.drawString(50, 685, "Customer Name:")pdf_canvas.drawString(50, 670, "Customer Address:")# 添加表格表头data = [["Item", "Description", "Quantity", "Unit Price", "Total"]]table = Table(data)table.setStyle(TableStyle([("BACKGROUND", (0, 0), (-1, 0), colors.grey),("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),("ALIGN", (0, 0), (-1, -1), "CENTER"),("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),("FONTSIZE", (0, 0), (-1, 0), 12),("BOTTOMPADDING", (0, 0), (-1, 0), 12),("GRID", (0, 0), (-1, -1), 0.5, colors.black),]))table.wrapOn(pdf_canvas, 450, 400)table.drawOn(pdf_canvas, 50, 600)# 保存模板pdf_canvas.save()print(f"Invoice template saved as {pdf_path}")# 生成模板
create_invoice_template()

在这个代码中,我们设置了发票的基本结构,包括公司和客户信息的显示位置,以及一张带有标题的表格,用于填写产品或服务明细。

2. 使用 PyPDF2 填写客户信息和项目详情

接下来,我们用 PyPDF2 在生成的模板上填写客户信息和项目详情。我们将客户信息和项目列表写入 invoice_filled.pdf 文件。

from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from io import BytesIOdef fill_invoice(customer_name, customer_address, items):# 打开模板reader = PdfReader("invoice_template.pdf")writer = PdfWriter()# 创建一个内存缓冲区来绘制覆盖内容packet = BytesIO()pdf_canvas = canvas.Canvas(packet, pagesize=A4)# 填写客户信息pdf_canvas.setFont("Helvetica", 12)pdf_canvas.drawString(150, 685, customer_name)pdf_canvas.drawString(150, 670, customer_address)# 填写项目明细y = 580for item in items:pdf_canvas.drawString(50, y, item["item"])pdf_canvas.drawString(150, y, item["description"])pdf_canvas.drawString(250, y, str(item["quantity"]))pdf_canvas.drawString(350, y, f"${item['unit_price']:.2f}")pdf_canvas.drawString(450, y, f"${item['quantity'] * item['unit_price']:.2f}")y -= 20  # 调整 y 坐标,确保每一项在新行# 保存绘制的内容pdf_canvas.save()# 将覆盖内容作为新页面内容合并packet.seek(0)overlay = PdfReader(packet)for page in reader.pages:page.merge_page(overlay.pages[0])writer.add_page(page)# 保存带内容的发票with open("invoice_filled.pdf", "wb") as output_pdf:writer.write(output_pdf)print("Invoice filled and saved as invoice_filled.pdf")# 示例数据
customer_name = "John Doe"
customer_address = "456 Example Ave., City"
items = [{"item": "Widget", "description": "High-quality widget", "quantity": 5, "unit_price": 20.00},{"item": "Gadget", "description": "Advanced gadget", "quantity": 3, "unit_price": 35.00},{"item": "Doohickey", "description": "Multi-purpose tool", "quantity": 2, "unit_price": 15.50},
]# 生成发票
fill_invoice(customer_name, customer_address, items)

在这个代码中,我们使用 fill_invoice 函数将客户信息和项目明细填充到 invoice_template.pdf 的模板中,并将其保存为 invoice_filled.pdf。每个项目明细按行填写,包括产品名称、描述、数量、单价和总价。


六、总结

在本教程中,我们学习了如何使用 PyPDF2 和 ReportLab 来处理 PDF 文件,从读取和合并现有文件,到从头生成和填充内容的自定义发票。这些技术为日常工作中的 PDF 操作带来了高效的解决方案,使自动化 PDF 处理成为可能。

借助 PyPDF2 和 ReportLab,您可以轻松创建自动化脚本生成 PDF 报告,处理包含敏感数据的加密文件,或构建批量文件处理系统。希望通过这篇博客,您能够灵活运用这两个库,提高 PDF 文件处理的效率。

相关文章:

Python中的PDF处理工具:PyPDF2和ReportLab使用指南

Python中的PDF处理工具:PyPDF2和ReportLab使用指南 在日常工作和项目中,PDF 文件处理是个常见需求,不论是合并报告、加密文档、填充表单,还是生成发票。Python 中有许多用于操作 PDF 文件的库,其中 PyPDF2 和 ReportL…...

【vxe-table】多选筛选项对列表的列进行动态的显示与隐藏

需求: 列表的组成部分由:一些固定的列,如:姓名,工号,以及 需要动态显示与隐藏的列,如:出勤、旷工、事假、病假等假勤类型 1、通过多选框多选,展示选中的列,未选中的不展示…...

微信小程序uniapp+vue飞机订票航空售票系统

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 对于小程序飞机订票信息管理所牵扯的信息管理及数据保存都是非常多的,举例像所有的管理员;管理员…...

如何取消Outlook中的循环会议

如何取消Outlook中的循环会议 参考链接:https://iknow.lenovo.com.cn/detail/195430 1、打开Outlook,进入 日历 视图界面; 2、 选择并双击要取消的循环会议; 3、 在 打开定期项目 对话框中选择整个序列,然后单击 确…...

Docker-- cgroups资源控制实战

上一篇:容器化和虚拟化 什么是cgroups? cgroups是Linux内核中的一项功能,最初由Google的工程师提出,后来被整合进Linux内核; 它允许用户将一系列系统任务及其子任务整合或分隔到按资源划分等级的不同组内,从而为系统…...

使用Python和Vosk库实现语音识别

使用Python和Vosk库实现语音识别 在人工智能和机器学习领域,语音识别技术正变得越来越重要。Python作为一种强大的编程语言,拥有丰富的库和框架,可以方便地实现语音识别功能。今天,我们将介绍如何使用Python中的SpeechRecognitio…...

stm32使用串口的轮询模式,实现数据的收发

------内容以b站博主keysking为原型,整理而来,用作个人学习记录。 首先在STM32CubeMX中配置 前期工作省略,只讲重点设置。 这里我配置的是USART2的模式。 会发现,PA2和PA3分别是TX与RX,在连接串口时需要TX对RX&…...

105. UE5 GAS RPG 搭建主菜单

在这一篇,我们将实现对打开游戏显示的主菜单进行搭建,主菜单将显示游戏主角,游戏名称和进入游戏和退出游戏两个按钮。 搭建菜单场景 我们将主菜单设置为一个单独的场景,前面可以显示对应的UI控件,用于玩家操作&#…...

基于 JAVASSM(Java + Spring + Spring MVC + MyBatis)框架开发一个医院挂号系统

基于 JAVASSM(Java Spring Spring MVC MyBatis)框架开发一个医院挂号系统是一个实用的项目。 步骤一:需求分析 明确系统需要实现的功能,比如: 用户注册和登录查看医生列表预约挂号查看预约记录取消预约管理员管…...

Golang | Leetcode Golang题解之第540题有序数组中的单一元素

题目&#xff1a; 题解&#xff1a; func singleNonDuplicate(nums []int) int {low, high : 0, len(nums)-1for low < high {mid : low (high-low)/2mid - mid & 1if nums[mid] nums[mid1] {low mid 2} else {high mid}}return nums[low] }...

影刀RPA实战:嵌入python,如虎添翼

1. 影刀RPA与Python的关系 影刀RPA与Python的关系可以从以下几个方面来理解&#xff1a; 技术互补&#xff1a;影刀RPA是一种自动化工具&#xff0c;它允许用户通过图形化界面创建自动化流程&#xff0c;而Python是一种编程语言&#xff0c;常用于编写自动化脚本。影刀RPA可以…...

es 数据清理delete_by_query

POST /索引名/_delete_by_query?conflictsproceed&scroll_size2000&wait_for_completionfalse&slices36 {"size": 2000, "query": {"bool": { "must": [{"terms": {"rule_id": [800007]}}]}} }slice…...

【每日 C/C++ 问题】

一、C 中类的三大特性是什么&#xff1f;请简要解释。 封装、继承、多态 封装&#xff1a;将事物的属性&#xff08;成员变量&#xff09;和行为&#xff08;成员函数&#xff09;封装在一起形成一个类。并且可以设置相应的访问权限&#xff08;私有的 受保护的 公有的&#…...

stm32学习4

学习目录 一.流水灯1.创建文件2.编写相关代码 一.流水灯 1.创建文件 将方法进行分类保存在不同的 .c 文件中&#xff0c;方便复用和寻找&#xff1b; 创建Hardware\LED文件&#xff0c;其中有led.c和led.h文件&#xff0c;用于存放有关LED灯操作的方法&#xff1b; 在User文…...

Midjourney国内直登

Midjourney确实是一个强大的AI绘画工具&#xff0c;能够根据用户输入的文本生成高质量的图像。然而&#xff0c;由于国内的网络限制&#xff0c;直接访问Midjourney可能会遇到障碍。 目前&#xff0c;已经有一些国内代理或中转平台可以帮助用户更方便地使用Midjourney&#xf…...

【双目视觉标定】——3面结构光相机标定实践(获取相机内参)~未完待续

相机标定基本原理及双目相机内参解析 相机标定是计算机视觉中的一个重要步骤&#xff0c;旨在确定相机的内部和外部参数&#xff0c;以便在图像处理中进行准确的三维重建、物体识别等任务。本文将重点讲解双目相机的内参和外参原理&#xff0c;并结合实际参数进行分析。 一、…...

Python常用脚本集锦

收集了一些常用Python脚本&#xff0c;作为平时练手使用&#xff0c;也可以作为自己的笔记&#xff0c;用到哪个功能可以自己查询一下即可。 文件和目录管理 复制文件 import shutil# 复制源文件到目标文件 shutil.copy(source.txt, destination.txt)移动文件 import shuti…...

MacBook 如何设置打开json格式文件的默认程序是vs code

首先右键选中文件&#xff0c;然后选中显示简介 然后选中打开方式 设置成vs code...

如何在 Spring Boot 中实现多数据源的事务管理?

在 Spring Boot 中实现多数据源的事务管理可以通过以下几种方式&#xff1a; 一、使用编程式事务管理 配置多个数据源 如同前面提到的&#xff0c;在 application.properties 或 application.yml 文件中配置多个数据源的连接信息&#xff0c;并创建对应的数据源 bean。 手动开启…...

SQL 常用更新操作

目录 1. 从一个查询结果中获取数据批量更新一张表 1. 从一个查询结果中获取数据批量更新一张表 更新table_a中所有id在tmp查询结果中的name值 UPDATE table_a a SET a.name tmp.name FROM (SELECT id, name FROM table_b) tmp WHERE a.id tmp.id;UPDATE table_a a JOIN (SE…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...