用Python实现一款永久免费的PDF编辑工具

前言:

PDF(Portable Document Format),中文名称便携文档格式是我们经常会接触到的一种文件格式,文献、文档...很多都是PDF格式。它以格式稳定的优势,使得我们在打印、分享、传输过程中能够最优的保持原有色彩和格式。

但是在可编辑性方面却为使用者引入了另外一个困扰。

曾经,为了替换PDF中的一页,我几乎试遍了所有市面上主流的PDF工具,最终还是不得不选择使用付费工具来解决问题。

事后想了想,既然这些商业化软件不靠谱,为什么不考虑自己动手开发一款工具呢?明明几十行代码能够解决的问题,为什么要费那么多劲去下载、安装那些没有节操的软件呢?

本文就来介绍一下利用Python轻松开发一款PDF编辑工具,可以用于PDF转TxT、分割、合并、剪切、转换。

有请主角登场 PyPDF2 和 pdfminer3k

PyPDF2

简介:由纯 Python 构建的PDF 工具包。它能够:

  • 提取文档信息(标题、作者等)
  • 一页拆分文档
  • 按页合并文档
  • 裁剪页面
  • 将多个页面合并到单个页面中
  • 加密和解密 PDF 文件

安装

直接使用pip安装

pip install PyPDF2 

代码操作

  • 简单的读写PDF操作
from PyPDF2 import PdfFileReader, PdfFileWriter 
infn = 'infn.pdf' 
outfn = 'outfn.pdf' 
# 获取一个 PdfFileReader 对象 
pdf_input = PdfFileReader(open(infn, 'rb')) 
# 获取PDF 的基本信息 
information =pdf_input.getDocumentInfo() 
print(information) 
# 获取 PDF 的页数 
page_count = pdf_input.getNumPages() 
print(page_count) 
# 返回一个 PageObject 
page = pdf_input.getPage(i) 
 
# 获取一个 PdfFileWriter 对象 
pdf_output = PdfFileWriter() 
# 将一个 PageObject 加入到 PdfFileWriter 中 
pdf_output.addPage(page) 
# 输出到文件中 
pdf_output.write(open(outfn, 'wb')) 
  • 删除PDF页
from PyPDF2 import PdfFileWriter,  PdfFileReader 
 
# 实例化一个输出的PDF实例 
output = PdfFileWriter() 
#  读取一个PDF文件 
input1 = PdfFileReader(open("example.pdf", "rb"))  
 
# 要删除的操作 
def delete_pdf(index): 
            pages = input1.getNumPages()  
# 循环删除 
     for i in range(pages): 
      if i+1 in index: 
       continue 
      output.addPage(input1.getPage(i))  
 
     outputStream = open("PyPDF2-output.pdf", "wb") 
     output.write(outputStream)   
 
delete_pdf([2,3,4]) 
  • 合并PDF
from PyPDF2 import PdfFileWriter, PdfFileReader 
 
output = PdfFileWriter() 
input1 = PdfFileReader(open("example.pdf", "rb")) 
input2 = PdfFileReader(open("simple2.pdf", "rb")) // 1 
 
def merge_pdf(add_index, origin_index): 
         pages = input1.getNumPages() 
         k = 0 
         for i in range(pages): 
          if i+1 in add_index: 
               output.addPage(input2.getPage(origin_index[k])) // 2 
               pages += 1 
               k += 1 
              output.addPage(input1.getPage(i)) 
 
         outputStream = open("PyPDF2-output.pdf", "wb") 
         output.write(outputStream) 
 
merge_pdf([2,3,4], [0, 0, 0]) 
  • 旋转
# 旋转90度 
input1.getPage(1).rotateClockwise(90) 
  • 添加水印
page = input1.getPage(3) 
watermark = PdfFileReader(open("watermark.pdf", "rb")) 
page.mergePage(watermark.getPage(0)) 
  • 加密
password = "secret" 
output.encrypt(password) 
  • 解密
print(output.decrypt('secret'))# secret==正确口令显示1,其他显示0 
page_obj= output.getPage(0)# 这样才能正确读取 
print(page_obj.extractText()) 

pdfminer3k

  • 简介

pdfminer3k 是一个 Python 3 端口的 pdfminer 。PDFMiner 是一个从 PDF 文档中提取信息的工具。与其他与 PDF 相关的工具不同,它完全侧重于获取和分析文本数据。PDFMiner 允许获取页面中文本的确切位置,以及其他信息,如字体或线条。它包括一个 PDF 转换器,可以将 PDF 文件转换为其他文本格式(如 HTML)。它有一个可扩展的PDF解析器,可用于其他目的,而不是文本分析

    • 能够准确获取文本的位置和布局信息;
    • 可以将PDF转换为HTML/XML等格式;
    • 可以提取目录;
    • 可以提取标签内容;
    • 支持各种字体类型(Type1、TrueType、Type3和CID);
    • 支持中、日、韩语言和垂直书写文本;
  • 安装
pip install pdfminer3k 
  • 文件的操作
from urllib.request import urlopen 
 
from pdfminer.converter import PDFPageAggregator 
from pdfminer.layout import LAParams 
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter 
from pdfminer.pdfparser import PDFParser, PDFDocument 
 
logging.Logger.propagate = False 
logging.getLogger().setLevel(logging.ERROR) 
 
fp = open('template/pdftest.pdf', 'rb') 
# 在线 
# fp = urlopen('http://---/---.pdf') 
 
# 创建一个与文档关联的解析器 
parser = PDFParser(fp) 
 
# PDF文档对象 
doc = PDFDocument() 
 
#创建pdf文档对象,存储文档结构 
document = PDFDocument(parser, password) 
 
# 链接解析器和文档对象 
parser.set_document(doc) 
doc.set_parser(parser) 
 
# 初始化文档 
doc.initialize("") 
 
# 创建DPF资源管理器 
resource = PDFResourceManager() 
 
# 参数分析器 
laparam = LAParams() 
 
# 聚合器 
device = PDFPageAggregator(resource, laparams=laparam) 
 
# 创建页面解析器 
interpreter = PDFPageInterpreter(resource, device) 
 
# 使用文档对象从pdf中读取内容 
for page in doc.get_pages(): 
    # 使用页面解析器 
    interpreter.process_page(page) 
 
    # 使用聚合器获取内容 
    layout = device.get_result() 
 
    for text_obj in layout: 
        # 判断是否有get_text属性 
        if hasattr(text_obj, 'get_text'): 
            print(text_obj.get_text()) 
# 处理包含在文档中的每一页 
for page in PDFPage.create_pages(document): 
          interpreter.process_page(page) 
          layout = device.get_result() 
          for x in layout: 
              # 获取文本对象 
              if isinstance(x, LTTextBox): 
                  print(x.get_text().strip()) 
              # 获取图片对象 
              if isinstance(x,LTImage): 
                  print('这里获取到一张图片') 
              # 获取 figure 对象 
              if isinstance(x,LTFigure): 
                  print('这里获取到一个 figure 对象') 

相关推荐