Ajouter du texte à un PDF existant à l'aide de Python

107

Je dois ajouter du texte supplémentaire à un PDF existant en utilisant Python, quelle est la meilleure façon de procéder et quels modules supplémentaires dois-je installer.

Remarque: Idéalement, j'aimerais pouvoir l'exécuter à la fois sur Windows et Linux, mais à la fois, seul Linux fera l'affaire.

Edit: pyPDF et ReportLab ont l' air bien mais aucun ne me permettra de modifier un PDF existant, y a-t-il d'autres options?

Frozenskys
la source

Réponses:

88

Je sais que c'est un article plus ancien, mais j'ai passé beaucoup de temps à essayer de trouver une solution. J'en ai rencontré un décent en utilisant uniquement ReportLab et PyPDF, alors j'ai pensé partager:

  1. lisez votre PDF en utilisant PdfFileReader(), nous appellerons cette entrée
  2. créez un nouveau pdf contenant votre texte à ajouter à l'aide de ReportLab, enregistrez-le en tant qu'objet chaîne
  3. lire l'objet string en utilisant PdfFileReader(), nous appellerons ce texte
  4. créer un nouvel objet PDF en utilisant PdfFileWriter(), nous appellerons cette sortie
  5. Parcourez l' entrée et appliquez .mergePage(*text*.getPage(0))pour chaque page à laquelle vous souhaitez ajouter le texte, puis utilisez output.addPage()pour ajouter les pages modifiées à un nouveau document

Cela fonctionne bien pour les ajouts de texte simples. Voir l'exemple de PyPDF pour le filigrane d'un document.

Voici un code pour répondre à la question ci-dessous:

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

De là, vous pouvez fusionner les pages du fichier d'entrée avec un autre document.

dwelch
la source
2
"créez un nouveau pdf contenant votre texte à ajouter en utilisant ReportLab, enregistrez-le en tant qu'objet chaîne" Comment faites-vous cela? C'est une instance de canevas.
Lakshman Prasad
1
J'ai ajouté un exemple de code ci-dessus pour répondre à la question de Lakshman.
dwelch
Je recommande d'utiliser PyPDF2 car il est plus mis à jour, vérifiez également leur exemple de code: github.com/mstamy2/PyPDF2/blob/…
blaze
2
Ce code créera un nouveau fichier pdf et ignorera toutes les métadonnées. Il ne s'ajoute donc pas au pdf existant.
Anton Kukoba
125

Exemple pour [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()

Exemple pour 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()
David Dehghan
la source
13
Pour python3, le paquet doit être io.BytesIOet utiliser PyPDF2 plutôt que pyPDF (qui n'est pas maintenu). Très bonne réponse!
Noufal Ibrahim
4
Merci d'avoir partagé. Cela fonctionne très bien. Une note: je pense qu'il vaut mieux utiliser openau lieu de file.
mitenka le
Je pense que c'est une réponse plus acceptable, d'autant plus qu'elle comprend un exemple concret.
Casey
1
Attention: le nouveau document ne comprend que la première page de l'original! Il est assez facile de copier le reste des pages de existing_pdfà output, l'exemple de code ne le fait pas.
alexis
@alexis: Comment modifieriez-vous le code pour mettre quelque chose sur la deuxième page du pdf? J'ai un formulaire qui utilise deux pages et je suis bloqué sur la première page. Merci d'avance.
DavidV
11

pdfrw vous permettra de lire des pages à partir d'un PDF existant et de les dessiner sur un canevas reportlab (comme pour dessiner une image). Il y a des exemples pour cela dans le sous-répertoire pdfrw examples / rl1 sur github. Avertissement: je suis l'auteur de pdfrw.

Patrick Maupin
la source
Je pense que vous pourriez mettre un lien là
The6thSense
Bon point! Je n'avais pas fait beaucoup de trucs SO quand j'ai posté ça, et j'étais préoccupé par la "politique de texte minimal plus lien". (Mon représentant n'avait que 46 ans à l'époque, et l'IIRC je venais de recevoir un -2 sur une réponse, donc j'étais un peu inquiet des nouvelles réponses à des questions de 5 ans :)
Patrick Maupin
les vieilles questions
reçoivent
FWIW, il y a d'autres exemples reportlab / pdfrw si vous commencez à suivre ce lien . J'ai répondu là, basé sur une réponse dans la cible dupe.
Patrick Maupin
7

En tirant parti de la réponse de David Dehghan ci-dessus, les travaux suivants fonctionnent en 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()
Ross Smith II
la source
3

cpdf fera le travail à partir de la ligne de commande. Ce n'est pas du python, cependant (afaik):

cpdf -add-text "Line of text" input.pdf -o output .pdf
user2243670
la source
0

Vous aurez peut-être plus de chance de résoudre le problème en convertissant le PDF en un format modifiable, en écrivant vos modifications, puis en le reconvertissant en PDF. Je ne connais pas de bibliothèque qui vous permet d'éditer directement un PDF mais il existe de nombreux convertisseurs entre DOC et PDF par exemple.

aehlke
la source
1
Le problème est que je n'ai que la source en PDF (d'un tiers) et PDF -> DOC -> PDF perdra beaucoup dans la conversion. J'ai également besoin de cela pour fonctionner sous Linux, donc DOC n'est peut-être pas le meilleur choix.
Frozenskys
Je pense qu'Adobe maintient la capacité d'édition de PDF assez fermée et propriétaire afin qu'ils puissent vendre des licences pour leurs meilleures versions d'Acrobat. Vous pouvez peut-être trouver un moyen d'automatiser l'utilisation d'Acrobat Pro pour le modifier, en utilisant une sorte d'interface de macro.
aehlke
Si les parties sur lesquelles vous voulez écrire sont des champs de formulaire, il existe des interfaces XML pour les éditer - sinon je ne trouve rien.
aehlke
Non, je voulais juste ajouter quelques lignes de texte à chaque page.
Frozenskys
0

Si vous êtes sous Windows, cela peut fonctionner:

Pilote PDF Creator

Il existe également un livre blanc sur un cadre de création et d'édition de PDF en Python. C'est un peu daté, mais peut peut-être vous donner des informations utiles:

Utilisation de Python comme cadre d'édition et de traitement de PDF

thedz
la source
Le livre blanc a l'air bien mais est un peu léger sur le code, et je n'ai pas vraiment les ressources pour implémenter tout un cadre PDF moi-même! ;)
Frozenskys
-4

Avez-vous essayé pyPdf ?

Désolé, il n'a pas la possibilité de modifier le contenu d'une page.

Zoman
la source
On dirait que cela pourrait fonctionner, est-ce que quelqu'un l'a utilisé? À quoi ressemble l'utilisation de la mémoire?
Frozenskys
Il a la capacité d'ajouter un filigrane de texte et s'il était correctement formaté, cela pourrait fonctionner.
Frozenskys