# Issue #009: PDF Generation **Tipo**: Enhancement **Prioridad**: Media **Estado**: Pendiente ## Descripción Implementar generación de PDFs de páginas web, similar a "Imprimir a PDF" del navegador. ## Funcionalidad deseada ### Operaciones básicas - Generar PDF de página completa - Generar PDF de página actual (viewport) - Control de formato de página (A4, Letter, etc.) - Orientación (portrait/landscape) - Márgenes personalizables - Headers y footers personalizados - Background graphics (imágenes de fondo) - Scale/zoom del contenido ### Operaciones avanzadas - Rangos de páginas específicos - Números de página - Fecha/hora en header/footer - CSS para medios de impresión - Protección de PDF (opcional) ## Implementación técnica ### Archivo sugerido `pkg/browser/pdf.go` ### CDP Method **Page.printToPDF** - Genera PDF de la página ### API propuesta ```go // PDFFormat formato de papel type PDFFormat string const ( PDFFormatA4 PDFFormat = "A4" PDFFormatLetter PDFFormat = "Letter" PDFFormatLegal PDFFormat = "Legal" PDFFormatA3 PDFFormat = "A3" PDFFormatTabloid PDFFormat = "Tabloid" ) // PDFOrientation orientación de página type PDFOrientation string const ( PDFOrientationPortrait PDFOrientation = "portrait" PDFOrientationLandscape PDFOrientation = "landscape" ) // PDFMargins márgenes del PDF type PDFMargins struct { Top float64 // En pulgadas Right float64 Bottom float64 Left float64 } // PDFOptions opciones para generación de PDF type PDFOptions struct { // Formato de papel Format PDFFormat // Default: A4 // Orientación Orientation PDFOrientation // Default: portrait // Dimensiones personalizadas (en pulgadas) // Si se especifica, ignora Format Width float64 Height float64 // Márgenes (en pulgadas) Margins PDFMargins // Default: 1cm todos // Scale del contenido (0.1 - 2.0) Scale float64 // Default: 1.0 // Incluir colores y gráficos de fondo PrintBackground bool // Default: false // Rango de páginas (ej: "1-5, 8, 11-13") PageRanges string // Header template (HTML) HeaderTemplate string // Footer template (HTML) FooterTemplate string // Mostrar header y footer DisplayHeaderFooter bool // Preferir CSS para @media print PreferCSSPageSize bool // Generar PDFs etiquetados (accesibilidad) GenerateTaggedPDF bool } // DefaultPDFOptions retorna opciones por defecto func DefaultPDFOptions() *PDFOptions // GeneratePDF genera un PDF de la página actual func (b *Browser) GeneratePDF(ctx context.Context, opts *PDFOptions) ([]byte, error) // SavePDF genera y guarda PDF a archivo func (b *Browser) SavePDF(ctx context.Context, filepath string, opts *PDFOptions) error // PrintToPDF genera PDF (alias de GeneratePDF) func (b *Browser) PrintToPDF(ctx context.Context, opts *PDFOptions) ([]byte, error) ``` ## Casos de uso ### Caso 1: PDF simple ```go // PDF con opciones por defecto (A4, portrait) pdf, _ := b.GeneratePDF(ctx, nil) os.WriteFile("page.pdf", pdf, 0644) ``` ### Caso 2: PDF con configuración personalizada ```go opts := &browser.PDFOptions{ Format: browser.PDFFormatLetter, Orientation: browser.PDFOrientationLandscape, PrintBackground: true, // Incluir colores de fondo Scale: 0.8, // 80% del tamaño Margins: browser.PDFMargins{ Top: 0.5, Right: 0.5, Bottom: 0.5, Left: 0.5, }, } pdf, _ := b.GeneratePDF(ctx, opts) ``` ### Caso 3: PDF con header y footer ```go opts := &browser.PDFOptions{ DisplayHeaderFooter: true, HeaderTemplate: `
Elemento ' + i + '
'; } `) // Generar PDF pdf, _ := b.GeneratePDF(ctx, nil) ``` ### Batch PDF generation ```go urls := []string{ "https://example.com/page1", "https://example.com/page2", "https://example.com/page3", } for i, url := range urls { b.Navigate(ctx, url, nil) b.WaitForNavigation(ctx, nil) filename := fmt.Sprintf("page_%d.pdf", i+1) b.SavePDF(ctx, filename, nil) } ``` ## Consideraciones ### Tamaño del PDF - PDFs grandes pueden exceder límite de respuesta CDP - Usar streaming para PDFs > 10MB (no implementado en v1) ### Performance - Generación de PDF es **bloqueante** - Puede tomar varios segundos para páginas grandes - Considerar timeout apropiado ### Calidad - Images embebidas mantienen su resolución - Fonts pueden no incluirse (usar web fonts) - JavaScript no se ejecuta durante generación ### Headless mode - PDF generation funciona mejor en headless - Algunas páginas pueden requerir modo visible ## Referencias - CDP Page.printToPDF: https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF - Chrome printing: https://developer.chrome.com/docs/chromium/print-previews - Playwright PDF: https://playwright.dev/docs/api/class-page#page-pdf - Puppeteer PDF: https://pptr.dev/api/puppeteer.page.pdf