weixin_48331547 2022-07-24 04:30 采纳率: 100%
浏览 126
已结题

python PDF转存及压缩功能需求,有偿

我是一位设计师,平时工作中需要大量的pdf的转存的工作,工作流程为:

  1. 将N个pdf合并成一个pdf,(N一般大于100页,体量庞大,单个文件为设计内容,合并为一个汇报文件)
  2. 将合并pdf另存为JPG,(设计付费及版权原因,原有pdf为矢量内容需要转为图片格式)
  3. 将JPG合成为一个pdf,并且压缩降低文件尺寸(重新组合为一个汇报文件,并且压缩到合适与发送的大小)

这个事虽然简单,但面临每次几百页的pdf,合并压缩时间缓慢,中间还需关注,执行各个操作步骤,效率低下,

我只是刚接触python,需要能实现输入一个文件地址,就会将内部pdf按照顺序合并,另存jpg,再合并并压缩的功能

希望有能帮我实现这个功能的python代码,并且有比较详细的库的安装方式,感谢!

  • 写回答

5条回答 默认 最新

  • 脚踏南山 2022-07-24 13:14
    关注

    后续可以远程帮组调试,该项目是我之前自动化下载百度经验所用
    下有代码,可直接复制使用。如有帮助,敬请采纳,你的采纳是我前进的动力,O(∩_∩)O谢谢!!!!!!!!
    路过的朋友也可以点个赞~(≧▽≦)/~
    安装依赖包

    pip3 install PyMuPDF==1.19.6
    pip3 install reportlab==3.6.8
    pip3 install pillow==9.0.1
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
    weixin_48331547 回复 脚踏南山 2022-07-25 04:21

    刚学编程不久,有个问题,现在3个def的功能,是未来分别一个个执行是吗?如果是这样可能和我原先用pdf压缩过程差不多,我希望能全自动化的,比如转jpg之后自动把jpg再合并起来,我只需操作一次

    回复
    脚踏南山 回复 weixin_48331547 2022-07-25 05:59

    配置好红框中的参数,可直接使用

    img

    # -*- coding: UTF-8 -*-
    """
    @项目名称:合并文件夹下的PDF并添加书签.py
    @作   者:陆地起飞全靠浪
    @创建日期:2022-04-29-17:51
    https://blog.csdn.net/weixin_48331547?type=ask
    """
    
    import os
    from PyPDF2 import PdfFileReader, PdfFileWriter
    import time
    import shutil
    import fitz
    from glob import glob
    
    
    def getFileName(filepath):
        file_list = glob("{}/*.pdf".format(filepath))
        # 默认按照字典序排序,也可以安装自定义的方式排序
        file_list.sort(key=lambda x: int(x.split('/')[-1].split('、')[0]))
        return file_list
    
    
    ###########合并同一个文件夹下所有PDF文件###############
    def MergePDF(filepath, outfile):
        output = PdfFileWriter()
        outputPages = 0
        pdf_fileName = getFileName(filepath)
        for each_file in pdf_fileName:
            print("adding %s" % each_file)
            # 读取源pdf文件
            input = PdfFileReader(open(each_file, "rb"))
    
            # 如果pdf文件已经加密,必须首先解密才能使用pyPdf
            if input.isEncrypted == True:
                input.decrypt("map")
    
            # 获得源pdf文件中页面总数
            pageCount = input.getNumPages()
            outputPages += pageCount
            print("文件《%s》有%d页" % (each_file, pageCount))
    
            # 分别将page添加到输出output中
            for iPage in range(pageCount):
                output.addPage(input.getPage(iPage))
    
            # 添加书签
            each_file = os.path.basename(each_file)
            output.addBookmark(title=each_file[:-4], pagenum=outputPages - pageCount)
    
        print("All Pages Number: " + str(outputPages))
        # 最后写pdf文件
        outputStream = open(os.path.join(filepath, outfile), "wb")
        output.write(outputStream)
        outputStream.close()
        print("finished")
    
    
    def test_PyMuPDF_pdf2jpg(pdf_path=r'百度经验/1恩Ian.pdf', save_path='图片保存/路径', scale=1.0):
        #  打开PDF文件,生成一个对象
        doc = fitz.open(pdf_path)
        print("共", doc.pageCount, "页")
        for pg in range(doc.pageCount):
            print("\r转换为图片", pg + 1, "/", doc.pageCount, end="")
            page = doc[pg]
            rotate = int(0)
            # 缩放图片,乘以以下系数
            zoom_x = scale  # 缩放宽度
            zoom_y = scale  # 缩放高度
            trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
            pm = page.get_pixmap(matrix=trans, alpha=False)
            pm.save(f'{save_path}/' + '{}.jpg'.format(pg))
    
    
    def test_PyMuPDF_jpg2pdf(img_dir='你的图片/路径', out_pdf='.pdf'):
        img_path_list = glob(img_dir + '/*.jpg')
        img_path_list.sort(key=lambda x: int(x.split('/')[-1].split('.')[0]))
        doc = fitz.open()
        for img in img_path_list:  # 读取图片,确保按文件名排序
            print(img)
            imgdoc = fitz.open(img)  # 打开图片
            pdfbytes = imgdoc.convertToPDF()  # 使用图片创建单页的 PDF
            imgpdf = fitz.open("pdf", pdfbytes)
            doc.insertPDF(imgpdf)  # 将当前页插入文档
        if os.path.exists(f"{img_dir}.pdf"):
            os.remove(f"{img_dir}.pdf")
        doc.save(out_pdf)  # 保存pdf文件
        doc.close()
    
    
    def run(pdf_dir, merge_pdf, save_jpg_dir, out_pdf):
        shutil.rmtree(save_jpg_dir)
        if not os.path.isdir(save_jpg_dir):
            os.mkdir(save_jpg_dir)
        # 合并多个PDF到一个pdf文件
        MergePDF(pdf_dir, merge_pdf)
    
        # pdf转JPG并压缩
        test_PyMuPDF_pdf2jpg(pdf_path=merge_pdf, save_path=save_jpg_dir, scale=scale)
    
        # JPG合并成PDF
        test_PyMuPDF_jpg2pdf(img_dir=save_jpg_dir, out_pdf=out_pdf)
    
    
    if __name__ == '__main__':
        time1 = time.time()
        # 配置
        pdf_dir = u'pdf文件夹路径'
        merge_pdf = "合并的pdf.pdf"
        save_jpg_dir = '图片保存路径'
        out_pdf = '最终输出PDF.pdf'
        # 压缩比,大于1放大,小于1缩小
        scale = 1.0
    
        run(pdf_dir, merge_pdf, save_jpg_dir, out_pdf)
        time2 = time.time()
        print(u'总共耗时: %.4f s' % (time2 - time1))
    
    
    

    回复
    万里鹏程转瞬至 回复 weixin_48331547 2022-07-25 06:15

    答主的代码很完整了,亲测可用。略微调整了细节,在win10下可用

    import ipdb
     
    import os,shutil
    from PyPDF2 import PdfFileReader, PdfFileWriter
    import time
    import glob
    import fitz
     
     
    def getFileName(filepath):
        file_list = glob.glob("{}/*.pdf".format(filepath))
        
        # 默认按照字典序排序,也可以安装自定义的方式排序
        #file_list.sort(key=lambda x: int(x.split('/')[-1].split('、')[0]))
        file_list.sort()
        return file_list
     
     
    ###########合并同一个文件夹下所有PDF文件###############
    def MergePDF(filepath, outfile):
        output = PdfFileWriter()
        outputPages = 0
        pdf_fileName = getFileName(filepath)
        for each_file in pdf_fileName:
            print("adding %s" % each_file)
            # 读取源pdf文件
            input = PdfFileReader(open(each_file, "rb"))
     
            # 如果pdf文件已经加密,必须首先解密才能使用pyPdf
            if input.isEncrypted == True:
                input.decrypt("map")
     
            # 获得源pdf文件中页面总数
            pageCount = input.getNumPages()
            outputPages += pageCount
            print("文件《%s》有%d页" % (each_file, pageCount))
     
            # 分别将page添加到输出output中
            for iPage in range(pageCount):
                output.addPage(input.getPage(iPage))
     
            # 添加书签
            each_file = os.path.basename(each_file)
            output.addBookmark(title=each_file[:-4], pagenum=outputPages - pageCount)
     
        print("All Pages Number: " + str(outputPages))
        # 最后写pdf文件
        outputStream = open(os.path.join(filepath, outfile), "wb")
        output.write(outputStream)
        outputStream.close()
        print("finished")
     
     
     
    def test_PyMuPDF_pdf2img(pdf_path=r'百度经验/1恩Ian.pdf',save_path = '图片保存/路径'):
        #os.system(f'rm -rf {save_path}/*') 这个命令只能针对linux
        
        if not os.path.isdir(save_path):
            os.mkdir(save_path)
        else:
            shutil.rmtree(save_path)#删除文件夹
            os.mkdir(save_path)
            
        #  打开PDF文件,生成一个对象
        doc = fitz.open(pdf_path)
        print("共", doc.pageCount, "页")
        for pg in range(doc.pageCount):
            print("\r转换为图片", pg + 1, "/", doc.pageCount, end="")
            page = doc[pg]
            rotate = int(0)
            # 缩放图片,乘以以下系数
            zoom_x = 8.0  # 缩放宽度
            zoom_y = 8.0  # 缩放高度
            trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
            pm = page.get_pixmap(matrix=trans, alpha=False)
            pm.save(f'{save_path}/' + '{}.jpg'.format(pg))
     
     
    def test_PyMuPDF_pic2pdf(img_dir='你的图片/路径'):
        img_path_list = glob.glob(img_dir + '/*.jpg')
        img_path_list.sort(key=lambda x: int(x.split('\\')[-1].split('/')[-1].split('.')[0]))# 这里要考虑win10下路径为//的情况
        doc = fitz.open()
        for img in img_path_list:  # 读取图片,确保按文件名排序
            print(img)
            imgdoc = fitz.open(img)  # 打开图片
            pdfbytes = imgdoc.convertToPDF()  # 使用图片创建单页的 PDF
            imgpdf = fitz.open("pdf", pdfbytes)
            doc.insertPDF(imgpdf)  # 将当前页插入文档
        if os.path.exists(f"{img_dir}.pdf"):
            os.remove(f"{img_dir}.pdf")
        doc.save(f"{img_dir}.pdf")  # 保存pdf文件
        doc.close()
     
    if __name__ == '__main__':
        time1 = time.time()
        # 多个pdf所在目录,不能以/结尾,请注意文件名顺序(根据文件名顺序进行排序0-9,A-Z,a-z)
        file_dir = u'D:/MyPDF'
        # 合并后的pdf文件名,最终文件名,默认以文件夹名称路径
        out_file = f"{file_dir}.pdf"
        MergePDF(file_dir, out_file)
        print(u'总共耗时: %.4f s' % (time.time() - time1))
        
        time1 = time.time()
        test_PyMuPDF_pdf2img(out_file,"D:/MyPDFImg")#图片会保存到D:/MyPDFImg目录下
        print(u'总共耗时: %.4f s' % (time.time() - time1))
        
        time1 = time.time()
        test_PyMuPDF_pic2pdf("D:/MyPDFImg")#文件最终保存为D:/MyPDFImg.pdf
        print(u'总共耗时: %.4f s' % (time.time() - time1))
        
    
    
    ```python
    
    
    

    ```

    回复
    展开全部4条评论
查看更多回答(4条)
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 8月1日
  • 已采纳回答 7月25日
  • 创建了问题 7月24日
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部