用Python自动获取PDF图纸的图纸大小,并依此分类整理

在建筑行业,设计师用CAD设计完建筑图纸后,常常需要上传到市、省二级图审平台上,故需要将每张图纸转成PDF文档,并盖电子章(出图章、建造师章和结构章),然后上传图审系统。如果设计师在CAD转PDF时没标明图幅大小(A0,A1,A3,A4?),盖章的人就不得不一张张地打开来查看并盖章,没办法用“批量盖章”的方式。由于图纸量大,往往累成狗。

电子章要批量盖章的前提条件就是:同一批图纸的图幅是相同的,这样,电子章盖在相同的地方才不会错位。

为了解决这个问题,我用Python编了一个脚本,它可以自动识别PDF文档的尺寸(size),也就是“图幅”,并将相同图幅的PDF文档归纳到同一个目录中,以方便批量盖电子章。

该代码经多次实践,方便可靠。

以下是源代码:

'''第一步:
批量获取PDF文档的第一页的页面大小,并将其添加到该PDF文档文件名的最后面
'''
#打开PDF图纸所在的文件夹,将其文件路径复制到剪贴板中
#先指定要处理的图纸目录,注意:反斜杠“\“要改为斜杠"/"

#------------------将复制在剪贴板中的文件路径中的“\”替换成"/",并重新复制到剪贴板中------------------
import pyperclip

# 获取剪贴板中的文本
file_path = pyperclip.paste()

# 将 "\\" 替换为 "/"
file_path = file_path.replace("\\", "/")

# 将修改后的文本复制到剪贴板
pyperclip.copy(file_path)

#将修改后的文件夹路径赋予变量
目录 = pyperclip.paste()
#------------------

import os
import fitz  # PyMuPDF库

def get_pdf_page_sizes(pdf_path):
    page_sizes = {}
    try:
        doc = fitz.open(pdf_path)
        for page_num in range(doc.page_count):
            page = doc[page_num]
            width = page.rect.width  # 获取页面宽度
            height = page.rect.height  # 获取页面高度
            size = (width, height)
            page_sizes.setdefault(size, []).append(page_num + 1)  # 将页面大小和页码添加到字典中
    except Exception as e:
        print(f"Error processing {pdf_path}: {e}")
    finally:
        if doc:
            doc.close()
    return page_sizes

def rename_files_with_page_size(pdf_folder):
    # 遍历文件夹中的所有PDF文件
    for filename in os.listdir(pdf_folder):
        if filename.endswith(".pdf"):
            pdf_path = os.path.join(pdf_folder, filename)
            print(f"Processing {pdf_path}...")
            page_sizes = get_pdf_page_sizes(pdf_path)
            for size, pages in page_sizes.items():
                if len(pages) > 0:  # 如果有页面大小信息
                    # 构建新的文件名
                    new_filename = f"{os.path.splitext(filename)[0]}_Page_{pages[0]}_Size_{size[0]}x{size[1]}.pdf"
                    new_path = os.path.join(pdf_folder, new_filename)
                    # 重命名文件
                    try:
                        os.rename(pdf_path, new_path)
                        print(f"Renamed {filename} to {new_filename}")
                    except Exception as e:
                        print(f"Error renaming {filename} to {new_filename}: {e}")

# 指定包含PDF文件的文件夹路径
pdf_folder_path = 目录

# 将“Page 1 Size:”后面的内容添加到原文件名的最后面(重命名文件)
rename_files_with_page_size(pdf_folder_path)

#------------------------------------------------------------------------------------------------
'''第二步:
将文件名后面从“Page_1_Size_"开始到后缀名之前的内容相同的文件(就是页面大小相同的文件)归类到同一目录
'''
import os
import shutil

