当前位置:脚本大全 > > 正文

python创建pdf(Python玩转PDF的各种骚操作)

时间:2021-10-13 00:32:35类别:脚本大全

python创建pdf

Python玩转PDF的各种骚操作

portable document format(可移植文档格式),或者pdf是一种文件格式,可以用于跨操作系统的呈现和文档交换。尽管pdf最初是由adobe发明的,但它现在是由国际标准化组织(iso)维护的开放标准。你可以通过使用pypdf2包在python中处理已先存在的pdf。

pypdf2是一个纯python包,可用于许多不同类型的pdf操作。

本文将带你了解如何执行以下操作:

从python中提取pdf中的文档信息

一、pypdf,pypdf2和pypdf4的历史

最初的pypdf软件包于2005年发布。pypdf的最后一个正式版本是在2010年。大约一年后,一家名为phasit的公司赞助了一个名为pypdf2的pypdf分支。该代码编写为向后与原始代码兼容,并且用了好多年,效果一直很好,其最后一个版本是在2016年。

有一个名为pypdf3的软件包简短系列版本,然后该项目被重命名为pypdf4。所有这些项目都完全相同,但pypdf和pypdf2 +之间的最大区别在于后者版本增加了python 3支持。python 3的原始pypdf有一个不同的python 3分支,但是这个分支已经多年没有维护了。

虽然最近放弃了pypdf2,但新的pypdf4与pypdf2没有完全的向后兼容性。本文中的大多数示例都可以与pypdf4完美配合,但也有一些不能,这就是为什么pypdf4在本文中没有更多的特色。随意用pypdf4替换pypdf2的导入,看看它是如何工作的。

二、pdfrw:一个替代的pdf操作包

patrick maupin创建了一个名为pdfrw的软件包,它可以完成许多与pypdf2相同的工作。除了加密的特殊情况外,本文后面提到pypdf2的所有操作,pdfrw均可以实现。

pdfrw的最大区别在于它与reportlab软件包集成,因此你可以使用一些或所有预先存在的pdf构建一个新的pdf。

三、pypdf2的安装

如果使用anaconda而不是常规python,可以使用pip或conda安装pypdf2。以下是使用pip安装pypdf2的方法:

$ pip install pypdf2

由于pypdf2没有任何依赖,因此安装非常快。

四、如何从python中提取pdf文档信息

我们可以使用pypdf2从pdf中提取元数据和一些文本,尤其是当在预先存在的pdf文件上执行某些类型的自动化时是非常有用的。

以下是当前可以提取的数据类型:

