Agregar texto a PDF existente usando Python

106

Necesito agregar algo de texto adicional a un PDF existente usando Python, cuál es la mejor manera de hacerlo y qué módulos adicionales necesitaré instalar.

Nota: Idealmente, me gustaría poder ejecutar esto tanto en Windows como en Linux, pero en un empujón solo Linux servirá.

Editar: pyPDF y ReportLab se ven bien, pero ninguno me permitirá editar un PDF existente, ¿hay otras opciones?

Frozenskys
fuente

Respuestas:

88

Sé que esta es una publicación anterior, pero pasé mucho tiempo tratando de encontrar una solución. Me encontré con uno decente usando solo ReportLab y PyPDF, así que pensé en compartir:

  1. lea su PDF usando PdfFileReader(), llamaremos a esta entrada
  2. cree un nuevo pdf que contenga su texto para agregar usando ReportLab, guárdelo como un objeto de cadena
  3. leer el objeto de cadena usando PdfFileReader(), llamaremos a este texto
  4. crear un nuevo objeto PDF usando PdfFileWriter(), llamaremos a esta salida
  5. iterar a través de la entrada y aplicar .mergePage(*text*.getPage(0))para cada página a la que desea agregar el texto, luego usar output.addPage()para agregar las páginas modificadas a un nuevo documento

Esto funciona bien para adiciones de texto simples. Consulte el ejemplo de PyPDF para marcar un documento con una marca de agua.

Aquí hay un código para responder la siguiente pregunta:

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

Desde aquí puede fusionar las páginas del archivo de entrada con otro documento.

morar
fuente
2
"cree un nuevo pdf que contenga su texto para agregar usando ReportLab, guárdelo como un objeto de cadena" ¿Cómo se hace eso? Es una instancia de lienzo.
Lakshman Prasad
1
Agregué un código de muestra arriba para responder a la pregunta de Lakshman.
habita el
Recomiendo usar PyPDF2 ya que está más actualizado, también verifique su código de muestra: github.com/mstamy2/PyPDF2/blob/…
blaze
2
Este código creará un nuevo archivo pdf y omitirá todos los metadatos. Por lo tanto, no se agrega a un PDF existente.
Anton Kukoba
124

Ejemplo de [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()

Ejemplo de 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
fuente
13
Para python3, el paquete debe ser io.BytesIOy usar PyPDF2 en lugar de pyPDF (que no se mantiene). ¡Gran respuesta!
Noufal Ibrahim
4
Gracias por compartir. Funciona muy bien. Una nota: creo que es mejor usar en openlugar de file.
mitenka
Creo que esta es una respuesta más aceptable, especialmente porque incluye un ejemplo práctico.
Casey
1
Atención: ¡el nuevo documento solo incluye la primera página del original! Es bastante fácil copiar el resto de las páginas de existing_pdfa output, el código de muestra simplemente no lo hace.
Alexis
@alexis: ¿Cómo modificaría el código para poner algo en la segunda página del pdf? Tengo un formulario que usa dos páginas y estoy atascado en la primera página. Gracias por adelantado.
DavidV
11

pdfrw le permitirá leer páginas de un PDF existente y dibujarlas en un lienzo de reportlab (similar a dibujar una imagen). Hay ejemplos de esto en el subdirectorio pdfrw examples / rl1 en github. Descargo de responsabilidad: soy el autor de pdfrw.

Patrick Maupin
fuente
Creo que podría poner un enlace allí
The6thSense
¡Buen punto! No había hecho mucho SO cuando publiqué eso, y estaba preocupado por la "política de texto mínimo más enlaces". (Mi representante era solo 46 en ese momento, y el IIRC acababa de recibir un -2 en una respuesta, así que estaba un poco preocupado por las nuevas respuestas a las preguntas de 5 años :)
Patrick Maupin
las viejas preguntas obtienen más vista :) y atención
The6thSense
FWIW, hay algunos ejemplos más de reportlab / pdfrw si comienza a seguir este enlace . Respondí allí, basado en una respuesta en el objetivo engañado.
Patrick Maupin
7

Aprovechando la respuesta de David Dehghan anterior, lo siguiente funciona 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
fuente
3

cpdf hará el trabajo desde la línea de comandos. Sin embargo, no es python (afaik):

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

Es posible que tenga más suerte descomponiendo el problema en convertir PDF a un formato editable, escribir sus cambios y luego convertirlo nuevamente en PDF. No conozco una biblioteca que le permita editar PDF directamente, pero hay muchos convertidores entre DOC y PDF, por ejemplo.

aehlke
fuente
1
El problema es que solo tengo la fuente en PDF (de un tercero) y PDF -> DOC -> PDF perderá mucho en la conversión. También necesito que esto se ejecute en Linux, por lo que es posible que DOC no sea la mejor opción.
Frozenskys
Creo que Adobe mantiene la capacidad de edición de PDF bastante cerrada y patentada para que puedan vender licencias para sus mejores versiones de Acrobat. Tal vez pueda encontrar una manera de automatizar el uso de Acrobat Pro para editarlo, utilizando algún tipo de interfaz de macro.
aehlke
Si las partes en las que desea escribir son campos de formulario, hay interfaces XML para editarlas; de lo contrario, no puedo encontrar nada.
aehlke
No, solo quería agregar algunas líneas de texto a cada página.
Frozenskys
0

Si está en Windows, esto podría funcionar:

Piloto de PDF Creator

También hay un documento técnico de un marco de creación y edición de PDF en Python. Está un poco anticuado, pero quizás pueda darte información útil:

Uso de Python como marco de procesamiento y edición de PDF

thedz
fuente
El documento técnico se ve bien, pero es un poco ligero en código, ¡y realmente no tengo los recursos para implementar un marco PDF completo yo mismo! ;)
Frozenskys
-4

¿Has probado pyPdf ?

Lo sentimos, no tiene la capacidad de modificar el contenido de una página.

Zoman
fuente
Parece que eso podría funcionar, ¿alguien lo ha usado? ¿Cómo es el uso de la memoria?
Frozenskys
Tiene la capacidad de agregar una marca de agua de texto y, si se formateó correctamente, podría funcionar.
Frozenskys