PyPDF2:项目实战源码分享(PDF裁剪)

news2024/11/20 13:31:17

PyPDF2

目录📑

    • 1. 背景📑
    • 2. 源码模块解析📑
      • 2.1 读取PDF页数
      • 2.2 获取指定页的宽高尺寸
      • 2.3 裁剪单页PDF
      • 2.4 批量裁剪PDF
    • 总结📑

1. 背景📑

接PyPDF2模块推荐博文中提到的实际需求(将银行网站下载来的多页且单页多张回单的PDF裁剪成每张单据独立一个PDF文件),我决定将项目所做操作的模块化源码分享给大家

原PDF
原PDF

裁剪后PDF
原PDF

2. 源码模块解析📑

2.1 读取PDF页数

因为数据范围是动态的,所以每次处理的PDF页数也是不同的,操作一个回单PDF首先需要知道他有多少页

def get_page_num(pdf_path) -> int:
    """
    获取PDF文件页数

    params:
        pdf_path: 需要读取页数的PDF文件路径

    return:
        _pages_count: PDF文件的页数
    """
    with open(pdf_path, 'rb') as _pdf_file:
        # 读取PDF文件
        _pdf_file = PyPDF2.PdfReader(_pdf_file)
        # 获取总页数
        _pages_count = len(_pdf_file.pages)
    return _pages_count

2.2 获取指定页的宽高尺寸

裁剪前肯定需要知道原尺寸,然后根据原尺寸初步三等分,再做微调,最终实现银行回单的等分

def get_page_wh(pdf_path, page_num) -> list:
    """
    获取PDF文件指定页的宽高数据

    params:
        pdf_path: 需要读取宽高的PDF文件路径
        page_num: 需要读取宽高的是哪一页,页码

    return:
        _width: PDF文件指定页的宽度
        _height: PDF文件指定页的高度
    """
    with open(pdf_path, 'rb') as _pdf_file:
        # 读取PDF文件
        _pdf_file = PyPDF2.PdfReader(_pdf_file)
        # 获取PDF指定页信息
        _pdf_info = _pdf_file.pages[int(page_num) - 1]
        # 获取PDF指定页宽
        _width = float(_pdf_info.mediabox.width)
        # 获取PDF指定页高
        _height = float(_pdf_info.mediabox.height)
    return [_width, _height]

2.3 裁剪单页PDF

下面就是需求的核心功能——裁剪了(需要注意的是,我这里是根据需求将裁剪后的每一张回单放在同一个输出PDF文件中,如果需要每一张回单都为一个独立PDF文件,可以自行调整代码)

def split_pdf(input_path, output_path, page_num, upper_left, upper_right, lower_left, lower_right):
    """
    裁剪指定单页PDF的区域,并另存为一个独立的文件到output_path

    注意:
        当PDF单页的 宽width < 高height 的时候,即文件是竖向的时候,左下角为坐标原点
        当PDF单页的 宽width > 高height 的时候,即文件是横向的时候,右下角为坐标原点

    params:
        input_path: 需要裁剪的PDF文件路径
        output_path: 输出路径
        page_num: 需要裁剪的是哪一页,页码
        upper_left: 裁剪区域的左上角坐标
        upper_right: 裁剪区域的右上角坐标
        lower_left: 裁剪区域的左下角坐标
        lower_right: 裁剪区域的右下角坐标
    """
    with open(input_path, 'rb') as _input_file:
        # 读取PDF文件
        _input_file = PyPDF2.PdfReader(_input_file)
        # 创建输出PDF对象
        _that_page = PyPDF2.PdfWriter()
        # 获取PDF文件指定页对象
        _this_page = _input_file.pages[int(page_num) - 1]
        # 划定裁剪区域
        _this_page.mediabox.upper_left = tuple(upper_left)
        _this_page.mediabox.upper_right = tuple(upper_right)
        _this_page.mediabox.lower_left = tuple(lower_left)
        _this_page.mediabox.lower_right = tuple(lower_right)
        # 为输出PDF对象添加裁剪页
        _that_page.add_page(_this_page)

        with open(output_path, 'wb') as _output_file:
            # 将输出PDF对象写入输出路径文件
            _that_page.write(_output_file)

2.4 批量裁剪PDF

因为原需求是一个回单PDF中由格式相同的多页回单组成的,所以我直接写了一个批量裁剪整个多页PDF文件的函数(同样需要注意的是,我这里根据需求写的是将裁剪后的每一张回单放在同一个输出PDF文件中,如果需要每一张回单都为一个独立PDF文件,可以自行调整代码)

