name: pdf description: Usa este skill cada vez que el usuario quiera hacer algo con archivos PDF. Esto incluye leer o extraer texto/tablas de PDFs, combinar o fusionar múltiples PDFs en uno solo, dividir PDFs, rotar páginas, añadir marcas de agua, crear nuevos PDFs, rellenar formularios PDF, cifrar/descifrar PDFs, extraer imágenes y OCR en PDFs escaneados para hacerlos buscables. Si el usuario menciona un archivo .pdf o pide producir uno, usa este skill. license: Propietaria. LICENSE.txt contiene los términos completos
Guía de Procesamiento de PDFs
Resumen
Esta guía cubre operaciones esenciales de procesamiento de PDFs utilizando librerías de Python y herramientas de línea de comandos. Para funciones avanzadas, librerías 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
lector = PdfReader("documento.pdf")
print(f"Páginas: {len(lector.pages)}")
# Extraer texto
texto = ""
for pagina in lector.pages:
texto += pagina.extract_text()
Librerías de Python
pypdf - Operaciones Básicas
Fusionar PDFs
from pypdf import PdfWriter, PdfReader
escritor = PdfWriter()
for archivo_pdf in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
lector = PdfReader(archivo_pdf)
for pagina in lector.pages:
escritor.add_page(pagina)
with open("fusionado.pdf", "wb") as salida:
escritor.write(salida)
Dividir PDF
lector = PdfReader("entrada.pdf")
for i, pagina in enumerate(lector.pages):
escritor = PdfWriter()
escritor.add_page(pagina)
with open(f"pagina_{i+1}.pdf", "wb") as salida:
escritor.write(salida)
Extraer Metadatos
lector = PdfReader("documento.pdf")
meta = lector.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
lector = PdfReader("entrada.pdf")
escritor = PdfWriter()
pagina = lector.pages[0]
pagina.rotate(90) # Rotar 90 grados en sentido horario
escritor.add_page(pagina)
with open("rotado.pdf", "wb") as salida:
escritor.write(salida)
pdfplumber - Extracción de Texto y Tablas
Extraer Texto con Diseño
import pdfplumber
with pdfplumber.open("documento.pdf") as pdf:
for pagina in pdf.pages:
texto = pagina.extract_text()
print(texto)
Extraer Tablas
with pdfplumber.open("documento.pdf") as pdf:
for i, pagina in enumerate(pdf.pages):
tablas = pagina.extract_tables()
for j, tabla in enumerate(tablas):
print(f"Tabla {j+1} en la página {i+1}:")
for fila in tabla:
print(fila)
Extracción Avanzada de Tablas
import pandas as pd
with pdfplumber.open("documento.pdf") as pdf:
todas_tablas = []
for pagina in pdf.pages:
tablas = pagina.extract_tables()
for tabla in tablas:
if tabla: # Verificar si la tabla no está vacía
df = pd.DataFrame(tabla[1:], columns=tabla[0])
todas_tablas.append(df)
# Combinar todas las tablas
if todas_tablas:
df_combinado = pd.concat(todas_tablas, ignore_index=True)
df_combinado.to_excel("tablas_extraidas.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("hola.pdf", pagesize=letter)
ancho, alto = letter
# Añadir texto
c.drawString(100, alto - 100, "¡Hola Mundo!")
c.drawString(100, alto - 120, "Este es un PDF creado con reportlab")
# Añadir una línea
c.line(100, alto - 140, 400, alto - 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("informe.pdf", pagesize=letter)
estilos = getSampleStyleSheet()
contenido = []
# Añadir contenido
titulo = Paragraph("Título del Informe", estilos['Title'])
contenido.append(titulo)
contenido.append(Spacer(1, 12))
cuerpo = Paragraph("Este es el cuerpo del informe. " * 20, estilos['Normal'])
contenido.append(cuerpo)
contenido.append(PageBreak())
# Página 2
contenido.append(Paragraph("Página 2", estilos['Heading1']))
contenido.append(Paragraph("Contenido para la página 2", estilos['Normal']))
# Construir PDF
doc.build(contenido)
Subíndices y Superíndices
IMPORTANTE: Nunca uses caracteres Unicode de subíndice/superíndice (₀₁₂₃₄₅₆₇₈₉, ⁰¹²³⁴⁵⁶⁷⁸⁹) en PDFs de ReportLab. Las fuentes integradas no incluyen estos glifos, lo que provoca que se rendericen como cuadros negros sólidos.
En su lugar, utiliza las etiquetas XML de ReportLab en objetos Paragraph:
from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet
estilos = getSampleStyleSheet()
# Subíndices: usar etiqueta <sub>
quimico = Paragraph("H<sub>2</sub>O", estilos['Normal'])
# Superíndices: usar etiqueta <super>
al_cuadrado = Paragraph("x<super>2</super> + y<super>2</super>", estilos['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 entrada.pdf salida.txt
# Extraer texto conservando el diseño
pdftotext -layout entrada.pdf salida.txt
# Extraer páginas específicas
pdftotext -f 1 -l 5 entrada.pdf salida.txt # Páginas 1-5
qpdf
# Fusionar PDFs
qpdf --empty --pages archivo1.pdf archivo2.pdf -- fusionado.pdf
# Dividir páginas
qpdf entrada.pdf --pages . 1-5 -- paginas1-5.pdf
qpdf entrada.pdf --pages . 6-10 -- paginas6-10.pdf
# Rotar páginas
qpdf entrada.pdf salida.pdf --rotate=+90:1 # Rotar página 1 90 grados
# Eliminar contraseña
qpdf --password=micontraseña --decrypt cifrado.pdf descifrado.pdf
pdftk (si está disponible)
# Fusionar
pdftk archivo1.pdf archivo2.pdf cat output fusionado.pdf
# Dividir
pdftk entrada.pdf burst
# Rotar
pdftk entrada.pdf rotate 1east output rotado.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
imagenes = convert_from_path('escaneado.pdf')
# OCR en cada página
texto = ""
for i, imagen in enumerate(imagenes):
texto += f"Página {i+1}:\n"
texto += pytesseract.image_to_string(imagen)
texto += "\n\n"
print(texto)
Añadir Marca de Agua
from pypdf import PdfReader, PdfWriter
# Crear marca de agua (o cargar existente)
marca_agua = PdfReader("marca_agua.pdf").pages[0]
# Aplicar a todas las páginas
lector = PdfReader("documento.pdf")
escritor = PdfWriter()
for pagina in lector.pages:
pagina.merge_page(marca_agua)
escritor.add_page(pagina)
with open("marcado.pdf", "wb") as salida:
escritor.write(salida)
Extraer Imágenes
# Usando pdfimages (poppler-utils)
pdfimages -j entrada.pdf prefijo_salida
# Esto extrae todas las imágenes como prefijo_salida-000.jpg, prefijo_salida-001.jpg, etc.
Protección con Contraseña
from pypdf import PdfReader, PdfWriter
lector = PdfReader("entrada.pdf")
escritor = PdfWriter()
for pagina in lector.pages:
escritor.add_page(pagina)
# Añadir contraseña
escritor.encrypt("contraseña_usuario", "contraseña_propietario")
with open("cifrado.pdf", "wb") as salida:
escritor.write(salida)
Referencia Rápida
| Tarea | Mejor Herramienta | Comando/Código |
|---|---|---|
| Fusionar PDFs | pypdf | escritor.add_page(pagina) |
| Dividir PDFs | pypdf | Una página por archivo |
| Extraer texto | pdfplumber | pagina.extract_text() |
| Extraer tablas | pdfplumber | pagina.extract_tables() |
| Crear PDFs | reportlab | Canvas o Platypus |
| Fusión en línea de comandos | qpdf | qpdf --empty --pages ... |
| OCR en 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 librerías 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