审计文件标识作为水印打印在pdf页面边角

目录

  • 说明

说明

将审计文件的所需要贴的编码直接作为水印贴在页面四个角落,节省辨别时间

我曾经写过一个给pdf页面四个角落加上文件名水印的python脚本,现在需要加一个图形界面进一步加强其实用性。首先通过路径浏览指定文件路径,先检测该路径是不是已经存在的文件夹,如果不是,再判断是不是txt如果也不是,提示需要txt路径列表或者提供根路径,如果是文件路径,提示该路径下子文件夹的文件也会被做同样处理,做好文件备份隔离防护工作。如果是txt则按行读取,并且提示其中的路径有多少是有效的。
提供一个勾选框,决定是否要将路径中的各种图片格式转化为同名pdf。然后提供两个文本框指定图片转化线程数和水印添加线程数
然后再提供2个参数文本框,第一个文本框内数字为g(成为打印页边距)分别用来调节水印离两个方向页面边界的距离(%为单位的相对距离,实际距离取决于读取到的页面尺寸,长和宽的乘积取平方根再乘以g%),第2文本框用来指定相对字体大小f%%为单位,计算一个参考高度等于页面长宽乘积取平方根再乘以5%再乘以f%,然后计算选定字体显示高度与参考高度相等的字号),用标签提示最好在实验文件夹中测试好需要的相对字体大小
font_family根据系统可选提供下拉菜单,改为用户指定,前两个默认为Times New Roman和楷体
水印内容和示例代码中一样根据文件名、当前页数和总页数来确定
由于插入点是文本左上角,而四个角文本的方向不同,为了让文本更好贴合打印边界又不超出打印边界,该代码根据页面尺寸、打印边距和指定字体字号情况下文本显示所占矩形空间来确定插入点的具体位置
点击执行按钮,遍历一次路径如果有图片需要转化又未被转化,先转化图片为pdf(多线程执行),同时记录所有有待处理的pdf文件数(包括图片转化出来的)
再遍历一次路径,将每个pdf的按照设定参数添加水印(用多线程执行),并且替换原文件。按已处理文件数/总文件数显示进度条,完成后弹窗提示

import os
import re
import fitz
from PIL import ImageFont
def text_position(w,h,x,y,width,height,gap):
    if y<=height/2:
        if x<=width/2:
            x=max(x,gap)+h
            y=gap+w
            return [x,y]
        else:
            x=width-gap-w
            y=max(gap,y)+h
            return [x,y]
    else:
        if x<=width/2:
            x=gap+w
            y=height-max(gap,height-y)-h
            return [x,y]
        else:
            x=width-max(gap,width-x)-h
            y=height-gap-w
            return [x,y]
def text_size(line,font_family,font_size):
    font = ImageFont.truetype(font_family, font_size, 0)
    width, height = font.getsize(line)
    #DeprecationWarning: getsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use getbbox or getlength instead.
    return [width,height]
def text_insert_once(x1,y1,x2,y2,x3,y3,x4,y4,text,fname,fsize,page):
    p = fitz.Point(x2,y2)#右上角
    page.insert_text(p,  # bottom-left of 1st char
                         text,  # the text (honors '\n')
                         fontname = fname,  # the default font
                         fontsize = fsize,  # the default font size
                         rotate = 0,  # also available: 90, 180, 270
                         )
    p = fitz.Point(x3,y3)#左下角,从右往左
    page.insert_text(p,  # bottom-left of 1st char
                         text,  # the text (honors '\n')
                         fontname = fname,  # the default font
                         fontsize = fsize,  # the default font size
                         rotate = 180,  # also available: 90, 180, 270
                         )
    p = fitz.Point(x1,y1)#左上角,从下到上
    page.insert_text(p,  # bottom-left of 1st char
                         text,  # the text (honors '\n')
                         fontname = fname,  # the default font
                         fontsize = fsize,  # the default font size
                         rotate = 90,  # also available: 90, 180, 270
                         )
    p = fitz.Point(x4,y4)#右下角,从上到下
    page.insert_text(p,  # bottom-left of 1st char
                         text,  # the text (honors '\n')
                         fontname = fname,  # the default font
                         fontsize = fsize,  # the default font size
                         rotate = 270,  # also available: 90, 180, 270
                         )