def batch_split_pdf(input_path, output_path, crop_area_list):
    """
    循环PDF文件每一页,裁剪出每一页所有裁剪区域列表中指示的区域,并且裁剪后输出到同一个PDF文件内

    注意:
        当PDF单页的 宽width < 高height 的时候,即文件是竖向的时候,左下角为坐标原点
        当PDF单页的 宽width > 高height 的时候,即文件是横向的时候,右下角为坐标原点

    params:
        input_path: 需要裁剪的PDF文件路径
        output_path: 输出路径
        crop_area_list: 需要裁剪的区域列表(三维列表)
    """
    with open(input_path, 'rb') as _input_file:
        # 读取PDF文件
        _input_file = PyPDF2.PdfReader(_input_file)
        # 获取总页数
        _pages_count = len(_input_file.pages)
        # 创建输出PDF对象
        _that_page = PyPDF2.PdfWriter()
        # 循环每一页
        for _page_num in range(_pages_count):
            # 循环要裁剪的区域列表
            for _crop_area in crop_area_list:
                # 获取PDF文件指定页对象
                _this_page = _input_file.pages[_page_num]
                # 划定裁剪区域
                _this_page.mediabox.upper_left = tuple(_crop_area[0])
                _this_page.mediabox.upper_right = tuple(_crop_area[1])
                _this_page.mediabox.lower_left = tuple(_crop_area[2])
                _this_page.mediabox.lower_right = tuple(_crop_area[3])
                # 为输出PDF对象添加裁剪页
                _that_page.add_page(_this_page)
        
        with open(output_path, 'wb') as _output_file:
            # 将输出PDF对象写入输出路径文件
            _that_page.write(_output_file)

总结📑

以上就是关于银行回单PDF裁剪需求涉及到的源代码了,抛砖引玉,大家可以根据自己更强的实力对代码做自己的个性化调整,冲💪!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1469250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式--单例模式--懒汉饿汉

单例模式 单例模式(Singleton)&#xff0c;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 单例模式 通常我们可以让一个全局变量使得一个对象被访问&#xff0c;但它不能防止你实例化多个对象。一个最好的办法就是&#xff0c;让类自身负责保存它的唯一实…

[嵌入式系统-34]:RT-Thread -19- 新手指南:RT-Thread标准版系统架构

目录 一、RT-Thread 简介 二、RT-Thread 概述 三、许可协议 四、RT-Thread 的架构 4.1 内核层&#xff1a; 4.2 组件与服务层&#xff1a; 4.3 RT-Thread 软件包&#xff1a; 一、RT-Thread 简介 作为一名 RTOS 的初学者&#xff0c;也许你对 RT-Thread 还比较陌生。然…

vue-element-admin如何绕开系统的请求的路由,使用静态路由

我开发时候遇到一个这样的问题&#xff0c;服务端权限管理部分还没搞好&#xff0c;所以但是需要将所有菜单列出来 我做了以下的修改 首先是建一个文件存放后期需要动态生成的路由 引入到常量路由中 另外在permissions当中

FPGA之16:1复选器

每个slice 都有一个F8MUX。F8MUX原语&#xff1a; MUXF8 MUXF8_inst&#xff08; .0&#xff08;0&#xff09;&#xff0c;Il Output of MUX to general routing .I0&#xff08;10&#xff09;&#xff0c;//Input&#xff08;tie to MUXF7L/LO out&#xff09; .I1&#xf…

This dependency was not found解决方法

问题如上(前端代码)&#xff0c;我是引用js文件出的问题&#xff0c;无法找到api/userManage模块。 解决&#xff1a;没感觉哪有问题&#xff0c;把后面加了个/&#xff0c;就解决了&#xff0c;代表src目录&#xff0c;应该是目录和目录之间应该有/作为分割&#xff1a;

vue3+js 实现记住密码功能

常见的几种实现方式 1 基于spring security 的remember me 功能 ​​​​​​​ localStorage 除非主动清除localStorage 里的信息 &#xff0c;不然永远存在&#xff0c;关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…

C++ //练习 8.4 编写函数,以读模式打开一个文件,将其内容读入到一个string的vector中,将每一行作为一个独立的元素存于vector中。

C Primer&#xff08;第5版&#xff09; 练习 8.4 练习 8.4 编写函数&#xff0c;以读模式打开一个文件&#xff0c;将其内容读入到一个string的vector中&#xff0c;将每一行作为一个独立的元素存于vector中。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09…

【Java程序设计】【C00314】基于Springboot的足球俱乐部管理系统(有论文)

基于Springboot的足球俱乐部管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的足球俱乐部管理系统的设计与实现&#xff0c;本系统有管理员以及用户二种角色权限 管理员权限操作的功能包括管理公告&#x…

