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?

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.


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()

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.


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()

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

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.


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


-4

¿Has probado pyPdf ?

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.