Crear PDFs en Laravel con Browsershot

Repaso a una alternativa moderna y fácil de usar a DomPDF para la generación de PDFs en PHP.

Crear PDFs en Laravel con Browsershot
Photo by Austin Distel / Unsplash

Aún me acuerdo de usar DomPDF para la generación de PDFs usando PHP. Sin embargo, uno de los problemas más grandes con los que me he encontrado es que no soporta CSS3, solamente hasta CSS2.1. Esto implica que hay características como flex o grid que no podemos usar en los PDF.

Hay casos en los que esto no es un problema (ej. para generar ciertas facturas) pero sinceramente lo veo cada vez un poco más desfasado. Últimamente he estado probando a generar PDFs usando Browsershot y es un gustazo.

Qué es Browsershot

Browsershot es una librería de PHP de Spatie que utiliza un navegador Chrome a través de Puppeteer para sacar screenshots y exportar páginas a PDF. Al usar la última versión de Chrome, se asegura de soportar las características CSS que puedes también imprimir con Chrome (porque generar un PDF lo hace imprimiendo con Ctrl + P y guardando el fichero!).

Cómo generar un PDF con Browsershot

La instalación es bastante sencilla. Primero, hay que instalar Browsershot en nuestro proyecto:

composer require spatie/browsershot

Una vez instalado, tenemos que asegurarnos de tener instalado Puppeteer en nuestro proyecto o, en su defecto, en nuestro sistema:

npm install puppeteer

O, para instalarlo en el sistema:

npm install -g puppeteer

Ahora que ya tenemos todo, solamente tenemos que ir a nuestro controlador y poner el siguiente código:

Browsershot::url('https://raullg.com')
	->save('raullg-com.pdf');

Hay muchas opciones que se le puede pasar a Browsershot, podéis verlas todas aquí.

Usar Browsershot con NVM en Mac

Uno de los problemas con los que me encontré yo cuando utilicé Browsershot es que no detectaba mi binario de node ni de npm, ya que mi instalación de Node está hecha a través de NVM, para poder tener varias versiones corriendo a la vez.

La forma de solucionar este problema en local es a través de los métodos setNodeBinary y setNpmBinary:

Browsershot::url('https://raullg.com')
    ->setNodeBinary('/usr/local/bin/node')
    ->setNpmBinary('/usr/local/bin/npm')
    ->save('raullg-com.pdf');

Para sacar la ruta correcta de tu versión de node y npm puedes ejecutar which en tu ordenador:

which npm
which node