Text in vorhandene pdf einfügen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Hallo allerseits,

ist es möglich in eine vorhandene .pdf (besteht nur aus Kopf- und Fußzeile) Text einzufügen (z.B. mit reportlab)??

Die vorh. pdf soll ein Grundlayout darstellen, dass dann wie ein Formular ausgefüllt wird... und als neue pdf gespeichert bzw. ausgedruckt...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich glaube es ist einfacher den 1. Schritt in den 2. zu nehmen und erst dann das PDF zu erstellen. Hast du den 1. Schritt denn unter deiner Kontrolle?
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ja, aber ich habe schon in Word lange gebastelt bis ich alles so hinbekommen habe wie ich wollte, die Arbeit möchte ich mir ersparen :wink:
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Das Problem dürfte schon damit anfangen, daß niemand weiß wie *Dein* Word PDFs erstellt (gut es gibt gewisse Standards, aber auch 1001 alternative Distiller). Also cofis Idee scheint mir die am besten gangbare:

Nachdem ich auf Jinja2 gestossen wurde bin ich ein Fan von LaTeX+Jinja2. Damit sollte das recht einfach gehen - sofern man Python & LaTeX kann, natürlich.

HTH
Christian
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

uffff :?

aber erstmal danke...
problembär

Wie schon in dem anderen Thread geschrieben, wenn Dein Word pdfs erzeugen kann, würde ich es mit win32com steuern und am Ende alles zusammen über Word ausgeben.

Eine zweite Möglichkeit wäre vielleicht, mit ReportLab eine Seite zu erzeugen und sie mit pyPdf über die bestehende pdf-Seite zu legen.
Es kann auch sein, daß ReportLab noch weitere geeignete Tools bietet, aber nicht alle davon sind frei, z.B. nicht Pagecatcher.

Wie gesagt, ich würd's über Word/Python machen.

Gruß
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

pyPDF ist die Lösung, Danke....


eine Zusatzfrage:

ich erstelle eine temp.pdf , die ich mit dem "Formular" vereine und möchte diese über einen evt.close löschen, aber folgendes
os.remove("temp.pdf")
WindowsError: [Error 32] Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird: 'temp.pdf'

kann ich das Löschen erzwingen, (-f) oder wie kann ich herausfinden welche Anwendung die Datei noch geöffnet hat (pyPDF oder reportlab)???

Ich würde ja gerne das Schließen erzwingen..


edit:

temp.pdf wird so erzeugt:

Code: Alles auswählen

from reportlab.pdfgen import canvas

def hello(c):
    c.drawString(100,100,"Hello World")
    c = canvas.Canvas("temp.pdf")
    hello(c)
    c.showPage()
    c.save()
zusammengefügt wird so:

Code: Alles auswählen

        output = PdfFileWriter()
        input1 = PdfFileReader(file("GraphFiles\\Rahmen.pdf", "rb"))
        input2 = PdfFileReader(file("temp.pdf", "rb"))
        output.addPage(input1.getPage(0))
        page1 = input1.getPage(0)
        watermark = PdfFileReader(file("temp.pdf", "rb"))
        page1.mergePage(watermark.getPage(0))
        
        # finally, write "output" to document-output.pdf
        outputStream = file("document-output.pdf", "wb")
        output.write(outputStream)
        outputStream.close()
  ----->      #os.remove("temp.pdf")  <--- das funktioniert nicht 
Zuletzt geändert von mathi am Donnerstag 5. November 2009, 19:41, insgesamt 1-mal geändert.
problembär

mathi hat geschrieben:pyPDF ist die Lösung
Na ja, eine der möglichen Lösungen.

Deinen Code zum Erzeugen von "temp.pdf" verstehe ich nicht. Wo sind die Einrückungen der Funktion??

