Guía de Procesamiento de PDFs
Resumen
Esta guía cubre operaciones esenciales de procesamiento de PDFs utilizando bibliotecas de Python y herramientas de línea de comandos. Para funciones avanzadas, bibliotecas de JavaScript y ejemplos detallados, consulta REFERENCE.md. Si necesitas rellenar un formulario PDF, lee FORMS.md y sigue sus instrucciones.
Inicio Rápido
from pypdf import PdfReader, PdfWriter
# Leer un PDF
reader = PdfReader("document.pdf")
print(f"Páginas: {len(reader.pages)}")
# Extraer texto
text = ""
for page in reader.pages:
text += page.extract_text()
Bibliotecas de Python
pypdf - Operaciones Básicas
Fusionar PDFs
from pypdf import PdfWriter, PdfReader
writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("merged.pdf", "wb") as output:
writer.write(output)
Dividir PDF
reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as output:
writer.write(output)
Extraer Metadatos
reader = PdfReader("document.pdf")
meta = reader.metadata
print(f"Título: {meta.title}")
print(f"Autor: {meta.author}")
print(f"Asunto: {meta.subject}")
print(f"Creador: {meta.creator}")
Rotar Páginas
reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(90) # Rotar 90 grados en sentido horario
writer.add_page(page)
with open("rotated.pdf", "wb") as output:
writer.write(output)
pdfplumber - Extracción de Texto y Tablas
Extraer Texto con Diseño
import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
print(text)
Extraer Tablas
with pdfplumber.open("document.pdf") as pdf:
for i, page in enumerate(pdf.pages):
tables = page.extract_tables()
for j, table in enumerate(tables):
print(f"Tabla {j+1} en la página {i+1}:")
for row in table:
print(row)
Extracción Avanzada de Tablas
import pandas as pd
with pdfplumber.open("document.pdf") as pdf:
all_tables = []
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
if table: # Verificar si la tabla no está vacía
df = pd.DataFrame(table[1:], columns=table[0])
all_tables.append(df)
# Combinar todas las tablas
if all_tables:
combined_df = pd.concat(all_tables, ignore_index=True)
combined_df.to_excel("extracted_tables.xlsx", index=False)
reportlab - Crear PDFs
Creación Básica de PDF
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
c = canvas.Canvas("hello.pdf", pagesize=letter)
width, height = letter
# Añadir texto
c.drawString(100, height - 100, "¡Hola Mundo!")
c.drawString(100, height - 120, "Este es un PDF creado con reportlab")
# Añadir una línea
c.line(100, height - 140, 400, height - 140)
# Guardar
c.save()
Crear PDF con Múltiples Páginas
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("report.pdf", pagesize=letter)
styles = getSampleStyleSheet()
story = []
# Agregar contenido
title = Paragraph("Título del Informe", styles['Title'])
story.append(title)
story.append(Spacer(1, 12))
body = Paragraph("Este es el cuerpo del informe. " * 20, styles['Normal'])
story.append(body)
story.append(PageBreak())
# Página 2
story.append(Paragraph("Página 2", styles['Heading1']))
story.append(Paragraph("Contenido para la página 2", styles['Normal']))
# Construir PDF
doc.build(story)
Subíndices y Superíndices
IMPORTANTE: Nunca uses caracteres Unicode de subíndice/superíndice (₀₁₂₃₄₅₆₇₈₉, ⁰¹²³⁴⁵⁶⁷⁸⁹) en PDFs de ReportLab. Las fuentes incorporadas no incluyen estos glifos, lo que hace que se representen como cuadros negros sólidos.
En su lugar, usa las etiquetas XML de ReportLab en objetos Paragraph:
from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
# Subíndices: usa la etiqueta <sub>
chemical = Paragraph("H<sub>2</sub>O", styles['Normal'])
# Superíndices: usa la etiqueta <super>
squared = Paragraph("x<super>2</super> + y<super>2</super>", styles['Normal'])
Para texto dibujado en canvas (no objetos Paragraph), ajusta manualmente el tamaño y la posición de la fuente en lugar de usar subíndices/superíndices Unicode.
Herramientas de Línea de Comandos
pdftotext (poppler-utils)
# Extraer texto
pdftotext input.pdf output.txt
# Extraer texto preservando el diseño
pdftotext -layout input.pdf output.txt
# Extraer páginas específicas
pdftotext -f 1 -l 5 input.pdf output.txt # Páginas 1-5
qpdf
# Fusionar PDFs
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf
# Dividir páginas
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
qpdf input.pdf --pages . 6-10 -- pages6-10.pdf
# Rotar páginas
qpdf input.pdf output.pdf --rotate=+90:1 # Rotar página 1 90 grados
# Eliminar contraseña
qpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf
pdftk (si está disponible)
# Fusionar
pdftk file1.pdf file2.pdf cat output merged.pdf
# Dividir
pdftk input.pdf burst
# Rotar
pdftk input.pdf rotate 1east output rotated.pdf
Tareas Comunes
Extraer Texto de PDFs Escaneados
# Requiere: pip install pytesseract pdf2image
import pytesseract
from pdf2image import convert_from_path
# Convertir PDF a imágenes
images = convert_from_path('scanned.pdf')
# OCR cada página
text = ""
for i, image in enumerate(images):
text += f"Página {i+1}:\n"
text += pytesseract.image_to_string(image)
text += "\n\n"
print(text)
Agregar Marca de Agua
from pypdf import PdfReader, PdfWriter
# Crear marca de agua (o cargar existente)
watermark = PdfReader("watermark.pdf").pages[0]
# Aplicar a todas las páginas
reader = PdfReader("document.pdf")
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark)
writer.add_page(page)
with open("watermarked.pdf", "wb") as output:
writer.write(output)
Extraer Imágenes
# Usando pdfimages (poppler-utils)
pdfimages -j input.pdf output_prefix
# Esto extrae todas las imágenes como output_prefix-000.jpg, output_prefix-001.jpg, etc.
Protección con Contraseña
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
# Agregar contraseña
writer.encrypt("userpassword", "ownerpassword")
with open("encrypted.pdf", "wb") as output:
writer.write(output)
Referencia Rápida
| Tarea | Mejor Herramienta | Comando/Código |
|---|---|---|
| Fusionar PDFs | pypdf | writer.add_page(page) |
| Dividir PDFs | pypdf | Un archivo por página |
| Extraer texto | pdfplumber | page.extract_text() |
| Extraer tablas | pdfplumber | page.extract_tables() |
| Crear PDFs | reportlab | Canvas o Platypus |
| Fusión en línea de comandos | qpdf | qpdf --empty --pages ... |
| OCR PDFs escaneados | pytesseract | Convertir a imagen primero |
| Rellenar formularios PDF | pdf-lib o pypdf (ver FORMS.md) | Ver FORMS.md |
Próximos Pasos
- Para uso avanzado de pypdfium2, consulta REFERENCE.md
- Para bibliotecas de JavaScript (pdf-lib), consulta REFERENCE.md
- Si necesitas rellenar un formulario PDF, sigue las instrucciones en FORMS.md
- Para guías de solución de problemas, consulta REFERENCE.md