Guía de Procesamiento de PDF
Resumen
Esta guía cubre las operaciones esenciales de procesamiento de PDF utilizando bibliotecas de Python y herramientas de línea de comandos. Para características 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 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
# Agregar texto
c.drawString(100, height - 100, "¡Hola Mundo!")
c.drawString(100, height - 120, "Este es un PDF creado con reportlab")
# Agregar una línea
c.line(100, height - 140, 400, height - 140)
# Guardar
c.save()
Crear PDF con Varias 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 integradas no incluyen estos glifos, lo que hace que se muestren como cuadros negros sólidos.
En su lugar, usa las etiquetas de marcado 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 con canvas (no objetos Paragraph), ajusta manualmente el tamaño de la fuente y la posición 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 a 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: uv pip install pytesseract pdf2image
import pytesseract
from pdf2image import convert_from_path
# Convertir PDF a imágenes
images = convert_from_path('scanned.pdf')
# OCR de 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 una 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 |
| Fusionar desde línea de comandos | qpdf | qpdf --empty --pages ... |
| OCR de 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
Esta habilidad es creada y mantenida por Anthropic. Incluida aquí sin modificaciones, excepto por los metadatos del frontmatter y la capitalización de los enlaces a reference.md/forms.md, que en el repositorio original están en mayúsculas; consulta LICENSE.txt para los términos.