可以在自己的电脑上随便找一个pdf文件进行尝试操作。下面是使用该pdf编写一些代码,并了解如何访问这些属性:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • from pypdf2 import pdffilereader
  • def extract_information(pdf_path):
  •  with open(pdf_path, 'rb') as f:
  •   pdf = pdffilereader(f)
  •   information = pdf.getdocumentinfo()
  •   number_of_pages = pdf.getnumpages()
  •  txt = f"""
  •  information about {pdf_path}:
  •  author: {information.author}
  •  creator: {information.creator}
  •  producer: {information.producer}
  •  subject: {information.subject}
  •  title: {information.title}
  •  number of pages: {number_of_pages}
  •  """
  •  print(txt)
  •  return information
  • if __name__ == '__main__':
  •  path = 'xxxx.pdf'
  •  extract_information(path)
  • 首先从pypdf2包导入pdffilereader。pdffilereader是一个具有多种与pdf文件交互的方法的类。在此示例中,我们调用了.getdocumentinfo(),它将返回documentinformation的实例,包含了我们感兴趣的大部分信息。我们还可以在reader对象上调用.getnumpages(),让它返回文档中的页数。

    information这个变量具有多个实例属性,可以使用这些属性从文档中获取所需的其余元数据。我们可以打印出该信息并将其返回以备将来使用。

    虽然pypdf2具有.extracttext(),可以在其页面对象上使用提取文本(本例中未显示),但它的效果不是很好。有些pdf会返回文本,有些会返回空字符串。如果要从pdf中提取文本,建议应该看一下pdfminer项目。pdfminer更加强大,专门用于从pdf中提取文本。

    五、如何旋转页面?

    有时候pdf是横向模式而不是纵向模式,甚至是颠倒的。当有人扫描文档为pdf或电子邮件时,很可能会发生这种情况。我们可以打印出文档并阅读纸质版本,也可以使用python的强大功能来旋转有问题的页面。

    下面看一下如何使用pypdf2旋转文章的一些页面:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • from pypdf2 import pdffilereader, pdffilewriter
  • def rotate_pages(pdf_path):
  •  pdf_writer = pdffilewriter()
  •  pdf_reader = pdffilereader(path)
  •  # 顺时针旋转90度
  •  page_1 = pdf_reader.getpage(0).rotateclockwise(90)
  •  pdf_writer.addpage(page_1)
  •  # 逆时针旋转90度
  •  page_2 = pdf_reader.getpage(1).rotatecounterclockwise(90)
  •  pdf_writer.addpage(page_2)
  •  # 在正常方向上添加一页
  •  pdf_writer.addpage(pdf_reader.getpage(2))
  •  with open('rotate_pages.pdf', 'wb') as fh:
  •   pdf_writer.write(fh)
  • if __name__ == '__main__':
  •  path = '新路径.pdf'
  •  rotate_pages(path)
  • 上面除了pdfilereader之外,还导入了pdfilewriter,因为我们需要编写一个新的pdf。rotate_pages()获取要修改的pdf的路径。在这个函数中,需要创建一个可以命名为pdf-writer的writer对象和一个名为pdf-reader的reader对象。

    接下来,可以使用.get page()获取所需的页面。上面开始输入了第0页,也就是第一页,调用page对象的.rotateclockwise()顺时针旋转方法并输入90。然后同样地,对于第二页,调用.rotatecounterlockwise()逆时针旋转并输入90。

    每次调用rotation旋转方法后,都会调用.addpage(),这将向writer对象添加页面的旋转版本。最后一页是第3页,没有对其进行任何旋转。最后,使用.write()把所有新页写入新的pdf。

    六、如何合并pdf?

    在许多情况下,我们希望将两个或多个pdf合并到一个pdf中。例如,现在可能有一个标准的封面,需要转到许多类型的报告中。这时候就可以使用python来帮助完成这类工作。

    下面是实现的代码,完成pdf合并的操作:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • from pypdf2 import pdffilereader, pdffilewriter
  •  
  • def merge_pdfs(paths, output):
  •  pdf_writer = pdffilewriter()
  •  for path in paths:
  •   pdf_reader = pdffilereader(path)
  •   for page in range(pdf_reader.getnumpages()):
  •    # 将每页添加到writer对象
  •    pdf_writer.addpage(pdf_reader.getpage(page))
  •  # 写入合并的pdf
  •  with open(output, 'wb') as out:
  •   pdf_writer.write(out)
  • if __name__ == '__main__':
  •  paths = ['document1.pdf', 'document2.pdf']
  •  merge_pdfs(paths, output='merged.pdf')
  • 假如有一个要合并到一起的pdf列表时,可以直接使用merge_pdf函数完成。此函数采用了输入路径和输出路径作为参数。

    首先遍历输入的paths,并为每个输入创建一个pdf阅读对象。然后遍历pdf文件中的所有页面,并使用.addpage()将这些页面写入writer对象。当完成对列表中所有pdf的所有页面的写入后,将在末尾写入新的结果中。

    如果不想合并每个pdf的所有页面,可以通过添加一系列要添加的页面来稍微增强这个脚本。挑战一点的话,也可以使用python的argparse模块为这个函数创建一个命令行接口。

    七、如何拆分pdf?

    有时可能需要将pdf拆分为多个pdf,对于包含大量扫描内容的pdf来说尤其重要。以下是如何使用pypdf2将pdf拆分为多个文件:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • from pypdf2 import pdffilereader, pdffilewriter
  • def split(path, name_of_split):
  •  pdf = pdffilereader(path)
  •  for page in range(pdf.getnumpages()):
  •   pdf_writer = pdffilewriter()
  •   pdf_writer.addpage(pdf.getpage(page))
  •   output = f'{name_of_split}{page}.pdf'
  •   with open(output, 'wb') as output_pdf:
  •    pdf_writer.write(output_pdf)
  • if __name__ == '__main__':
  •  path = 'xxx.pdf'
  •  split(path, 'jupyter_page')
  • 这个函数中再次创建了pdf的reaer对象,并对其所读取的页面进行遍历。对于pdf中的每个页面,创建一个新的pdf的writer实例并向其添加单个页面。然后,将该页面写入一个唯一命名的文件。脚本运行完毕后,就可以将原始pdf的每个页面拆分为单独的pdf。

    八、如何添加水印?

    水印是纸质或者电子文档上的图像或图案,一些水印只能在特殊照明条件下才能看到。水印的重要性在于它可以保护你的知识产权,例如图像或pdf。

    我们可以使用python和pypdf2为文档添加水印,而且是拥有仅包含水印图像或文本的pdf。下面是向pdf添加水印方法:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • from pypdf2 import pdffilewriter, pdffilereader
  • def create_watermark(input_pdf, output, watermark):
  •  watermark_obj = pdffilereader(watermark)
  •  watermark_page = watermark_obj.getpage(0)
  •  pdf_reader = pdffilereader(input_pdf)
  •  pdf_writer = pdffilewriter()
  •  # 给所有页面添加水印
  •  for page in range(pdf_reader.getnumpages()):
  •   page = pdf_reader.getpage(page)
  •   page.mergepage(watermark_page)
  •   pdf_writer.addpage(page)
  •  with open(output, 'wb') as out:
  •   pdf_writer.write(out)
  • if __name__ == '__main__':
  •  create_watermark(
  •   input_pdf='jupyter_notebook_an_introduction.pdf',
  •    output='watermarked_notebook.pdf',
  •   watermark='watermark.pdf')
  • 上面create_watermark有三个参数:

    在代码中,打开水印pdf并从文档中抓取第一页,因为这是水印应该驻留的位置。然后使用input_pdf和通用pdf_writer对象创建pdf的writer对象,以写出带水印的pdf。

    下一步是遍历input_pdf中的页面,然后调用.mergepage()并以用上面读取的水印对象watermark_page为参数,这样会将watermark_page覆盖在当前页面的顶部,然后再将新合并的页面添加到pdf_writer对象中。遍历完成后,最后将新加水印的pdf写入磁盘。

    九、如何加密pdf?

    pypdf2目前仅支持将用户密码和所有者密码添加到预先存在的pdf。在pdf版本中,所有者密码会提供pdf的管理员权限,并允许设置文档的权限,而用户密码只允许打开文档。

    实际上,pypdf2是不允许设置文档的任何权限的,即使它允许设置所有者密码的情况下。但无论如何,这是可以加密的方式,也将固有地加密pdf:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • from pypdf2 import pdffilewriter, pdffilereader
  • def add_encryption(input_pdf, output_pdf, password):
  •  pdf_writer = pdffilewriter()
  •  pdf_reader = pdffilereader(input_pdf)
  •  for page in range(pdf_reader.getnumpages()):
  •   pdf_writer.addpage(pdf_reader.getpage(page))
  •  pdf_writer.encrypt(user_pwd=password, owner_pwd=none,
  •       use_128bit=true)
  •  with open(output_pdf, 'wb') as fh:
  •   pdf_writer.write(fh)
  • if __name__ == '__main__':
  •  add_encryption(input_pdf='reportlab-sample.pdf',
  •      output_pdf='reportlab-encrypted.pdf',
  •      password='twofish')
  • add_encryption以输入输出pdf路径和要添加到pdf的密码为参数。由于需要加密整个输入pdf,因此需要遍历其所有页面并将其添加到writer编写器。最后一步是调用.encrypt(),以用户密码,所有者密码以及是否应该添加128位加密为参数。默认情况下,要启用128位加密。如果将其设置为false,则将应用40位加密。

    结论

    pypdf2包非常有用,可以使用pypdf2自动执行脚本完成pdf文档的批量操作。本文介绍了如何从pdf中提取元数据,旋转页面,合并和拆分pdf,添加水印,以及添加加密的操作。

    同时,还要关注较新的pypdf4包,因为它很快就会取代pypdf2。也可以看看pdfrw包,它也可以执行许多与pypdf2相同的操作。

    以上所述是小编给大家介绍的python玩转pdf的各种骚操作,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对开心学习网网站的支持!

    如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

    原文链接:https://blog.csdn.net/qq_41841569/article/details/89813721

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