Vielleicht stört Windows überhaupt, daß Dein Skript noch irgendwie darauf zugreift. Vielleicht könnte man zwei Skripte machen, die nacheinander aufgerufen werden.
Vielleicht geht's aber auch doch noch sauberer.

Gruß
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

die Einrückung hat gefehlt, das habe ich übersehen, ich habs im obigen Post geändert, :oops:
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

problembär hat geschrieben:....., daß Dein Skript noch irgendwie darauf zugreift.
na genau da möchte ich ansetzen und diesen Zugriff stoppen....
BlackJack

@mathi: Unter Windows ist eine beliebte Quelle für so eine Meldung auch, dass ein Virenscanner oder ein Dokumentenindexer, der im Hintergrund läuft, sich diese neue Datei gerade vorgenommen hat.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ok, aber was kann man da machen??
Das File soll weg....zumal ich im Windows-Explorer beim löschen erfahre, dass pythonw die Datei gerade benutzt.


ich denke, ich müßte die Datei nur richtig schließen, sowas wie f.close()

nur weiß ich nicht wie das geht
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Statt

Code: Alles auswählen

input2 = PdfFileReader(file("temp.pdf", "rb")) 
das

Code: Alles auswählen

with open("temp.pdf", "rb") as input_file:
    input2 = PdfFileReader(input_file) 
    ...
Für Input 1 natürlich das selbe und für Output auch.

Wobei das mit der Einrückung irgendwann mal unschön wird, wenn man mehrere Dateien nacheinander mit ``with`` öffnet. Deshalb vllt auch alles in einem try..finally Block. Aber das sollte man ja eigentlich auch nicht machen?! Oder kennt dafür jemand eine elegante Lösung?

Du solltest außerdem nie die ``file`` Funktion verwenden, sondern immer nur ``open``. (Ja, ich weiß, das ist so im Beispiel drin. Trotzdem! ;) )

Edit: Ab 2.7 gehen ``multiple context expression``

Code: Alles auswählen

with A() as a, B() as b:
    suite
IMHO eine sehr sinnvolle Erweiterung.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ice2k3 hat geschrieben:Aber das sollte man ja eigentlich auch nicht machen?! Oder kennt dafür jemand eine elegante Lösung?
Neben den von dir beschriebenen Erweiterungen gibt es auch ``contextlib.nested()``.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

vielen Dank an alle, ich habe es nun so gelöst:

Code: Alles auswählen

    with nested(open("tmp.pdf", "rb"),open("GraphFiles\\Rahmen.pdf", "rb"),open("temp.pdf", "wb")) as (tmp_file, rahmen_file, temp_file):
        input1 = PdfFileReader(rahmen_file)
        input2 = PdfFileReader(tmp_file)
        outputStream=temp_file
und im Hauptfenster einen evt_close:

Code: Alles auswählen

	def OnClose(self, event):
		if os.path.exists("temp.pdf"):
			os.remove("temp.pdf") 
		if os.path.exists("tmp.pdf"):
			os.remove("tmp.pdf") 	
		self.Show(False)
		self.Destroy()    


damit klappt es super :-)
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Diese Zuweisung ist natürlich unnötig

Code: Alles auswählen

outputStream=temp_file
Du kannst ja schon beim ``with`` den gewünschten Variablenname angeben.
Außerdem solltest du dich an die PEP8 halten. Variablennamen schreibt man ``klein_mit_unterstrich`` und Klassen ``CamelCase``
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

ice2k3 hat geschrieben:Diese Zuweisung ist natürlich unnötig

Code: Alles auswählen

outputStream=temp_file
Außerdem solltest du dich an die PEP8 halten. Variablennamen schreibt man ``klein_mit_unterstrich`` und Klassen ``CamelCase``

hab ich von
http://pybrary.net/pyPdf/

den Beispielcode, aber danke für den Hinweis.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Leider halten sich viele Module nicht an diese Namenskonventionen, sogar in der Standardbibliothek (bei Python 2.x).
Antworten