python自动化办公——定制化将电子签名批量签写到PDF文件

news2024/11/18 10:31:45

python自动化办公——定制化将电子签名批量签写到PDF文件

文章目录

  • python自动化办公——定制化将电子签名批量签写到PDF文件
    • 1、安装依赖
    • 2、需求分析
    • 3、代码

1、安装依赖

首先需要下载所需要的库

pip install pdf2image
pip install img2pdf
pip install opencv-python

此外还需要下载poppler,这里使用的是poppler-0.67.0

这是一个处理PDF文件的工具包,里面包含了非常多的功能供我们使用。

下载地址:https://blog.alivate.com.au/poppler-windows/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mZhYkSEa-1687095937537)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230618210931647.png)]

下载完压缩包之后,将压缩包解压到本地的某个地方,并记好路径。

2、需求分析

现需要将类似这种PDF文件,共10份或更多,批量插入电子签名

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CZNggct3-1687095937538)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230618211812141.png)]

假设每个PDF文件的签名位置相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fDPGbUHB-1687095937539)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230618212007712.png)]

写一个签名命名为tianhai.jpg

注:需将文件命名为英文,不然cv2的方法会读取不到文件

我们只需将需要签名的坐标找到,并插入图片即可。

3、代码

思路:

  1. 输入签字图片和PDF文件
  2. 将PDF文件转为图片格式
  3. 使用opencv对图片对签名和图片形式的文件进行处理
  4. 再将图片转换为PDF文件
  5. 输出PDF

导包

from pdf2image import convert_from_path
import img2pdf
import cv2
import os

使用pdf2image的convert_from_path方法,用于读取输入的PDF文件并将其转换为图片,注意将poppler-0.67.0\bin写入到参数里。

def pdf_to_image(inputPdf,outputJpg):
    images = convert_from_path(pdf_path=inputPdf,
                               dpi=400,
                               thread_count=4,
                               poppler_path='D:\\文件项目\\autoSign\\poppler-0.67.0\\bin')
    for index, img in enumerate(images):
        if index % 10 == 0:
            print('正在转换第%s页...' % (index))
        img.save(outputJpg + '_%s.jpg' % (index))

定义处理签名图片的函数

