如何使用Python从PDF中删除文本

5
我正在编写一个用于编辑PDF文本的Python脚本。
我有这段Python代码,它允许我将文本添加到PDF文件的特定位置。
import PyPDF2
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
import sys

packet = io.BytesIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
# Insert code into specific position
can.drawString(300, 115, "Hello world")
can.save()
#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PyPDF2.PdfFileReader(packet)
# read your existing PDF
existing_pdf = PyPDF2.PdfFileReader(open("original.pdf", "rb"))
num_pages = existing_pdf.numPages 
output = PyPDF2.PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(num_pages-1) # get the last page of the original pdf
page.mergePage(new_pdf.getPage(0)) # merges my created text with my PDF.
x = existing_pdf.getNumPages()
#add all pages from original pdf into output pdf
for n in range(x):
    output.addPage(existing_pdf.getPage(n))
# finally, write "output" to a real file
outputStream = open("output.pdf", "wb")
output.write(outputStream)
outputStream.close()

我的问题:我想用自定义文本替换原始PDF文件中特定位置的文本。写入空白字符的方法可能行得通,但我没有找到任何可以实现这一点的东西。

注:必须使用Python代码,因为我稍后需要将其部署为.exe文件,并且我只知道如何使用Python代码完成此操作。

2个回答

3
PDF中的通用替换文本算法是一个困难的问题。我并不是说它完全不能做到,因为我已经使用Adobe PDF库演示过,尽管只是对于没有复杂性的非常简单的输入文件,但我不确定pyPDF2是否具备所需的功能。部分原因在于,仅仅查找文本可能就是一个挑战。
你(或更现实地说是你的PDF库)必须解析页面内容并跟踪图形状态的更改,特别是在文本位于Form XObject时当前变换矩阵的更改和文本变换矩阵以及字体的更改;你必须使用字体资源获取字符宽度以确定插入字符串后文本光标可能的位置。您可能需要处理不包含其字体资源中该信息的标准14字体(应用程序-您的程序-预计知道它们的度量)。
在所有这些之后,如果您不需要将Tj或TJ(显示文本)指令拆分成不同部分,则删除文本很容易。如果要防止后面的文本移位,如果需要,可能需要插入新的Tm指令将后面的文本重新定位到原来的位置。
插入新文本可能会带来挑战。如果您想保持所使用的嵌入和子集字体的一致性,并且它不一定包含您需要的字形以进行文本插入。插入后,您还需要决定是否需要重新排版插入文本之后的文本。
最后,您将需要您的PDF库保存所有更改。坦白地说,使用Adobe Acrobat的"删除功能"可能比从头开始编写程序更便宜、更具成本效益。

我可以使用reportlab找到文本的位置,我成功地使用该库编写了所需的内容。我想要添加的文本将始终位于相同的位置,这使得任务更加容易。解决我的问题的“简单”方法是使用reportlab合并功能将文本替换为空格,但我不知道如何实现。 - Gabriel Belini
你混淆了Reportlab和PyPDF2。Reportlab可以用于创建新内容,而PyPDF2仅具有一些有限的操作现有PDF文件的功能。根据我对PyPDF2文档的浏览,我没有看到您可以删除现有内容,但是您可以在添加文本之前使用白色填充路径来覆盖它。如果您选择这种方法,用户可能仍然会看到原始文本,然后再被覆盖掉,而且文本提取可能会将该区域的原始文本和新文本混合在一起,导致无法理解的结果。 - Patrick Gallot

0

如果您想要使用ReportLab和PyPDF2进行简单的编辑,您可以使用ReportLab创建替换内容。给定一个Canvas、一个指示区域的矩形、一个文本字符串和插入文本字符串的点,然后您可以:

#set a fill color to white:
c.setFillColorRGB(1,1,1)
# draw a rectangle
c.rect([your rectangle], fill=1)
# change color
c.setFillColorRGB(0,0,0)
c.drawString([text insert position], [text string])

将您创建的PDF文档保存到临时文件中。 使用PyPDF2的PdfFileReader打开此PDF文档和要修改的文档。创建一个pdfFileWriter对象,称其为ModifiedDoc。获取临时PDF的第0页,称其为updatePage。获取另一个文档的第n页,称其为toModifyPage。

toModifyPage.mergePage(updatePage)

在更新页面完成后:

modifiedDoc.cloneDocumentFromReader(srcDoc)
modifiedDoc.write(outStream)

如果您选择这种方法,用户可能仍然会在新内容覆盖之前看到原始文本,并且文本提取很可能会将该区域的原始文本和新文本一起提取出来,并可能将其混合成难以理解的内容。


你知道吗?即使你用白色矩形填充了文本字符串,它仍然可以被复制。 - Sandip Kumar
1
是的,这就是为什么我说“文本提取可能会提取出该区域的原始文本和新文本,并可能将其混合成难以理解的内容。” - Patrick Gallot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接