Fügen Sie mit Python Text zu vorhandenen PDF-Dateien hinzu


106

Ich muss einer vorhandenen PDF-Datei mit Python zusätzlichen Text hinzufügen. Wie gehe ich am besten vor und welche zusätzlichen Module muss installiert werden?

Hinweis: Idealerweise möchte ich dies sowohl unter Windows als auch unter Linux ausführen können, aber auf Knopfdruck reicht Linux nur aus.

Bearbeiten: pyPDF und ReportLab sehen gut aus, aber keiner erlaubt mir, ein vorhandenes PDF zu bearbeiten. Gibt es andere Optionen?

Antworten:


88

Ich weiß, dass dies ein älterer Beitrag ist, aber ich habe lange versucht, eine Lösung zu finden. Ich bin auf einen anständigen gestoßen, der nur ReportLab und PyPDF verwendet, also dachte ich, ich würde teilen:

  1. Lesen Sie Ihr PDF mit PdfFileReader(), wir nennen diese Eingabe
  2. Erstellen Sie ein neues PDF mit Ihrem Text, das Sie mit ReportLab hinzufügen möchten, und speichern Sie dieses als Zeichenfolgenobjekt
  3. Lesen Sie das String-Objekt mit PdfFileReader(), wir nennen diesen Text
  4. Erstellen Sie ein neues PDF-Objekt mit PdfFileWriter(), wir nennen diese Ausgabe
  5. Durchlaufen Sie die Eingabe und wenden Sie sie .mergePage(*text*.getPage(0))für jede Seite an, zu der der Text hinzugefügt werden soll. Verwenden Sie dann diese Option output.addPage(), um die geänderten Seiten einem neuen Dokument hinzuzufügen

Dies funktioniert gut für einfache Textzusätze. Informationen zum Wasserzeichen eines Dokuments finden Sie im PyPDF-Beispiel.

Hier ist ein Code zur Beantwortung der folgenden Frage:

packet = StringIO.StringIO()
can = canvas.Canvas(packet, pagesize=letter)
<do something with canvas>
can.save()
packet.seek(0)
input = PdfFileReader(packet)

Von hier aus können Sie die Seiten der Eingabedatei mit einem anderen Dokument zusammenführen.


2
"Erstellen Sie ein neues PDF mit Ihrem Text, das Sie mit ReportLab hinzufügen möchten, und speichern Sie es als Zeichenfolgenobjekt." Wie machen Sie das? Es ist eine Canvas-Instanz.
Lakshman Prasad

1
Ich habe oben einen Beispielcode hinzugefügt, um Lakshmans Frage zu beantworten.
dwelch

Ich empfehle die Verwendung von PyPDF2, da es aktueller ist. Überprüfen Sie auch den Beispielcode: github.com/mstamy2/PyPDF2/blob/…
Blaze

2
Dieser Code erstellt eine neue PDF-Datei und überspringt alle Metadaten. Es wird also nicht an vorhandenes PDF angehängt.
Anton Kukoba

124

Beispiel für [Python 2.7]:

