• python_pdf常规使用


    目录

    1. 加水印

    2. 将pdf转成一张张图片 

     3. 多张图片转成一个pdf

     4. 多个pdf合并成一个pdf

     附加


    1. 加水印

    给pdf文件加自定义水印

    代码中 msyn.ttf 需要下载下来,然后在代码中指向存放的位置

    1. import os,datetime,fitz
    2. # fitz ==> pip install PyMuPDF==1.18.9
    3. from PyPDF2 import PdfFileReader,PdfFileWriter
    4. from reportlab.lib.units import cm
    5. from reportlab.pdfgen import canvas
    6. from reportlab.pdfbase import pdfmetrics
    7. from reportlab.pdfbase.ttfonts import TTFont
    8. pdfmetrics.registerFont(TTFont('msyh','./msyh.ttf'))

    以上是python操作pdf需要用到的包

    创建水印的代码:

    1. # 创建水印
    2. # content: 字符串列表
    3. def create_watermark00(pre_dir,content):
    4. print(content)
    5. '''创建水印'''
    6. # 默认大小为 21cm*29.7cm
    7. file_name = pre_dir+'mark.pdf'
    8. c = canvas.Canvas(file_name,pagesize=(30*cm,30*cm))
    9. # 移动坐标原点(坐标系左下为(0,0))
    10. c.translate(10*cm,5*cm)
    11. # 设置字体
    12. c.setFont('msyh',20)
    13. # 指定描边的颜色
    14. c.setStrokeColorRGB(0,0,0)
    15. # 指定填充颜色
    16. c.setFillColorRGB(0,0,0,0.2)
    17. # 旋转45度,坐标系被旋转
    18. c.rotate(30)
    19. # 画几个文本,注意坐标系旋转的影响
    20. for i in range(5):
    21. for j in range(10):
    22. a = 20*(i-1)
    23. b = 5*(j-2)
    24. for item_i,item_txt in enumerate(content):
    25. c.drawString((a+item_i)*cm,(b-item_i)*cm,item_txt)
    26. # c.drawString(a*cm,b*cm,content)
    27. c.setFillAlpha(0.1)
    28. c.save()
    29. return file_name

    添加水印的代码:

    1. # 给pdf添加水印
    2. def add_watermark(pdf_file_in,pdf_file_mark,pdf_file_out):
    3. pdf_output = PdfFileWriter()
    4. input_stream = open(pdf_file_in,'rb')
    5. pdf_input = PdfFileReader(input_stream,strict=False)
    6. # 获取pdf文件的页数
    7. pageNum = pdf_input.getNumPages()
    8. # 读入水印pdf文件
    9. pdf_watermark = PdfFileReader(open(pdf_file_mark,'rb'),strict=False)
    10. # 给每一页打水印
    11. for i in range(pageNum):
    12. page = pdf_input.getPage(i)
    13. page.mergePage(pdf_watermark.getPage(0))
    14. page.compressContentStreams()
    15. pdf_output.addPage(page)
    16. pdf_output.write(open(pdf_file_out,'wb'))
    17. pass

    使用:

    1. if __name__ == '__main__':
    2. pdf_file_in = r'E:/temp003/牧原股份_分析.pdf'
    3. pdf_file_out = r'E:/temp003/temp_mark.pdf'
    4. w_list = ['人生若只如初见','何事秋风悲画扇']
    5. pdf_file_mark = create_watermark00(r'E:/temp003/',w_list)
    6. add_watermark(pdf_file_in,pdf_file_mark,pdf_file_out)

    加水印前:

     加水印后: 

    2. 将pdf转成一张张图片 

    pdf有多少页就转成多少张图片

    1. # 将pdf转成图片
    2. def pdf_2_imgs(pdfPath, imagePath):
    3. startTime_pdf2img = datetime.datetime.now() # 开始时间
    4. print("imagePath=" + imagePath)
    5. pdfDoc = fitz.open(pdfPath)
    6. for pg in range(pdfDoc.pageCount):
    7. page = pdfDoc[pg]
    8. rotate = int(0)
    9. # 每个尺寸的缩放系数为1.3,这将为我们生成分辨率提高2.6的图像。
    10. # 此处若是不做设置,默认图片大小为:792X612, dpi=96
    11. zoom_x = 1.33333333 # (1.33333333-->1056x816) (2-->1584x1224)
    12. zoom_y = 1.33333333
    13. mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)
    14. pix = page.getPixmap(matrix=mat, alpha=False)
    15. if not os.path.exists(imagePath): # 判断存放图片的文件夹是否存在
    16. os.makedirs(imagePath) # 若图片文件夹不存在就创建
    17. pix.writePNG(imagePath + '/' + 'images_%s.png' % pg) # 将图片写入指定的文件夹内
    18. endTime_pdf2img = datetime.datetime.now() # 结束时间
    19. print('pdf2img时间=', (endTime_pdf2img - startTime_pdf2img).seconds)

    使用:

    1. if __name__ == '__main__':
    2. pdf_path = r'E:/temp003/temp_mark.pdf'
    3. pic_dir = r'E:/temp003/pic/'
    4. pdf_2_imgs(pdf_path,pic_dir)

    pdf有42页内容

     转成42张图片

     3. 多张图片转成一个pdf

    1. # 将图片文件前后顺序用数字命名
    2. def imgs_2_pdf(source_folder,pdfPath):
    3. doc = fitz.open()
    4. file_list = os.listdir(source_folder)
    5. file_map = {}
    6. for item in file_list:
    7. item_arr = item.split('.')
    8. file_map[item_arr[0]] = item
    9. pass
    10. for i in range(len(file_list)):
    11. img = source_folder + file_map[str(i)]
    12. imgdoc = fitz.open(img) # 打开图片
    13. pdfbytes = imgdoc.convertToPDF() # 使用图片创建单页的 PDF
    14. imgpdf = fitz.open("pdf", pdfbytes)
    15. doc.insertPDF(imgpdf) # 将当前页插入文档
    16. doc.save(pdfPath) # 保存pdf文件
    17. doc.close()

    使用:

    1. if __name__ == '__main__':
    2. img_dir = r'E:/temp003/pic/'
    3. pdf_path = r'E:/temp003/pic_after.pdf'
    4. imgs_2_pdf(img_dir,pdf_path)

    图片的名称需要按照前后顺序从0开始命名

     

     4. 多个pdf合并成一个pdf

    1. # 合并多个pdf文件成一个文件
    2. def merge_pdfs_2_one(file_path,out_file):
    3. output = PdfFileWriter()
    4. outputPages = 0
    5. pdf_fileName = getFileName(file_path)
    6. if pdf_fileName:
    7. for pdf_file in pdf_fileName:
    8. # 读取源pdf文件
    9. input = PdfFileReader(open(pdf_file,'rb'))
    10. pageCount = input.getNumPages()
    11. outputPages += pageCount
    12. # 分别将page添加到输出output中
    13. for iPage in range(pageCount):
    14. output.addPage(input.getPage(iPage))
    15. pass
    16. print('合并后总页数',outputPages)
    17. # 写入到目标pdf文件
    18. outputStream = open(os.path.join(file_path,out_file),'wb')
    19. output.write(outputStream)
    20. outputStream.close()
    21. else:
    22. print('没有可以合并的pdf文件')
    23. pass
    24. pass
    25. # 使用os模块的walk函数,搜索出指定目录下的全部PDF文件
    26. # 获取同一目录下的所有PDF文件的绝对路径
    27. def getFileName(filedir):
    28. file_list = [os.path.join(root, filespath) \
    29. for root, dirs, files in os.walk(filedir) \
    30. for filespath in files \
    31. if str(filespath).endswith('pdf')
    32. ]
    33. return file_list if file_list else []

    使用:

    1. if __name__ == '__main__':
    2. file_path = r'E:/temp003/temp/'
    3. out_file_name = r'E:/temp003/merge_example.pdf'
    4. merge_pdfs_2_one(file_path,out_file_name)
    5. pass

    合并前:

    合并后:

     

     附加

    msyh.ttf下载地址

    链接:https://pan.baidu.com/s/1IBVyKi4prejEtHFbMCuVhw 
    提取码:urfi

  • 相关阅读:
    元数据性能大比拼:HDFS vs S3 vs JuiceFS
    2024年 Openai的API相关全部概论汇总(通用版)
    【c++随笔08】可变参数——va_list、va_start、va_end、va_arg
    2023各版本JDK下载链接
    【C# 7.0 in a Nutshell】第4章 C#的高级特性——委托
    一个混乱千万级软件项目
    k8s入门之Deployment(五)
    Pandas中创建DataFrame对象以及相关的列操作,行操作
    Java 七牛云OSS 上传文件,删除图片,刷新CDN
    从源码方面来分析Fragment管理中 Add() 方法
  • 原文地址:https://blog.csdn.net/m0_37967652/article/details/125622346