def pnum_print(pdf,file,flag=1):
    pagenum=pdf.page_count    
    i=0
    for page in pdf:
        content=[]
        #假定短边留白5%,长边留白3.3%
        i=i+1
        width=page.rect.width
        height=page.rect.height
        [wx,hx]=[0.06,0.04]
        if width>= height:
            #w=round(width*wx,0)
            h=round(height*wx,0)
            w=h
        else:
            w=round(width*wx,0)
            h=w
        fs=int(w/4)
        text=str(i)+'/'+str(pagenum)
        content.append(os.path.splitext(file)[0])
        content.append(text)       
        ff=page.insert_font(fontname="HT",fontfile=r"C:\Windows\Fonts\simhei.ttf", fontbuffer=None , set_simple=False )
        [x1,y1,x2,y2,x3,y3,x4,y4]=[0,0,width,0,0,height,width,height]
        for c in content:
            [w,h]=text_size(c,"simhei.ttf",fs)
            [x1,y1]=text_position(w,h,x1,y1,width,height,0*w)
            [x2,y2]=text_position(w,h,x2,y2,width,height,0*w)
            [x3,y3]=text_position(w,h,x3,y3,width,height,0*w)
            [x4,y4]=text_position(w,h,x4,y4,width,height,0*w)
            text_insert_once(x1,y1,x2,y2,x3,y3,x4,y4,c,"HT",fs,page)
    if pdf.can_save_incrementally():
        if flag==1:
            pdf.saveIncr()
        else:
            pdf.save(os.path.splitext(file)[0]+'(共'+str(pagenum)+'页)'+'.pdf')
        print(file+"***********processed")
        pdf.close()
        if flag!=1:
            os.remove(file)
        #os.remove(file)
    else:
        print("Can't save Incermentally")#增量保存的文件损坏和签名问题
def path_read(flag,source):
    path=[]
    if flag=="父节点":
        for p in os.listdir(source):
            if os.path.isdir(source+'\\'+p):
                path.append(source+'\\'+p)
        return path
    if flag=="列表文件":
        with open(source,'r') as f :
            for p in f.readlines():
                pp=p.replace('\n','')
                if os.path.isdir(pp):
                    path.append(pp)
        return path
    return None
def pic2pdf(file):
    img_file=['.png','.jpg',',jepg']
    title=os.path.splitext(file)[0]
    if os.path.splitext(file)[1] in img_file:
        imgdoc = fitz.open(file) # 打开图片
        pdfbytes = imgdoc.convert_to_pdf() # 使用图片创建单页的 PDF
        imgpdf = fitz.open("pdf", pdfbytes)
        doc=fitz.open()
        doc.insert_pdf(imgpdf) # 将当前页插入文档
        if os.path.exists(title+".pdf"):
            os.remove(title+".pdf")
        doc.save(title+".pdf") # 保存pdf文件
        doc.close()
        imgdoc.close()
        os.remove(file)
img_file=['.png','.jpg',',jepg']
img_convert=True #False  #True
#path=path_read(flag="列表文件",source=r'E:\huang\Desktop\路径列表.txt')
path=path_read(flag="父节点",source=r'E:\huang\Desktop\浙江通力传动科技股份有限公司\乐总底稿整理\新建文件夹\内控')
print(path)
for p in path:
    os.chdir(p)
    print(p)
    if img_convert:
        for file in os.listdir():
            if os.path.splitext(file)[1] in img_file:
                pic2pdf(file)
    for file in os.listdir():
        if os.path.splitext(file)[1]=='.pdf':
            print(file)
            if re.search(r'\(共\d+?页\)',file)==None:
                pdf_book=fitz.open(file)
                pnum_print(pdf_book,file,0)
                    

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

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

相关文章

多平台下Informatica在医疗数据抽取中的应用

一、引言 1.医疗数据抽取与 Informatica 概述 1.1 医疗数据的特点与来源 1.1.1 数据特点 医疗数据具有显著的多样性特点。从数据类型来看&#xff0c;涵盖了结构化数据&#xff0c;如患者的基本信息、检验检查结果等&#xff0c;这些数据通常以表格形式存储&#xff0c;便于…

智能创造的幕后推手:AIGC浪潮下看AI训练师如何塑造智能未来

文章目录 一、AIGC时代的算法与模型训练概览二、算法与模型训练的关键环节三、AI训练师的角色与职责四、AI训练师的专业技能与素养五、AIGC算法与模型训练的未来展望《AI训练师手册&#xff1a;算法与模型训练从入门到精通》亮点内容简介作者简介谷建阳 目录 《AI智能化办公&am…

有限元分析学习——Anasys Workbanch第一阶段笔记(13)网格单元分类、物理场与自由度概念

目录 0 序言 1 网格单元分类 2 各类单元的应用 3 massage与帮助和查看 4 物理场和自由度 4.1 各种单元自由度 4.2 结构自由度 0 序言 本章主要讲解网格单元的分类及物理场和自由度的相关概念。 1 网格单元分类 按单元的形状分类&#xff1a;实体单元、壳单元和杆梁单元…

RC2在线加密工具

RC2是由著名密码学家Ron Rivest设计的一种传统对称分组加密算法&#xff0c;它可作为DES算法的建议替代算法。RC2是一种分组加密算法&#xff0c;RC2的密钥长度可变&#xff0c;可以从8字节到128字节&#xff0c;安全性选择更加灵活。 开发调试上&#xff0c;有时候需要进行对…

深度学习笔记——循环神经网络RNN

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络RNN知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型&#xff08;Bag of Words, BOW&#xff09;工作原…

.NET周刊【1月第1期 2025-01-05】

国内文章 3款.NET开源、功能强大的通讯调试工具&#xff0c;效率提升利器&#xff01; https://www.cnblogs.com/Can-daydayup/p/18631410 本文介绍了三款功能强大的.NET开源通讯调试工具&#xff0c;旨在提高调试效率。这些工具包括LLCOM&#xff0c;提供串口调试和自动化处…

