好久没发文了,转眼已经2024年了,我的电脑已经八岁了,近来状况频发,为防止它哪天突然嘎嘣,我多年搜集的资料付诸东流,故决定把资料备份一下这些代码有的是原创,有的是借鉴了其他博主的文章,是平时工作生活里面比较常用的,但因为是作者在不同时期做的,所有编写水平也是在变化的。因主要目的是备份,所以没有那么详细的注释,各位看官多担待咯
写在前面,运行提示缺少什么库就pip什么库,*代表库名pip install *
目录
- PDF_TO_IMAGE
- PDF_TO_WORD
- PDF解密
- PPT_TO_IMAGE
- PPT_TO_PDF
- WORD_TO_PDF
- 批量合并PDF
- 批量裁剪图片
- 批量解压缩zip文件
- 批量压缩文件
- 批量新建文件夹
- 批量移动文件到同名文件夹下
- 批量转换文件编码格式
PDF_TO_IMAGE
应用场景:把pdf格式的文件转成一张张的图片格式,稍微改一改就能实现批量转换的功能
import fitz
import glob
import os
'''
# 将PDF转化为图片
pdfPath pdf文件的路径
imgPath 图像要保存的文件夹
zoom_x x方向的缩放系数
zoom_y y方向的缩放系数
rotation_angle 旋转角度
'''def pdf_image(pdfPath, zoom_x, zoom_y, rotation_angle):# 打开PDF文件pdf = fitz.open(pdfPath)imgPath = pdfPath.split(".")[0]if not os.path.exists(imgPath):os.mkdir(imgPath)# 逐页读取PDFfor pg in range(0, pdf.page_count):page = pdf[pg]# 设置缩放和旋转系数trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotation_angle)pm = page.get_pixmap(matrix=trans, alpha=False)# 开始写图像pm.save(imgPath + '\\' + str(pg) + ".png")pdf.close()
def Run():for pdf_file in glob.glob(r"【这里换成你的文件夹地址】\*.pdf"):pdf_image(pdf_file,10,10,0)print(f'{pdf_file}转换图片已完成!')
if __name__ == '__main__':pdf_image(r'【这里换成你的文件夹地址】\*.pdf',10,10,0)
PDF_TO_WORD
应用场景:批量把pdf格式的文件转换成word格式
import glob
from pdf2docx import Converter# 获取当前目录下的所有PDF文件
pdf_files = glob.glob('*.pdf')# 遍历PDF文件,并转换为Word
for pdf_path in pdf_files:word_path = pdf_path[:-4] + '.docx'cv = Converter(pdf_path)cv.convert(word_path, start=0, end=None)cv.close()print(f"Converted {pdf_path} to {word_path}")print("All PDF files have been converted to Word.")
PDF解密
应用场景:PDF加密后忘记了密码
from PyPDF2 import PdfReader # pdf的读取方法
from PyPDF2 import PdfWriter # pdf的写入方法
from Crypto.Cipher import AES # 高加密的方法,要引入不然会报错def get_reader(filename, password): # 读取pdf的方法(自定义函数)try:old_file = open(filename, 'rb')print('解密开始...')except Exception as err:return print('文件打开失败!' + str(err))# 如果是python2将PdfReader改为PdfFileReaderpdf_reader = PdfReader(old_file, strict=False) # 读取pdf文件# 如果是python2将is_encrypted改为isEncryptedif pdf_reader.is_encrypted: # 解密操作(以下操作是自适应,不会展示在终端中)if password is None:return print('文件被加密,需要密码!--{}'.format(filename))else:if pdf_reader.decrypt(password) != 1:return print('密码不正确!--{}'.format(filename))elif old_file in locals():old_file.close() # 如果pdf文件已经在本地了就关闭return pdf_reader # 返回读出pdf的值def deception_pdf(filename, password, decrypted_filename=None): # 生成新pdf的方法(自定义函数)print('正在生成解密...')pdf_reader = get_reader(filename, password) # 得到传入的文件名,和密码(如果密码没有可以不填)if pdf_reader is None:return print("无内容读取")# 如果是python2将is_encrypted改为isEncryptedelif not pdf_reader.is_encrypted:return print('文件没有被加密,无需操作')# 如果是python2将PdfWriter改为PdfFileWriterpdf_writer = PdfWriter() # 写pdf(记录pdf内容)# 如果是python2将append_pages_from_reader改为appendPagesFromReaderpdf_writer.append_pages_from_reader(pdf_reader)if decrypted_filename is None: # 创建解密后的pdf文件和展示文件的路径decrypted_filename = "".join(filename.split('.')[:-1]) + '_' + '已解密' + '.pdf'print("解密文件已生成:{}".format(decrypted_filename))# 写入新文件pdf_writer.write(open(decrypted_filename, 'wb'))if __name__ == '__main__':# 逗号前面的为需要解密的pdf文件路径,后面的''里面为密码,如果不知道就用不填deception_pdf(r'【这里换成你的文件夹地址】.pdf', '')
PPT_TO_IMAGE
应用场景:批量把ppt转换成一张一张的图片
# -*- coding: UTF-8 -*-
import os
import sysdef get_all_ppts(path):# 获取所有 ppt 文件ppt_paths = []for root, _, files in os.walk(path):for f in files:suffix = os.path.splitext(f)[-1].lower()if 'ppt' in suffix:ppt_paths.append(os.path.join(root, f))return ppt_pathsclass LinuxConverter():'''Linux 平台下转换工具借助 libreoffice 和 imagemagick'''def _run_cmd(self, cmd):try:os.system(cmd)except Exception as e:print('[ERROR] ', e)return Falseelse:return Truedef _ppt_to_imgs(self, ppt_path):# ppt - pdf - jpg# libreoffice 多进程会卡死,后续优化cmd = 'libreoffice --headless --language=zh-CN 'cmd += '--convert-to pdf {}>>/dev/null'.format(ppt_path)success = self._run_cmd(cmd)if not success:print('[ERROR] ppt2pdf: {}'.format(ppt_path))return successsuffix = os.path.splitext(ppt_path)[-1]pdf_path = ppt_path.replace(suffix, 'pdf').split('/')[-1]success, _ = self._pdf_to_imgs(pdf_path)if not success:print('[ERROR] pdf2imgs: {}'.format(ppt_path))return successdef _pdf_to_imgs(self, pdf_path):imgs_folder = os.path.splitext(pdf_path)[0]cmd = 'mkdir {}'.format(imgs_folder)success = self._run_cmd(cmd)if not success:print('[ERROR] mkdir: {}'.format(pdf_path))return success, ''cmd = 'convert {} {}/幻灯片%d.JPG'.format(pdf_path, imgs_folder)success = self._run_cmd(cmd)return success, imgs_folderdef convert(self, ppts_path_list, total_count):error_count = 0success_count = 0for idx in range(total_count):ppt_path = ppts_path_list[idx]print('[ {}/{} ] {}'.format(idx + 1, total_count, ppt_path))success, _ = self._ppt_to_imgs(ppt_path)if not success:error_count += 1continuesuccess_count += 1return error_count, success_countclass WinConverter():'''Windows 平台下转换工具借助 office PowerPoint'''def __init__(self):try:# 必须以该形式导入 `from win32com import client` 会报错import win32com.clientexcept ImportError:print('当前为windows平台,缺少 win32com 库,请执行 `pip install pywin32` 安装')exit(0)self._ppt_engine = win32com.client.Dispatch('PowerPoint.Application')self._ppt_engine.Visible = Truedef _ppt2jpg(self, ppt_path, imgs_path):ppt_path = os.path.abspath(ppt_path)imgs_path = os.path.abspath(imgs_path)try:ppt = self._ppt_engine.Presentations.Open(ppt_path)ppt.SaveAs(imgs_path, 18) # 17:jpg, 18:png, 19:bmpppt.Close()except Exception as e:print('[ERROR] ppt2imgs: {}'.format(ppt_path))return Falseelse:return Truedef convert(self, ppts_path_list, total_count):error_count = 0success_count = 0for idx in range(total_count):ppt_path = ppts_path_list[idx]print('[ {}/{} ] {}'.format(idx + 1, total_count, ppt_path))suffix = os.path.splitext(ppt_path)[-1]imgs_path = ppt_path.replace(suffix, '.png')success = self._ppt2jpg(ppt_path, imgs_path)if not success:error_count += 1continuesuccess_count += 1self._ppt_engine.Quit()return error_count, success_countdef convert_ppts_to_imgs(path):if os.path.isdir(path):ppts_path_list = get_all_ppts(path)elif os.path.isfile(path):ppts_path_list = [path]if not ppts_path_list:print('该路径下未找到 ppt 文件')exit(0)plat = sys.platformif 'linux' in plat:converter = LinuxConverter()elif 'win' in plat:converter = WinConverter()total_count = len(ppts_path_list)print('[BEGIN] 共 {} 个 ppt 文件'.format(total_count))error_count, success_count = converter.convert(ppts_path_list, total_count)print('[END] error:{} success:{}'.format(error_count, success_count))if __name__ == '__main__':path = '【这里换成你的文件夹地址】'convert_ppts_to_imgs(path)
PPT_TO_PDF
应用场景:批量把PPT格式的文件转换成PDF格式的文件
# 1). 导入需要的模块(打开应用程序的模块)
import win32com.client
import osdef ppt2pdf(filename, output_filename):"""PPT文件导出为pdf格式:param filename: PPT文件的名称:param output_filename: 导出的pdf文件的名称:return:"""# 2). 打开PPT程序ppt_app = win32com.client.Dispatch('PowerPoint.Application')# ppt_app.Visible = True # 程序操作应用程序的过程是否可视化# 3). 通过PPT的应用程序打开指定的PPT文件# filename = "C:/Users/Administrator/Desktop/PPT办公自动化/ppt/PPT素材1.pptx"# output_filename = "C:/Users/Administrator/Desktop/PPT办公自动化/ppt/PPT素材1.pdf"ppt = ppt_app.Presentations.Open(filename)# 4). 打开的PPT另存为pdf文件。17数字是ppt转图片,32数字是ppt转pdf。ppt.SaveAs(output_filename, 32)print("导出成pdf格式成功!!!")# 退出PPT程序ppt_app.Quit()# 要处理的目录名称
# dirname = 'D:/Study/Old课程/单片机/单片机课件/try'
dirname = os.getcwd() # 获取当前目录
# 列出指定目录的内容
filenames = os.listdir(dirname)
# for循环依次访问指定目录的所有文件名
for filename in filenames:# 判断文件的类型,对所有的ppt文件进行处理(ppt文件以ppt或者pptx结尾的)if filename.endswith('ppt') or filename.endswith('pptx'):# print(filename) # PPT素材1.pptx -> PPT素材1.pdf# 将filename以.进行分割,返回2个信息,文件的名称和文件的后缀名base, ext = filename.split('.') # base=PPT素材1 ext=pdfnew_name = base + '.pdf' # PPT素材1.pdf# ppt文件的完整位置: C:/Users/Administrator/Desktop/PPT办公自动化/ppt/PPT素材1.pptxfilename = dirname + '/' + filename# pdf文件的完整位置: C:/Users/Administrator/Desktop/PPT办公自动化/ppt/PPT素材1.pdfoutput_filename = dirname + '/' + new_name# 将ppt转成pdf文件ppt2pdf(filename, output_filename)
WORD_TO_PDF
应用场景:批量把word文档转换成pdf格式的文件
from win32com.client import constants, gencache
import os
import fitz
import tkinter as tk
from tkinter import filedialog
import msvcrtpdf_dir = []
Word_files = []def get_file():root = tk.Tk()root.withdraw()# 想要选中文件的,可以使用这个方法直接获取文件路径dir_path = filedialog.askdirectory(initialdir='./')# print("dir_path:"+dir_path)docunames = os.listdir(dir_path)for file in docunames:print("file:" + file)# 找出所有后缀为doc或者docx的文件if file.endswith(('.doc', '.docx')):Word_files.append(file)print(Word_files)for file in Word_files[88:90]:file_path = os.path.abspath(dir_path + "/" + file)index = file_path.rindex('.')pdf_path = file_path[:index] + '.pdf'Word_to_Pdf(file_path, pdf_path)# Word转pdf方法,第一个参数代表word文档路径,第二个参数代表pdf文档路径
def Word_to_Pdf(Word_path, Pdf_path):print("Word_path:" + Word_path)print("Pdf_path:" + Pdf_path)word = gencache.EnsureDispatch('Word.Application')doc = word.Documents.Open(Word_path)# 转换方法doc.ExportAsFixedFormat(Pdf_path, constants.wdExportFormatPDF)word.Quit()if __name__ == '__main__':get_file()
批量合并PDF
应用场景:当你有多个连续的pdf想要合并成为一个的时候
import os
from PyPDF2 import PdfFileReader, PdfFileWriterdef GetFileName(dir_path):file_list = [os.path.join(dirpath, filesname) \for dirpath, dirs, files in os.walk(dir_path) \for filesname in files]return file_listdef MergePDF(dir_path, file_name):output = PdfFileWriter()outputPages = 0file_list = GetFileName(dir_path)for pdf_file in file_list:print("文件:%s" % pdf_file.split('\\')[-1], end=' ')# 读取PDF文件input = PdfFileReader(open(pdf_file, "rb"))# 获得源PDF文件中页面总数pageCount = input.getNumPages()outputPages += pageCountprint("页数:%d" % pageCount)# 分别将page添加到输出output中for iPage in range(pageCount):output.addPage(input.getPage(iPage))print("\n合并后的总页数:%d" % outputPages)# 写入到目标PDF文件print("PDF文件正在合并,请稍等......")with open(os.path.join(dir_path, file_name), "wb") as outputfile:# 注意这里的写法和正常的上下文文件写入是相反的output.write(outputfile)print("PDF文件合并完成")if __name__ == '__main__':# 设置存放多个pdf文件的文件夹dir_path = r'【这里换成你的文件夹地址】'# 目标文件的名字file_name = "【这里换成你的文件夹地址】.pdf"MergePDF(dir_path, file_name)
批量裁剪图片
应用场景:当你需要批量裁剪图片时
from PIL import Image
import os,datetimedef Cut(file_path):now = datetime.datetime.now().strftime('%Y_%m_%d')if not os.path.exists(f'./cut_{now}'):os.mkdir(f'./cut_{now}')filename = file_path.split('\\')[-1].split('.')[0]pic = Image.open(file_path)box = (0, 0, pic.size[0], pic.size[1] / 2)new_pic = pic.crop(box)new_pic.save(f'./cut_{now}/{filename}_300.jpg')print(f'{file_path}裁剪_300 成功')returnif __name__ == '__main__':import globfor file in glob.glob(r'【这里换成你的文件夹地址】\*'):Cut(file)
批量解压缩zip文件
应用场景:当你有大量的zip压缩包需要解压时
import os
import shutil
import zipfile# 首先引入需要的工具包
# shutil为后期移动文件所需,可以忽略此项
# 路径改这里!
# parent_path = r'输入路径,会解压该路径下的所有zip压缩文件'
parent_path = r'【这里换成你的文件夹地址】'
# 文件类型选择
# 可以自行更改压缩文件类型,需要引入其它工具包,如tarfile等
# 这里是因为在自己的windows上,zip比较常见,其他类型请自行更改
file_flag = '.zip' # 修改需解压的格式 例如:.rar# 删除已解压的zip文件
# 不建议初次使用,在确定程序无误后可以添加使用
def del_old_zip(file_path):os.remove(file_path)# 解压
def decompress(file_path, root):# 开始# zipfile打开zip文件z = zipfile.ZipFile(f'{file_path}', 'r')# 解压z.extractall(path=f"{root}") # path为解压路径,解包后位于该路径下# 判断是否需要重复解包for names in z.namelist():if names.endswith(file_flag):z.close()return 1# 结束z.close()return 0# 因为我在使用过程中发现有些zip解包后会混在一起
# 在平时大家手动解压时可能也会遇到提示是否覆盖的问题
# 下面的两个函数解决这一问题
# 开始要先创建一个大文件夹 与压缩包名字相同
# 避免后期混乱和麻烦
def start_dir_make(root, dirname):os.chdir(root)os.mkdir(dirname)return os.path.join(root, dirname)# 去除多余文件夹
def rem_dir_extra(root, father_dir_name):# 递归要注意信息的正常处理 搞不好上一个调用已经改变了东西 而下面的调用还是使用之前的数据try:# 判断文件夹重名 开始for item in os.listdir(os.path.join(root, father_dir_name)):# 第一步判断是不是一个文件夹,如果不是则跳过本次循环if not os.path.isdir(os.path.join(root, father_dir_name, item)):continue# 判断是否要脱掉一层目录结构# 文件夹名字要相同,且子目录中只有单独的一个文件夹if item == father_dir_name and len(os.listdir(os.path.join(root, father_dir_name))) == 1:# 改变工作目录os.chdir(root)# 将无用文件夹重命名,因为直接移动会有重名错误os.rename(father_dir_name, father_dir_name + '-old')# 移动文件后删除空文件夹shutil.move(os.path.join(root, father_dir_name + '-old', item), os.path.join(root))os.rmdir(os.path.join(root, father_dir_name + '-old'))# 将去掉一层目录结构后的文件夹继续作为父本递归处理下去# 这里要注意,上面已经发生过数据的改动,所以下面递归传参一定要正确!rem_dir_extra(root, item)else:# 处理那些不满足上面条件的文件夹rem_dir_extra(os.path.join(root, father_dir_name), item)except Exception as e:# 打印错误信息print("清除文件夹出错" + str(e))# 入口if __name__ == '__main__':flag = 1while flag:# 循环遍历文件夹for root, dirs, files in os.walk(parent_path):# 读取文件名for name in files:if name.endswith(file_flag):# 创建文件夹new_ws = start_dir_make(root, name.replace(file_flag, ''))# zip文件地址zip_path = os.path.join(root, name)# 解压flag = decompress(zip_path, new_ws)# 删除解压后的文件# 有点危险# 但不删除又可能会重复运行# 一定要备份或先测试,不然可能会凉,自己选择修改del_old_zip(zip_path)# 去掉多余的文件结构rem_dir_extra(root, name.replace(file_flag, ''))print(f'{root}\\{name}'.join(['文件:', '\n解压完成\n']))# 由于解压可能解了好几次 所以可能会有已经解压好的父级目录重名无法处理 这里要再处理一次rem_dir_extra(os.path.split(parent_path)[0], os.path.split(parent_path)[1])print("解压完成啦,记得检查有没有zip格式之外的呀!\n\n其他格式需要自己改一下了")
批量压缩文件
应用场景:当你有大量的文件需要进行压缩时
import os,zipfile,glob
# 这是一个可以实现压缩文件夹的函数,传入参数为文件夹位置和保存的压缩文件名
def zip_file(src_dir, zip_name):z = zipfile.ZipFile(zip_name,'w',zipfile.ZIP_DEFLATED)for dirpath, dirnames, filenames in os.walk(src_dir):fpath = dirpath.replace(src_dir,'')fpath = fpath and fpath + os.sep or ''for filename in filenames:z.write(os.path.join(dirpath, filename),fpath+filename)print ('==压缩成功==')z.close()def run():for file in glob.glob(r'【这里换成你的文件夹地址】\*'):try:if os.path.isdir(file):name = file.split('\\')[-1]filename = rf"【这里换成你的文件夹地址】\{name}.zip"# print(filename)zip_file(file,filename)print(f'{file}压缩成功')except:pass
if __name__ == '__main__':run()
批量新建文件夹
应用场景:当你需要新建大量的文件夹时,或根据列表清单进行新建文件夹等工作场景
def Makedirs(dirname_list):import ospath = '【这里换成你的文件夹地址】'for i in dirname_list:isExists = os.path.exists(path+str(i))if not isExists:os.makedirs(path+str(i))print("%s 目录创建成功"%i)else:print("%s 目录已经存在"%i)continue
if __name__ == '__main__':# 直接给定需要批量新建的文件名列表dirname_list = [11,12,13]Makedirs(dirname_list)
批量移动文件到同名文件夹下
应用场景:当你需要进行文件夹整理时
import os
import shutil
import glob
for file in glob.glob('【这里换成你的文件夹地址】\*'):try:if os.path.isdir(file):passelse:move_path = file.split('.')[0]shutil.move(file,move_path)except:pass
批量转换文件编码格式
应用场景:需要统一文件编码格式或进行批量更改时
import osfrom chardet import detect# 需要把这个文件放在你要改编码格式的文件夹下fns = []filedir = os.path.join(os.path.abspath('.'))file_name = os.listdir(os.path.join(os.path.abspath('.')))for fn in file_name:if fn.endswith('.txt'): # 这里填文件后缀fns.append(os.path.join(filedir, fn))for fn in fns:with open(fn, 'rb+') as fp:content = fp.read()codeType = detect(content)['encoding']content = content.decode(codeType, "ignore").encode("utf-8")fp.seek(0)fp.write(content)print(fn, ":已修改为utf-8编码")