def signatureJpg(inputJpg,sigJpg,outputJpg):

    oriData = cv2.imread(inputJpg,0)

    sigData = cv2.imread(sigJpg,0)

    print(oriData.shape)
    oriRow = int(oriData.shape[0]*11.5//17)
    oriCol = int(oriData.shape[1]*5//12)

    print(oriCol,oriRow)
    # cv2.imshow('this',oriData)
    for i in range(sigData.shape[0]):
        for j in range(sigData.shape[1]):
            if sigData[i][j] < 100:
                oriData[oriRow+i][oriCol+j] = sigData[i][j]

    cv2.imwrite(outputJpg,oriData)

定义将图片形式转换为PDF的函数

def jpg_to_pdf(inputfile,outputfile):
    with open('output/' + outputfile,'wb') as f:
        f.write(img2pdf.convert(inputfile))
    print('ok')

定义签名的函数,传入原始PDF、电子签名,输出pdf

def signaturePdf(inputPdf,sigJpg,outputPdf):
    outputJpg = 'pdf2img'
    pdf_to_image(inputPdf,outputJpg)
    signatureJpg(outputJpg + '_0.jpg', sigJpg, outputJpg + '.jpg')
    jpg_to_pdf(outputJpg + '.jpg',outputPdf)

最后循环传入所有PDF进行处理,并执行上述函数,输出结果。

for i, j, k in os.walk('input/'):
    print(i,j,k)
    for item in k:
        inputPdf = i + item
        sigJpg = 'tianhai.jpg'
        outputPdf = item
        signaturePdf(inputPdf,sigJpg,outputPdf)

完整代码如下:

from pdf2image import convert_from_path
import img2pdf
import cv2
import os


def pdf_to_image(inputPdf,outputJpg):
    images = convert_from_path(pdf_path=inputPdf,
                               dpi=400,
                               thread_count=4,
                               poppler_path='D:\\文件项目\\autoSign\\poppler-0.67.0\\bin')
    for index, img in enumerate(images):
        if index % 10 == 0:
            print('正在转换第%s页...' % (index))
        img.save(outputJpg + '_%s.jpg' % (index))


def signatureJpg(inputJpg,sigJpg,outputJpg):

    oriData = cv2.imread(inputJpg,0)

    sigData = cv2.imread(sigJpg,0)

    print(oriData.shape)
    oriRow = int(oriData.shape[0]*11.5//17)
    oriCol = int(oriData.shape[1]*5//12)

    print(oriCol,oriRow)
    # cv2.imshow('this',oriData)
    for i in range(sigData.shape[0]):
        for j in range(sigData.shape[1]):
            if sigData[i][j] < 100:
                oriData[oriRow+i][oriCol+j] = sigData[i][j]

    cv2.imwrite(outputJpg,oriData)

def jpg_to_pdf(inputfile,outputfile):
    with open('output/' + outputfile,'wb') as f:
        f.write(img2pdf.convert(inputfile))
    print('ok')


def signaturePdf(inputPdf,sigJpg,outputPdf):
    outputJpg = 'pdf2img'
    pdf_to_image(inputPdf,outputJpg)
    signatureJpg(outputJpg + '_0.jpg', sigJpg, outputJpg + '.jpg')
    jpg_to_pdf(outputJpg + '.jpg',outputPdf)


for i, j, k in os.walk('input/'):
    print(i,j,k)
    for item in k:
        inputPdf = i + item
        sigJpg = 'qianming.jpg'
        outputPdf = item
        signaturePdf(inputPdf,sigJpg,outputPdf)

结果如下:多少个PDF都可以写入
在这里插入图片描述

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

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

相关文章

【工作记录】基于可视化爬虫spiderflow实战天气数据爬取@20230618

前言 之前写过一篇关于可视化爬虫spiderflow的文章&#xff0c;介绍了基本语法并实战了某校园新闻数据的爬取。 还有一篇文章介绍了基于docker-compose快速部署spiderflow的过程&#xff0c;需要部署的话可参考该文章。 文章链接如下: 可视化爬虫框架spiderflow入门及实战【…

基于SpringBoot+Vue+微信小程序的电影平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 研究背景&#xff1a;…

【通过Data Studio连接openGauss---快速入门】

【通过Data Studio连接openGauss---快速入门】 &#x1f53b; 一、访问openGauss&#x1f530; 1.1 确认连接信息&#xff08;单节点&#xff09;&#x1f530; 1.2 使用gsql访问openGauss&#xff08;本地连接数据库&#xff09;&#x1f530; 1.3 使用gsql访问openGauss&…

多道程序设计(操作系统)

目录 1 单道程序设计的缺点 2 多道程序设计的提出 3 多道程序设计的问题 多道程序设计目标&#xff1a; 多道程序设计是操作系统所采用最基本、最重要的技术&#xff0c;其根本目标是提高整个计算机系统的效率。衡量系统效率有一个尺度&#xff0c;那就是吞吐量。 提高系统…

clDice-一种新的分割标准-能够促进管状结构分割的连接性

clDice-a Novel Topology-Preserving Loss Function for Tubular StructureSegmentation论文总结 论文&#xff1a;clDice-A Novel Topology-Preserving Loss Function for Tubular Structure 源码&#xff1a;GitHub - jocpae/clDice 目录 一、论文背景和出发点 二、创新点 …

动态规划III (买股票-121、122、123、188、309)

CP121 买股票的最佳时机 题目描述&#xff1a; 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利…

Advanced-C.04.函数

函数 函数的定义 包括两个部分&#xff0c;“函数头"和"函数体” 返回值类型 函数名(形参1,形参2,...)//函数头{}//函数体 函数类型决定返回值类型&#xff0c;执行函数需要调用 函数的返回值和参数可以是任何类型&#xff0c;包括空类型&#xff01;&#xff01;函…

Android adb shell命令捕获systemtrace

Android adb shell命令捕获systemtrace (1)抓取trace文件&#xff1a; adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory -t 时长&#xff0c;20s&a…

Java学习笔记23——集合进阶

集合进阶 集合进阶CollectionCollection集合常用方法Collection集合的遍历Iterator中的常用方法集合的使用步骤 List集合概述和特点List集合的特点List集合的特有方法并发修改异常ListIterator 列表迭代器常用方法增强for循环 数据结构栈队列数组链表 Set集合Set特点实现类Hash…

Presto(Trino)的逻辑执行计划和Fragment生成过程

文章目录 1. 前言2. 从SQL提交到Fragment计划生成全过程2.1 Statement生成2.2 对结构化的Statement进行分析2.3 生成未优化的逻辑执行计划2.4 基于Visitor模型对逻辑执行计划进行优化2.4.1 Visitor模型介绍2.4.2 Presto中常见的逻辑执行计划优化器常规OptimizerIterativeOptimi…

阿里月薪23k软件测试工程师:必备的6大技能(建议收藏)

随着软件开发行业的日益发展&#xff0c;岗位需求量和行业薪资都不断增长&#xff0c;想要入行的人也是越来越多&#xff0c;但不知道从哪里下手&#xff0c;今天&#xff0c;就给大家分享一下&#xff0c;软件测试行业都有哪些必会的方法和技术知识点&#xff0c;作为小白该从…

EmGU(4.7) 和C#中特征检测算法详解集合

C#联合Emgu实现计算机视觉任务&#xff08;特征提取篇&#xff09; 文章目录 C#联合Emgu实现计算机视觉任务&#xff08;特征提取篇&#xff09;前言一、Emgu库中特征提取有哪些类函数&#xff1f;二、特征提取函数1.AgastFeatureDetector类2.AKAZE 类3.FastFeatureDetector类4…

Docker部署(2)——实现两个容器互相访问并运行项目

一、拉取MySQL镜像&#xff0c;并启动镜像对应的容器 由于上一篇文章实现了拉取jdk8的环境&#xff0c;同时将jar包打成了一个镜像。但是要想真正的把项目运行起来&#xff08;此处仅以单体项目为例&#xff09;还需要MySQL的容器提供数据支持&#xff08;当然这里面方法有多种…

深蓝学院C++基础与深度解析笔记 第 4 章 表达式

第 4 章 表达式 一、表达式基础 A、表达式: 由一到多个操作数组成&#xff0c;可以求值并 ( 通常会 ) 返回求值结果: #include <iostream> int main(){int x;x 3; }最基本的表达式&#xff1a;变量、字面值通常来说&#xff0c;表达式会包含操作符&#xff08;运算符…

Vue3项目中引入ElementUI使用详解

目录 Vue3项目中引入 ElementUI1.安装2.引入2.1 全局引入2.2 按需引入viteWebpack 3.使用 Vue3项目中引入 ElementUI ElementUI是一个强大的PC端UI组件框架&#xff0c;它不依赖于vue&#xff0c;但是却是当前和vue配合做项目开发的一个比较好的ui框架&#xff0c;其包含了布局…

TensorFlow详细配置(Python版本)

文章目录 TensorFlow详细配置(Python版本)安装Python环境&#xff08;Python全家桶 Anaconda3&#xff09;环境配置TensorFlow官网对照表CUDA安装cuDNN 安装TensorFlow安装Jupyter Notebook使用方法其他问题 TensorFlow详细配置(Python版本) 安装Python环境&#xff08;Python…

51 最佳实践-安全最佳实践-qemu-ga

文章目录 51 最佳实践-安全最佳实践-qemu-ga51.1 概述51.2 操作方法 51 最佳实践-安全最佳实践-qemu-ga 51.1 概述 qemu-ga&#xff08;Qemu Guest Agent&#xff09;它是运行在虚拟机内部的守护进程&#xff0c;它允许用户在host OS上通过QEMU提供带外通道实现对guest OS的多…

【面试】线上Java程序占用 CPU 过高请说一下排查方法?

文章目录 前言模拟一个高 CPU 场景排查步骤第一步&#xff0c;使用 top 找到占用 CPU 最高的 Java 进程第二步&#xff0c;用 top -Hp 命令查看占用 CPU 最高的线程第三步&#xff0c;保存线程栈信息第四步&#xff0c;在线程栈中查找最贵祸首的线程 前言 这个问题可以说是 Ja…

【java】JDK21 要来了

文章目录 前言更丝滑的并发编程模式虚拟线程&#xff08;Virtual Threads&#xff09;结构化并发&#xff08;Structured Concurrency&#xff09;作用域值&#xff08;Scoped Values&#xff09; 试验一下虚拟线程的例子结构化编程的例子Scoped Values 的例子 前言 不过多久&…

算法与数据结构——递归算法+回溯算法——八皇后问题

八皇后问题 八皇后问题是一个经典的回溯算法问题&#xff0c;目的是在88的国际象棋棋盘上放置八个皇后&#xff0c;使得没有皇后可以互相攻击&#xff08;即没有两个皇后在同一行、同一列或同一对角线上&#xff09;。 回溯算法是一种解决问题的算法&#xff0c;它通过尝试所有…