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

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都可以写入
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue + el-table点击表头改变其当前样式

废话不多说&#xff0c;先看效果&#xff1a; 网上找了一大圈没有符合的&#xff0c;只能自己看着搞&#xff1a; 直接贴代码&#xff1a; <el-tableref"table":data"tableData"borderstripesort-change"changeColumn"><el-table-colu…

springMVC(二)—— 进阶

一、解决中文乱码问题 解决中文乱码问题的关键在于判断字符是什么时候乱码的 先在java程序里刚生成这个值的地方打印一下&#xff0c;如果在控制台输出就乱码了&#xff0c;那就排除浏览器和jsp页面的编码出问题。否则 看浏览器的编码 看这个jsp页面的编码是否设置好了 一般不用…

简要介绍 | 两阶段点云目标检测:理论与实践

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对两阶段点云目标检测进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 两阶段点云目标检测&#xff1a;理论与实践 在这篇博客中&#xff0c;我们将探索两阶段点云目标检测的理论基础和实际应用…

cancal 同步mysql数据到es中

1.环境&#xff1a; windocs service2012 、 jdk版本1.8 、canal版本1.5、mysql版本5.7、 注意&#xff1a;canal版本1.5需要的jdk是1.8 如果你下载的是canal1.6&#xff0c;jdk是1.8&#xff0c;那样会报错。 下载地址 Releases alibaba/canal GitHub 下载并上传到服…

创建数据库Market、Team,按要求完成指定操作

创建数据库Market&#xff0c;在Market中创建数据表customers&#xff0c;customers表结构如表4.6所示&#xff0c;按要求进行操作。 代码如下&#xff1a; #(1&#xff09;创建数据库Market mysql> create database Market; Query OK, 1 row affected (0.00 sec)mysql>…

Java阶段五Day02

Java阶段五Day02 文章目录 Java阶段五Day02MAVEN-聚合(多模块3)回顾多模块2个特性依赖:继承: 聚合场景聚合目的实现聚合聚合总结 远程仓库远程仓库概念配置settings.xml远程库配置注意事项 GIT详细学习git概括git历史本地版本控制相关命令git分支管理分支管理基本概念分支管理相…

Failed to initialize NVML: Driver/library version mismatch

nvidia驱动安装之后&#xff0c;nvidia-smi 报错 Driver/library version mismatch 不重启系统的解决方法 查看系统日志&#xff0c;确定具体报错信息&#xff1a; # dmesg | tail [8598493.408944] NVRM: API mismatch: the client has the version 525.125.06, butNVRM: t…

STL好难(4):list的使用

和列表很像 1.list的介绍 点击这里查看 list 的官方文档 list类似数据结构中的链表 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独…

flutter聊天界面-自定义表情键盘实现

flutter聊天界面-自定义表情键盘实现 flutter 是 Google推出并开源的移动应用开发框架&#xff0c;主打跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App&#xff0c;一套代码同时运行在 iOS 和 Android平台。 flutter开发基础腾讯IM的聊天应用&#xff0c;使用的是t…

css设计表格圆角最简单的方法

代码如下&#xff1a; table {width: 100%;/* border-collapse: collapse; */background-color: #FBFBFB; /* 背景颜色; */border-collapse: separate; /* 让border-radius有效 */border-spacing: 0; /*表格中每个格边距设为0*/border: 1px solid #DFDFDF;/*边框*/border-radi…

ETHERNET/IP 转ETHERCAT连接倍福和欧姆龙PLC的配置方法

ETHERNET/IP和ETHERCAT是两种不同的协议&#xff0c;它们在工业生产中都有广泛的应用。然而&#xff0c;由于协议不同&#xff0c;这两种设备之间无法通讯&#xff0c;这给工业生产带来了很大的麻烦。而远创智控YC-EIP-ECT网关应运而生&#xff0c;它能够连接到ETHERNET/IP总线…

【Linux之拿捏信号3】阻塞信号

文章目录 相关概念原理sigset_t信号集信号集操作函数sigprocmask系统调用sigpending 相关概念 实际执行信号的处理动作——信号递达Delivery&#xff08;例如自定义捕捉动作&#xff0c;core&#xff0c;Term终止进程的动作&#xff09;。信号从产生到递达之间的状态——信号未…

Anaconda配置可视化绘图库seaborn的方法

本文介绍在Anaconda的环境中&#xff0c;安装Python语言中&#xff0c;常用的一个绘图库seaborn模块的方法。 seaborn模块是基于Matplotlib的数据可视化库&#xff0c;它提供了一种更简单、更漂亮的界面来创建各种统计图形。seaborn模块主要用于数据探索、数据分析和数据可视化…

换零钱——最小钱币张数(贪心算法)

贪心算法&#xff1a;根据给定钱币面值列表&#xff0c;输出给定钱币金额的最小张数。 (本笔记适合学完python基本数据结构&#xff0c;初通 Python 的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣…

C/C++编程安全标准GJB-8114解读——声明定义类

软件检测实验室在建立软件测试体系或申请cnas/cma相关资质时&#xff0c;需要依据相关标准&#xff0c;使用有效的方法开展检验检测活动&#xff0c;GJB-8114是一部嵌入式软件安全测试相关的国家标准&#xff0c;本系列文章我们就针对GJB-8114《C/C语言编程安全子集》的具体内容…

Android 热修复一

一、什么是热修复&#xff1f; 在我们应用上线后出现bug需要及时修复时&#xff0c;不用再发新的安装包&#xff0c;只需要发布补丁包&#xff0c;在客户无感知下修复掉bug。 实现效果&#xff1a; Demo源码&#xff1a; https://gitee.com/sziitjim/hotfix 二、怎么进行热修…

一文了解Docker之网络模型

目录 1.Docker网络 1.1 Docker网络模型概述 1.2 Docker网络驱动程序 1.2.1 host模式 1.2.2 bridge模式 1.2.3 container模式 1.2.4 none模式 1.3 Docker网络命令示例 1.3.1 创建一个自定义网络 1.3.2 列出所有网络 1.3.3 连接容器到网络 1.3.4 断开容器与网络的连接…

如何与ChatGPT愉快地聊天

原文链接&#xff1a;https://mp.weixin.qq.com/s/ui-O4CnT_W51_zqW4krtcQ 人工智能的发展已经走到了一个新的阶段&#xff0c;在这个阶段&#xff0c;人工智能可以像人一样与我们进行深度的文本交互。其中&#xff0c;OpenAI的ChatGPT是一个具有代表性的模型。然而&#xff0…

【ARM Coresight 系列文章 3.1 - ARM Coresight DP 对 AP 的访问 1】

文章目录 1.1 DP 中相关寄存器的介绍1.1.1 DPACC and APACC 寄存器1.1.2 DP SELECT 寄存器1.1.3 AP CSW寄存器1.1.4 AP TAR 寄存器1.1.5 AP DRW寄存器1.1.6 AP Banked Data registers 1.1 DP 中相关寄存器的介绍 如果DAP接入的是JTAG接口&#xff0c;那么将会通过APACC寄存器来…

[VUE学习]权限管理系统前端vue实现8-右上角用户头像显示实现

1.现在有个问题 我们再没有token情况下通过url可以直接访问页面 这不可以 所以我们需要添加路由守卫 拦截 2.permission.js的代码 import router from "/router/index" import store from "/store"router.beforeEach((to,from,next)>{const whiteList…