Seite 1 von 1

Text in vorhandene pdf einfügen

Verfasst: Mittwoch 4. November 2009, 14:42
von mathi
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...

Verfasst: Mittwoch 4. November 2009, 15:18
von cofi
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?

Verfasst: Mittwoch 4. November 2009, 15:19
von mathi
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:

Verfasst: Mittwoch 4. November 2009, 15:24
von CM
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

Verfasst: Mittwoch 4. November 2009, 15:37
von mathi
uffff :?

aber erstmal danke...

Verfasst: Mittwoch 4. November 2009, 16:32
von 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ß

Verfasst: Donnerstag 5. November 2009, 15:13
von mathi
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 

Verfasst: Donnerstag 5. November 2009, 18:17
von 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ß

Verfasst: Donnerstag 5. November 2009, 19:45
von mathi
die Einrückung hat gefehlt, das habe ich übersehen, ich habs im obigen Post geändert, :oops:

Verfasst: Donnerstag 5. November 2009, 19:46
von mathi
problembär hat geschrieben:....., daß Dein Skript noch irgendwie darauf zugreift.
na genau da möchte ich ansetzen und diesen Zugriff stoppen....

Verfasst: Donnerstag 5. November 2009, 20:11
von 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.

Verfasst: Donnerstag 5. November 2009, 20:15
von mathi
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

Verfasst: Donnerstag 5. November 2009, 21:38
von ms4py
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.

Verfasst: Donnerstag 5. November 2009, 23:10
von Leonidas
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()``.

Verfasst: Freitag 6. November 2009, 08:31
von mathi
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 :-)

Verfasst: Freitag 6. November 2009, 08:54
von ms4py
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``

Verfasst: Freitag 6. November 2009, 10:07
von mathi
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.

Verfasst: Freitag 6. November 2009, 10:32
von ms4py
Leider halten sich viele Module nicht an diese Namenskonventionen, sogar in der Standardbibliothek (bei Python 2.x).