C语言实现简单选择排序

简单选择排序 简单选择排序的平均复杂度为 O(n2),但效率通常比相同平均复杂度的直接插入排序还要差。但由于选择排序是 内部排序&#xff0c;因此在内存严格受限的情况下还是可以用的。选择排序的原理很简单&#xff0c;如下图所示&#xff1a;持续从未处理元素中找到最小值并加…

使用命令行创建文件夹和文件

创建文件夹 md 文件夹名字 创建文件 echo >文件名字.后缀然后回车即可 注意点:echo >文件名字.后缀 的 >后面不可以加空格&#xff0c;不然会报错\

16. BI - 推荐系统之 ALS 实现

本文为 「茶桁的 AI 秘籍 - BI 篇 第 16 篇」 文章目录 对 MovieLens 进行电影推荐 Hi,你好。我是茶桁。 前面两节课的内容中&#xff0c;我们从矩阵分解到 ALS 原理&#xff0c;依次给大家讲解了推荐系统中的一个核心概念。 矩阵分解中拆矩阵的背后其实是聚类。就说 k 等于几…

YOLOv8重磅升级!新增旋转目标检测功能

YOLOv8重磅升级&#xff01;新增旋转目标检测功能&#xff0c;基于DOTA数据集&#xff0c;支持15个类别目标航拍图像检测&#xff0c;模型&代码均已开源~ 新版亮点 YOLOv8-OBB&#xff1a;YOLOv8中OBB(Oriented Bounding Box)模型的引入标志着物体检测的重要一步&#xff…

重点媒体如何投稿?考核稿件投稿指南

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 机构组织&#xff0c;国企央企都需要定期将相关新闻投递到央媒&#xff0c;官媒&#xff0c;或者地方重点媒体中&#xff0c;那么如何进行投稿了&#xff0c;今天就与大家分享下。 央媒投…

kafka生产者2

1.数据可靠 • 0&#xff1a;生产者发送过来的数据&#xff0c;不需要等数据落盘应答。 风险&#xff1a;leader挂了之后&#xff0c;follower还没有收到消息。。。。 • 1&#xff1a;生产者发送过来的数据&#xff0c;Leader收到数据后应答。 风险&#xff1a;leader应答…

C++ //练习 8.2 测试函数,调用参数为cin。

C Primer&#xff08;第5版&#xff09; 练习 8.2 练习 8.2 测试函数&#xff0c;调用参数为cin。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块见练习8.1 /**************************************************************…

密码算法简单整理

密码组成 国外的密码算法&#xff1a; DES、3DES、AES、SHA1、SHA2、SHA3、DSA、RSA、RC4等 高危密码算法&#xff1a; MD5、DES、RSA1024以下、SSH1.0、SSL3.0以下、SHA1等 密码算法通常可分为三大类&#xff1a; 对称密码算法 非对称密码算法 密码杂凑算法 1.对称密码算法&am…

MacOs 围炉夜话

文章目录 一、安装 Mac 一、安装 Mac macOS是一套由苹果开发的运行于Macintosh系列电脑上的操作系统。macOS是首个在商用领域成功的图形用户界面操作系统。 VM虚拟机怎么安装mac os&#xff1f;&#xff08;全教程&#xff09; 虚拟机&#xff1a;VMware Workstation 17 pro W…

IDEA下新建SpringBoot项目详细步骤

在IDEA下使用Spring Initializer&#xff1a; 一、新建项目&#xff0c;利用阿里云网址https://start.aliyun.com/下载项目&#xff0c;来到Spring Initializer模块&#xff1a; 我的jdk是8&#xff0c;构建Maven类型的项目&#xff0c;Java版本选8&#xff0c;Group为公司名。…

Python中操作MySQL和SQL Server数据库的基础与实战【第97篇—MySQL数据库】

Python中操作MySQL和SQL Server数据库的基础与实战 在Python中&#xff0c;我们经常需要与各种数据库进行交互&#xff0c;其中MySQL和SQL Server是两个常见的选择。本文将介绍如何使用pymysql和pymssql库进行基本的数据库操作&#xff0c;并通过实际代码示例来展示这些操作。…

音频smmu问题之smmu学习

一、音频smmu 内存访问问题 在工作中&#xff0c;遇到一个smmu问题&#xff0c;主要log信息如下&#xff1a; arm-smmu 15000000.apps-smmu: Unhandled arm-smmu context fault from soc:spf_core_platform:qcom,msm-audio-ion! arm-smmu 15000000.apps-smmu: FAR 0x0000000…