AT8870单通道直流电机驱动芯片

AT8870单通道直流电机驱动芯片 典型应用原理图 描述 AT8870是一款刷式直流电机驱动器&#xff0c;适用于打印机、电器、工业设备以及其他小型机器。两个逻辑输入控制H桥驱动器&#xff0c;该驱动器由四个N-MOS组成&#xff0c;能够以高达3.6A的峰值电流双向控制电机。利用电流…

创建 pdf 合同模板

创建 pdf 合同模板 一、前言二、模板展示三、制作过程 一、前言 前段时间要求创建“pdf”模板&#xff0c;学会了后感觉虽然简单&#xff0c;但开始也折腾了好久&#xff0c;这里做个记录。 二、模板展示 要创建这样的模板 三、制作过程 新建一个“Word”&#xff0c;这里命…

【Go】Go数据类型详解—指针

1. 前言 在我看来&#xff0c;一门编程语言语法的核心就在于数据类型。而各类编程语言的基本数据类型大致相同&#xff1a;int整型、float浮点型、string字符串类型、bool布尔类型&#xff0c;但是在一些进阶数据类型上就有所不同了。本文将会介绍Go语言当中核心的数据类型——…

CSS 圆形头像和破图时显示默认图片

一、需求 1、css实现圆形头像 2、破图是显示默认图片 二、实现 <img :src"photoSrc" class"circle-avatar" :width"size" :height"size" error"handleImageError" //破图时使用的方法 > <style> .circl…

SpringBoot+Vue小区智享物业管理系统(高质量源码,可定制,提供文档,免费部署到本地)

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

jenkins-视图管理

一. 简述&#xff1b; jenkins默认只有一个All的view&#xff0c; 在我们线上环境中(测试、预发布、线上、端、语言环境等)&#xff0c;显然是不合理的(放在一个view中不编译管理)。我们可以通过一个dashboard view的插件来进行多个view(按环境&#xff0c;业务等分隔均可)管理…

Transformer详解:Attention机制原理

前言 Hello&#xff0c;大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者&#xff0c;本系列文章是作者参加DataWhale2025年1月份学习赛&#xff0c;旨在讲解Transformer模型的理论和实践。&#x1f632; 本文将详细探讨Attention机制的原理…

PHP变量

目录 变量的定义 预定义变量 $_SERVER $_GET $_POST $_REQUEST $_COOKIE $_SESSION $_FILES 变量作用域 global 关键字 static 变量 可变变量 完结 上一篇文章已经学习了PHP的数据类型&#xff0c;今天将学习新的内容&#xff1a;变量。 变量的定义 PHP 中变量…

四、CSS效果

一、box-shadow box-shadow:在元素的框架上添加阴影效果 /* x 偏移量 | y 偏移量 | 阴影颜色 */ box-shadow: 60px -16px teal; /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影颜色 */ box-shadow: 10px 5px 5px black; /* x 偏移量 | y 偏移量 | 阴影模糊半径 | 阴影扩散半…

STM32 FreeRTOS 事件标志组

目录 事件标志组简介 基本概念 1、事件位&#xff08;事件标志&#xff09; 2、事件组 事件组和事件位数据类型 事件标志组和信号量的区别 事件标志组相关API函数介绍 事件标志组简介 基本概念 当在嵌入式系统中运行多个任务时&#xff0c;这些任务可能需要相互通信&am…

【网络原理】万字详解 HTTP 协议

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. HTTP 前置知识1.1 HTTP 是什么1.2 HTPP 协议应用场景1.3 HTTP 协议工作过程 2. HTTP 协议格式2.1 fiddler…

打造餐饮品牌的产品矩阵:美味与策略的完美融合-中小企实战运营和营销工作室博客

打造餐饮品牌的产品矩阵&#xff1a;美味与策略的完美融合-中小企实战运营和营销工作室博客 在竞争激烈的餐饮市场中&#xff0c;打造一个成功的餐饮品牌&#xff0c;关键在于构建一个强大且富有吸引力的产品矩阵。这不仅涉及到研发出令人垂涎欲滴的美味佳肴&#xff0c;更需要…

[Qt] Box Model | 控件样式 | 实现log_in界面

目录 1、样式属性 &#xff08;1&#xff09;盒模型&#xff08;Box Model&#xff09; 2、控件样式示例 &#xff08;1&#xff09;按钮 &#xff08;2&#xff09;复选框 &#xff08;3&#xff09;单选框 &#xff08;4&#xff09;输入框 &#xff08;5&#xff09…

【LangChain】Chapter10 - Retrieval

说在前面 上一节&#xff0c;我们介绍了语义搜索的基础知识&#xff0c;并做了一些实践案例,可以看到在有些情况下效果不错&#xff0c;但同时也能看到存在一些边缘情况。本节将介绍 检索&#xff08;Retrieval&#xff09;以及讲解一些解决这些边缘案例的高级方法。&#xff…