Aggiungi testo al PDF esistente utilizzando Python


107

Ho bisogno di aggiungere del testo extra a un PDF esistente usando Python, qual è il modo migliore per farlo e quali moduli extra dovrò installare.

Nota: idealmente mi piacerebbe essere in grado di eseguirlo sia su Windows che su Linux, ma solo Linux lo farà.

Modifica: pyPDF e ReportLab sembrano buoni ma nessuno dei due mi permetterà di modificare un PDF esistente, ci sono altre opzioni?

Risposte:


88

So che questo è un post precedente, ma ho passato molto tempo a cercare una soluzione. Ne ho trovato uno decente usando solo ReportLab e PyPDF, quindi ho pensato di condividere:

  1. leggi il tuo PDF usando PdfFileReader(), chiameremo questo input
  2. crea un nuovo pdf contenente il tuo testo da aggiungere usando ReportLab, salvalo come oggetto stringa
  3. leggi l'oggetto stringa usando PdfFileReader(), chiameremo questo testo
  4. creare un nuovo oggetto PDF utilizzando PdfFileWriter(), chiameremo questo output
  5. iterare attraverso l' input e applicare .mergePage(*text*.getPage(0))per ogni pagina a cui si desidera aggiungere il testo, quindi utilizzare output.addPage()per aggiungere le pagine modificate a un nuovo documento

Funziona bene per semplici aggiunte di testo. Vedere l'esempio di PyPDF per la filigrana di un documento.

Ecco del codice per rispondere alla domanda seguente:

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

Da qui puoi unire le pagine del file di input con un altro documento.


2
"crea un nuovo pdf contenente il tuo testo da aggiungere utilizzando ReportLab, salvalo come oggetto stringa" Come si fa? È un'istanza di tela.
Lakshman Prasad

1
Ho aggiunto del codice di esempio sopra per rispondere alla domanda di Lakshman.
dwelch

Consiglio di utilizzare PyPDF2 poiché è più aggiornato, controlla anche il loro codice di esempio: github.com/mstamy2/PyPDF2/blob/…
blaze

2
Questo codice creerà un nuovo file pdf e salterà tutti i metadati. Quindi non si aggiunge al PDF esistente.
Anton Kukoba

125

Esempio per [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()

Esempio per 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
Per python3, il pacchetto dovrebbe essere io.BytesIOe utilizzare PyPDF2 invece di pyPDF (che non è mantenuto). Bella risposta!
Noufal Ibrahim

4
Grazie per la condivisione. Funziona benissimo. Una nota: credo che sia meglio usare openinvece di file.
mitenka

Credo che questa sia una risposta più accettabile, soprattutto perché include un esempio funzionante.
Casey

1
Attenzione: il nuovo documento include solo la prima pagina dell'originale! È abbastanza facile copiare il resto delle pagine da existing_pdfa output, il codice di esempio semplicemente no.
alexis

@alexis: come modificheresti il ​​codice per inserire qualcosa nella seconda pagina del pdf? Ho un modulo che utilizza due pagine e sono bloccato sulla prima pagina. Grazie in anticipo.
DavidV

11

pdfrw ti consentirà di leggere pagine da un PDF esistente e di disegnarle su una tela di reportlab (simile al disegno di un'immagine). Ci sono esempi per questo nella sottodirectory pdfrw examples / rl1 su GitHub. Disclaimer: sono l'autore di pdfrw.


Penso che potresti mettere un link lì
The6thSense

Buon punto! Non avevo fatto molte cose SO quando l'ho postato ed ero preoccupato per il "testo minimo più la politica di collegamento". (Il mio rappresentante era solo 46 all'epoca e IIRC avevo appena ricevuto un -2 su una risposta, quindi ero un po 'preoccupato per le nuove risposte alle domande di 5 anni :)
Patrick Maupin

le vecchie domande hanno più visibilità :) e attenzione
The6thSense

FWIW, ci sono altri esempi di reportlab / pdfrw se inizi a seguire questo link . Ho risposto lì, sulla base di una risposta nel bersaglio duplicato.
Patrick Maupin

7

Sfruttando la risposta di David Dehghan sopra, il seguente funziona 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 farà il lavoro dalla riga di comando. Non è pitone, però (afaik):

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

0

Potresti avere più fortuna a scomporre il problema convertendo il PDF in un formato modificabile, scrivendo le modifiche, quindi riconvertendolo in PDF. Non conosco una libreria che ti consenta di modificare direttamente il PDF, ma ad esempio ci sono molti convertitori tra DOC e PDF.


1
Il problema è che ho solo la fonte in PDF (da una terza parte) e PDF -> DOC -> PDF perderà molto nella conversione. Inoltre ho bisogno di questo per funzionare su Linux, quindi DOC potrebbe non essere la scelta migliore.
Frozenskys

Credo che Adobe mantenga la capacità di modifica dei PDF piuttosto chiusa e proprietaria in modo che possano vendere le licenze per le loro versioni migliori di Acrobat. Forse puoi trovare un modo per automatizzare l'uso di Acrobat Pro per modificarlo, utilizzando una sorta di interfaccia macro.
aehlke

Se le parti su cui vuoi scrivere sono campi modulo, ci sono interfacce XML per modificarle, altrimenti non riesco a trovare nulla.
aehlke

No, volevo solo aggiungere poche righe di testo a ogni pagina.
Frozenskys


-4

Hai provato pyPdf ?

Spiacenti, non è in grado di modificare il contenuto di una pagina.


Sembra che potrebbe funzionare, qualcuno l'ha usato? Com'è l'utilizzo della memoria?
Frozenskys

Ha la capacità di aggiungere una filigrana di testo e se è stata formattata correttamente potrebbe funzionare.
Frozenskys
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.