from pyPdf import PdfFileWriter, PdfFileReader
import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(10, 100, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(file("original.pdf", "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = file("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

Beispiel für Python 3.x:


from PyPDF2 import PdfFileWriter, PdfFileReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = io.BytesIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(10, 100, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader(open("original.pdf", "rb"))
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = open("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

13
Für Python3 sollte das Paket PyPDF2 sein io.BytesIOund PyPDF2 anstelle von pyPDF (das nicht verwaltet wird) verwenden. Gute Antwort!
Noufal Ibrahim

4
Danke für das Teilen. Es funktioniert großartig. Eine Anmerkung: Ich glaube, es ist besser, openanstatt zu verwenden file.
Mitenka

Ich glaube, dies ist eine akzeptablere Antwort, zumal sie ein funktionierendes Beispiel enthält.
Casey

1
Achtung: Das neue Dokument enthält nur die erste Seite des Originals! Es ist einfach genug, den Rest der Seiten von existing_pdfnach zu kopieren output, der Beispielcode einfach nicht.
Alexis

@alexis: Wie würden Sie den Code ändern, um etwas auf die zweite Seite des PDFs zu setzen? Ich habe ein Formular, das zwei Seiten verwendet, und ich stecke auf der ersten Seite fest. Danke im Voraus.
DavidV

11

Mit pdfrw können Sie Seiten aus einer vorhandenen PDF-Datei einlesen und auf eine Reportlab-Leinwand zeichnen (ähnlich wie beim Zeichnen eines Bildes). Beispiele hierfür finden Sie im Unterverzeichnis pdfrw examples / rl1 auf github. Haftungsausschluss: Ich bin der pdfrw-Autor.


Ich denke, Sie könnten dort einen Link setzen
The6thSense

Guter Punkt! Ich hatte nicht viel SO-Zeug gemacht, als ich das gepostet habe, und war besorgt über die "Richtlinie für minimalen Text plus Link". (Mein Repräsentant war zu diesem Zeitpunkt nur 46 Jahre alt, und IIRC Ich hatte gerade eine -2 für eine Antwort erhalten, daher war ich ein wenig besorgt über neue Antworten auf 5 Jahre alte Fragen :)
Patrick Maupin

alte Fragen bekommen mehr Sicht :) und Aufmerksamkeit
The6thSense

FWIW, es gibt einige weitere Beispiele für reportlab / pdfrw, wenn Sie diesem Link folgen . Ich antwortete dort, basierend auf einer Antwort im betrogenen Ziel.
Patrick Maupin

7

Nutzung David Dehghan ‚s Antwort oben die folgenden Arbeiten in Python 2.7.13:

from PyPDF2 import PdfFileWriter, PdfFileReader, PdfFileMerger

import StringIO

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter

packet = StringIO.StringIO()
# create a new PDF with Reportlab
can = canvas.Canvas(packet, pagesize=letter)
can.drawString(290, 720, "Hello world")
can.save()

#move to the beginning of the StringIO buffer
packet.seek(0)
new_pdf = PdfFileReader(packet)
# read your existing PDF
existing_pdf = PdfFileReader("original.pdf")
output = PdfFileWriter()
# add the "watermark" (which is the new pdf) on the existing page
page = existing_pdf.getPage(0)
page.mergePage(new_pdf.getPage(0))
output.addPage(page)
# finally, write "output" to a real file
outputStream = open("destination.pdf", "wb")
output.write(outputStream)
outputStream.close()

3

cpdf erledigt den Job über die Kommandozeile. Es ist jedoch keine Python (afaik):

cpdf -add-text "Line of text" input.pdf -o output .pdf

0

Möglicherweise haben Sie mehr Glück, wenn Sie das Problem in die Konvertierung von PDF in ein bearbeitbares Format zerlegen, Ihre Änderungen schreiben und dann wieder in PDF konvertieren. Ich kenne keine Bibliothek, mit der Sie PDF direkt bearbeiten können, aber es gibt zum Beispiel viele Konverter zwischen DOC und PDF.


1
Das Problem ist, dass ich nur die Quelle in PDF (von einem Drittanbieter) habe und PDF -> DOC -> PDF bei der Konvertierung viel verliert. Außerdem muss dies unter Linux ausgeführt werden, damit DOC möglicherweise nicht die beste Wahl ist.
Frozenskys

Ich glaube, Adobe hält die PDF-Bearbeitungsfunktionen ziemlich geschlossen und proprietär, damit sie Lizenzen für ihre besseren Versionen von Acrobat verkaufen können. Vielleicht können Sie eine Möglichkeit finden, die Verwendung von Acrobat Pro zum Bearbeiten mithilfe einer Makroschnittstelle zu automatisieren.
Aehlke

Wenn es sich bei den Teilen, in die Sie schreiben möchten, um Formularfelder handelt, gibt es XML-Schnittstellen zum Bearbeiten. Andernfalls kann ich nichts finden.
Aehlke

Nein, ich wollte jeder Seite nur ein paar Textzeilen hinzufügen.
Frozenskys

0

Wenn Sie unter Windows arbeiten, funktioniert dies möglicherweise:

PDF Creator Pilot

Es gibt auch ein Whitepaper eines PDF-Frameworks zum Erstellen und Bearbeiten in Python. Es ist etwas veraltet, kann Ihnen aber möglicherweise nützliche Informationen geben:

Verwenden von Python als PDF-Bearbeitungs- und Verarbeitungs-Framework


Das Whitepaper sieht gut aus, enthält jedoch ein wenig Code und ich habe nicht wirklich die Ressourcen, um ein ganzes PDF-Framework selbst zu implementieren! ;)
Frozenskys

-4

Haben Sie pyPdf ausprobiert ?

Der Inhalt einer Seite kann leider nicht geändert werden.


Sieht so aus, als könnte das funktionieren, hat es jemand benutzt? Wie ist die Speichernutzung?
Frozenskys

Es kann ein Textwasserzeichen hinzufügen, und wenn es richtig formatiert wurde, funktioniert es möglicherweise.
Frozenskys
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.