def move_files_with_common_part(directory):
    # 获取目录中的所有文件
    files = [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]

    # 创建字典来存储共同部分和目标目录的对应关系
    common_parts = {}

    for file_name in files:
        # 查找文件名中的共同部分
        start_index = file_name.find("Page_1_Size_") + len("Page_1_Size_")
        end_index = file_name.find(".", start_index)
        common_part = file_name[start_index:end_index]

        # 构建目标目录路径
        target_directory = os.path.join(directory, common_part)

        # 创建目录(如果不存在)
        if not os.path.exists(target_directory):
            os.makedirs(target_directory)

        # 构建原文件路径和目标文件路径
        source_path = os.path.join(directory, file_name)
        target_path = os.path.join(target_directory, file_name)

        # 移动文件到目标目录
        shutil.move(source_path, target_path)
        print(f"移动文件: {file_name} -> {target_path}")

        # 更新字典中的目标目录路径
        common_parts[common_part] = target_directory

    # 输出每个共同部分的目标目录路径
    for common_part, target_directory in common_parts.items():
        print(f"共同部分: {common_part},目标目录: {target_directory}")

if __name__ == "__main__":
    # 指定目录路径
    target_directory = 目录

    # 调用函数移动具有相同共同部分的文件
    move_files_with_common_part(target_directory)

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

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

相关文章

react09 hooks(useState)

react-09 hooks(useState) hooks组件(函数组件动态化) 其本质就是函数组件,引用一些hooks方法,用来在函数组件中进行例如状态管理,模拟类组件的生命周期等,只能运用到函数组件中 ho…

基于MaxKB搭建一个知识库问答系统

什么是MaxKB MaxKB 是一款基于 LLM 大语言模型的知识库问答系统。MaxKB Max Knowledge Base,旨在成为企业的最强大脑。 开箱即用:支持直接上传文档、自动爬取在线文档,支持文本自动拆分、向量化,智能问答交互体验好&#xff1b…

DHCP Relay配置与抓包

前言:DHCP请求报文是以广播包方式发送的,当DHCP服务器与DHCP客户端不在同一网段时,就需要在三层网关设备配置DHCP中继功能 。 为能更好理解DHCP Relay功能,建议先看看DHCP Server的内容 https://blog.csdn.net/weixin_58574637…

【Java框架】SpringMVC(三)——异常处理,拦截器,文件上传,SSM整合

目录 异常处理解释局部异常处理全局异常 拦截器拦截器介绍作用:拦截器和过滤器之间的区别拦截器执行流程代码实现补充 文件上传依赖配置MultipartResolver编写文件上传表单页APIMultipartFileFile.separator必须对上传文件进行重命名代码示例 SpringMVC文件上传流程多文件上传 …

你知道吗?PCBA产品上市前还需要进行老化测试?

在PCBA加工过程中,电子工程师可能发现明明PCBA板出货时各项功能指标正常,但使用一段时间,就莫名其妙出现各种不良问题,最后返场维修,那么这是为什么? 首先,这些原因,十有八九可能是P…

谷歌开发者账号关联被封?解封申诉指南来了!

相信大部分在谷歌上架应用的开发者,已经被谷歌封号封麻了。且不少开发者普遍认为,一旦开发者账号被封禁,想要成功申诉回来的难度极大。 特别是那些因为涉及“高风险”滥用模式行为关联被封的账号,更是不可能申诉成功。但事实上&am…

再谈C语言——理解指针(五)(完结篇)

数组名的理解 在上⼀个章节我们在使⽤指针访问数组的内容时,有这样的代码: int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址&#xf…

【产品经理修炼之道】- 将用户需求转化为研发需求

每当接到一个用户需求,产品经理头疼的事情之一,可能就是如何把用户需求转化成研发需求。怎么理解二者的区别,并成功地将需求转化呢?这篇文章里,作者做了分享与总结,一起来看一下。 产品经理与研发人员的博弈…

【图像分割】光流生成标签(matlab)

