Un CV en PDF real (no imagen) con window.print

Documento PDF con texto seleccionable frente a una captura de imagen
Documento PDF con texto seleccionable frente a una captura de imagen

Muchos CVs web se exportan como imagen (html2canvas → PDF). Se ven bien, pero tienen un problema serio: un ATS (el filtro automático de recruiting) no puede leer una imagen. Tu experiencia acaba siendo un .png invisible para quien decide si pasas el primer corte. Quería lo contrario: un PDF de texto real, seleccionable y parseable, sin librerías.

El truco: window.print() + @media print

No hace falta generar el PDF a mano. El navegador ya sabe: el botón de descarga solo llama a imprimir, y el usuario elige “Guardar como PDF”.

<button type="button" data-no-print onclick="window.print()">
  Descargar PDF
</button>

La clave está en el CSS de impresión. Con @page fijo el tamaño y quito el margen del navegador (eso elimina la cabecera/pie con la URL y la fecha que mete Chrome):

@page {
  size: A4;
  margin: 0;
}

Forzar la paleta clara y ocultar lo que no va al papel

La web es dark; el PDF debe ser claro. En @media print redefino las variables de color y oculto todo lo que no es el CV: el header, el footer y cualquier cosa marcada como data-no-print (el propio botón, banners, etc.):

@media print {
  :root,
  .dark {
    --color-background: #ffffff;
    --color-foreground: #101216;
  }
  #header,
  footer,
  [data-no-print] {
    display: none !important;
  }
}

Que no corte mal entre páginas

El último detalle es evitar que una sección quede partida con el título huérfano al pie. Con break-inside: avoid en cada bloque, si no cabe, salta entero a la página siguiente:

#resume-content > section {
  break-inside: avoid;
}

Conclusión

window.print() + @media print + @page dan un PDF de texto real, sin html2canvas ni librerías de PDF, y con una ventaja concreta: un ATS lo lee. Para un CV, que es exactamente lo que un ATS va a procesar, es la diferencia entre pasar el filtro o no.