PDF页面倒序

今天遇到一个问题,把项目资料扫描电子版归档,扫描完后发现某个资料排序是从最新到最旧,想着如何倒序排列。尝试了几个常用的PDF阅读器,没发现类似的功能,于是尝试用python来实现。

import fitz  # PyMuPDF
import os
#定义函数
def reverse_pdf_order(input_pdf_path, output_pdf_path):
    source_pdf = fitz.open(input_pdf_path)  # 打开pdf
    reversed_pdf = fitz.open()  # 新建pdf

    # Iterate through the pages in reverse order
    for page_number in range(source_pdf.page_count - 1, -1, -1):
        # 插入页面
        reversed_pdf.insert_pdf(source_pdf, from_page=page_number, to_page=page_number)

    reversed_pdf.save(output_pdf_path)  # 保存生成的pdf
    source_pdf.close()  # 关闭输入pdf
    reversed_pdf.close()  # 关闭生成的pdf

folder = 'd:/Desktop/' #指定工作目录
os.chdir(folder)       #切换到工作目录
input = 'input.pdf'    #需要调整页面顺序的文件
reverse_pdf_order(input, 'reversed_' + input) #生成文件

当然,可以改造代码批量转换,就不多说了。

批量汇总多个dwg文件的材料标准并汇总成物料表

以下为代码,并都进行了标注。

# 导入必要的包
import pyautocad as pc
import numpy as np
from pathlib import Path
import win32com.client
import pythoncom
import time
import pandas as pd
import subprocess
#定义函数
def material_extraction(file_path):
    dwg_files = Path(file_path).glob('*.dwg') #获取所有dwg文件
    material_dict = {} #创建空字典
    for dwg_file in dwg_files: #遍历所有dwg文件
        acad= win32com.client.gencache.EnsureDispatch("AutoCAD.Application") #调用AutoCAD
        print(f'Openning {dwg_file}') #打印打开的文件名
        doc2 = acad.Documents.Open(dwg_file) #打开cad文件
        time.sleep(5) #休眠5秒钟,避免打开时间过长
        model = doc2.ModelSpace #获取模型空间
        pyacad = pc.Autocad(create_if_not_exists = True) #创建一个新的pyautocad对象
        model_space = pyacad.model #获取模型空间
        uptext = [] #创建空列表
        try: #尝试执行下面的代码
            for obj in pyacad.iter_objects_fast('TDbSymbMultiLeader',container=model_space): #遍历模型空间中的所有TDbSymbMultiLeader对象
                uptext.append(obj.uptext) #将uptext属性添加到uptext列表中
            material_dict[doc2.Name] = tuple(set(uptext)) #将文件名作为key,uptext列表作为value,添加到material_dict字典中
        except: #如果上面的代码执行失败,执行下面的代码
            print(f'{dwg_file}  failed') #打印失败的文件名
        doc2.Close() #关闭文件
    df = pd.DataFrame.from_dict(material_dict,orient='index').T #将material_dict字典转换为DataFrame对象
    df.to_csv(Path(file_path)/'物料表.csv',encoding='gb2312') #将DataFrame对象转换为csv文件
    print(f'打开项目文件夹:{file_path}') #打印打开的文件路径
    subprocess.Popen(f'explorer {file_path}') #打开文件路径
file_path = Path.cwd() #设置文件路径
material_extraction(file_path) #调用函数

我要忽悠大家学Python了

近年来,各种培训机构、公众号,都在呼吁大家学python,演示了各种花哨的功能,看着都很高大上的样子,然并卵,跟我们实际工作没有太大的关系。

        本人学Python很长时间了,主要用于处理GIS数据,自动化航拍处理流程,研究深度学习这些工作,虽然是未来设计的必然趋势,但是跟我们目前的日常工作关系也不大,因此就没有忽悠大家学Python。

        不过近期通过Python解决了一些我们日常工作的小问题,想拿出来聊聊,做成一个系列的文章,看看能否把大家忽悠瘸了。

        今天先拿一个很简单的案例来忽悠:

        项目做到一半,来了一版新的测绘图,发现标高变了,统一抬高或者降低了一定的高程,怎么办?总平竖向都定好了,标注了几百个标高,让我怎么改?查找替换?能实现增加前缀后缀这些,但是实现不了数字加减一定的值。

        相信很多人遇到过类似的问题,怎么解决?Python。

        用PyAutocad包即可实现这一目的,下面是代码:

#导入包,创建autocad实例
from pyautocad import Autocad,APoint
acad = Autocad(create_if_not_exists = True)
acad.prompt('Hello,Autocad from Python\n')
#循环所有天正标高,所有标高数字都增加10000
for obj in acad.iter_objects('TDbSymbElevation'):
    t = obj.Text
    if t.endswith('&%%P0.000'):
        obj.Text = obj.Text.replace('&%%P0.000','')
    if t.endswith('.'):
        obj.Text = obj.Text.replace('.','')
    obj.Text = str(float(obj.Text) + 10000)

        运行,效果如下:

        So easy,你会读了么?

补充:在本文发布后,有好多小伙伴发来消息,整理如下:

1、通过动态标注,移动所有标高,即可调整标高数值,何苦还要写代码?

回复:这就跟那个段子一个道理:如何检查空箱子?博士研究各种探测装置,工人用大风扇吹。貌似用风扇简单省事,研究探测装置纯粹浪费,但是一旦条件发生变化,简单的方法就会失效了,而高科技探测装置调整一下参数还可以达到目的。比如,检查的不是空箱子,而是没装满的箱子,你的大风扇还能吹走么?

具体到这个案例来,就是我们景观设计的标高往往习惯标注一些前缀:TW(Top of wall,墙顶标高),FL(Finish Level,完成面标高),你试试有了这些前缀后,你再开启动态标准,移动标高标注还有用么?这段代码我可以再增加个判断,先拆离前缀,最后在组合起来就可以了,能够根据需求,完成各种复杂的操作。

2、能否只局部抬高或者降低?

回复:可以的,有get.selection(),可以只对选中的部分进行操作。调整代码封装为函数,可以很方便的调整高程的增量,快速应用到不同的区域。

3、那么快做完 ,下面的人画什么呢?

回复:写代码只是解决简单重复的劳动,需要创意的工作还是要靠人来进行,因此不会影响设计师的成长。相反,从简单重复的劳动中解脱出来,更多的世界来思考设计,更有利于设计师的成长。

跟随教程练习的Python小小小程序

sercet_word = "test"
guess = ""
guess_count = 0
guess_limit = 3
out_of_guesses = False
while guess != sercet_word and not out_of_guesses:
    if guess_count < guess_limit:
       guess = input("Guess the word: ")
       guess_count += 1
    else:
        out_of_guesses = True
if out_of_guesses:
    print("Out of guesses,You lose!")
else:
    print("You Win!")

跟随教程练习了这么一个小程序,将if、loop、input等都运用上了,虽然很简单,但是尽量让自己的思维方式与程序员靠近。