文章目录 1. 框架2. opticalFlow_label3. 光流 1. 框架 2. opticalFlow_label close all; clear; clc; % 使用光流进行标签的生成 %% 视频帧的读取 npy_data readNPY(train.npy);%% 提取标签的坐标 first_label squeeze(npy_data(2,1,:,:)); h fspecial("gaussian&quo…

C语言自定义类型【结构体】

结构体的概念 结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量。 1.结构体的声明 1.1普通声明 我们假设要创建一本书的类型,那我们需要书名,作者,价格,书的ID 代码如下:…

第十五届蓝桥杯省赛第二场C/C++B组A题【进制】题解(AC)

解题思路 按照题意进行模拟&#xff0c;计算 x x x 的 b b b 进制过程中&#xff0c;若出现余数大于 9 9 9&#xff0c;则说明 x x x 的 b b b 进制一定要用字母进行表示。 #include <iostream> #include <cstring> #include <algorithm> #include &l…

vue3推荐算法

Vue 3 推荐算法主要指的是在 Vue 3 框架中实现的或者适用于 Vue 3 的算法库或组件库。Vue 3 由于其优秀的设计和性能&#xff0c;被广泛应用于构建各种类型的应用程序&#xff0c;包括需要复杂算法支持的项目。以下是一些在 Vue 3 中可能会用到的推荐算法资源&#xff1a; Vue-…

啊? 又要洗数据啦!! 还是两个key决定一个表! 二维Map学习,基于guava的HashBasedTable

一个洗数据的需求&#xff0c;表设计的外建不能判断某一个数据源&#xff0c;还要根据tyoe来进行判断才可以。 那此时呆逼的查发能实现但不够优雅&#xff0c;于是乎想到了二维数组&#xff0c;查了下资料有相关的实现给大家分享下&#xff01;&#xff01; 背景 表设计如下&a…

美易官方:AI热潮“熄火”了?Meta Q1财报较差

近期&#xff0c;随着Meta&#xff08;前Facebook&#xff09;发布了其2023年第一季度的财报&#xff0c;一场科技股的震荡在美股市场上演。曾经风光无限的AI热潮似乎出现了“熄火”的迹象&#xff0c;引发了市场的广泛关注和讨论。 Cresset Wealth Advisors首席投资官Jack Abl…

libVLC 专栏介绍

本专栏主要界面libVLC的使用&#xff0c;详细介绍了相关用法&#xff0c;使用Qt作为显示界面&#xff0c;不仅可以了解Qt的使用&#xff0c;QSS的美化&#xff0c;更能够熟悉libVLC核心接口的使用&#xff0c;最后打造一款属于自己的精美播放器。 每一节都有单独的源码供查看。…

CSS @media 媒体查询全解:打造极致跨平台页面的动态户体体验

随着互联网设备的多样化和用户浏览习惯的变化&#xff0c;现代网页设计越来越注重提供跨平台、跨设备的无缝用户体验。CSS媒体查询media在此背景下扮演着至关重要的角色&#xff0c;它赋予网页设计者精准控制网页样式的能力&#xff0c;使之能随设备环境变化而动态调整&#xf…

内存管理下及模板初阶

嗨喽&#xff0c;今天阿鑫给大家带来内存管理下以及模板初阶的博客&#xff0c;下面让我们开始今天的学习吧&#xff01; 内存管理下及模板初阶 new和delete的实现原理定位new表达式(placement-new)常见面试题泛型编程函数模板类模板 1. new和delete的实现原理 1.1 内置类型…

短链接推荐:一个可以监测用户行为的“营销神器”

客户对我的推广有兴趣吗&#xff1f;他喜欢我的产品吗&#xff1f;他打开了我的营销信息吗&#xff1f;这三个问题相信每一位推广者都遇到过。接下来&#xff0c;就将给大家介绍一位大聪明——它能帮你监测每一位用户的行为&#xff0c;让你分分秒秒掌握用户的心理&#xff01;…

consul服务注册与发现、服务配置与刷新

为什么要用服务注册&#xff1f;为什么要用consul不用eureka&#xff1f; 举个栗子&#xff1a; 微服务当中存在多个服务模块&#xff0c;每个服务模块的ip端口在每套环境是不一致的&#xff0c;开发切换环境部署时&#xff0c;如果漏了一个配置忘记改动&#xff0c;将是一个很…

黑龙江—等保测评三级安全设计思路

需求分析 6.1、 系统现状 6.2、 现有措施 目前&#xff0c;信息系统已经采取了下述的安全措施&#xff1a; 1、在物理层面上&#xff0c; 2、在网络层面上&#xff0c; 3、在系统层面上&#xff0c; 4、在应用层面上&#xff0c; 5、在管理层面上&#xff0c; 6.…