Ir al contenido

Descripción general de NextPDF Artisan

NextPDF Artisan es el puente con Chrome de NextPDF. Envía un fragmento de HTML a un proceso de headless Chrome mediante el Chrome DevTools Protocol, captura la salida de printToPDF e incrusta el resultado en el documento de destino como un Form XObject. El texto incrustado sigue siendo seleccionable y admite búsquedas.

El paquete Artisan (nextpdf/artisan) extiende el motor de código abierto NextPDF con un renderer que delega la maquetación a Chrome. El pipeline HTML nativo de NextPDF ya cubre un amplio subconjunto de CSS. El puente Artisan está pensado para documentos que necesitan una maquetación con calidad de Chrome —flexbox y grid de CSS, fuentes web personalizadas cargadas desde data URIs y selectores complejos— y que, aun así, producen texto vectorial en lugar de una captura de pantalla rasterizada.

El puente es un pipeline de componentes pequeños y de propósito único. ChromeHtmlRenderer orquesta una operación de renderizado. ChromeSecurityPolicy valida la entrada y la envuelve en un documento HTML restringido. BrowserPool gestiona el ciclo de vida del proceso de Chrome. ViewportCalculator mapea los puntos PDF a píxeles CSS. El lector NextPDF\Parser analiza la salida de Chrome, y PageImporter la convierte en un Form XObject. Cada componente es final, recibe sus dependencias por el constructor y está tipado en el nivel 10 de PHPStan.

El puente tiene una dependencia externa obligatoria. Necesita la biblioteca chrome-php/chrome (^1.15) y un binario de Chrome o Chromium que el proceso de PHP pueda encontrar. Ninguno de los dos viene incluido. Cuando la biblioteca no está presente, el puente lanza ChromeNotAvailableException en lugar de degradarse de forma silenciosa; véase /integrations/artisan/failure-modes/ en la página /integrations/artisan/troubleshooting/.

Ningún renderizado llega a Chrome hasta que la entrada pasa ChromeSecurityPolicy::validate(), y el documento que recibe Chrome siempre va envuelto con una Content-Security-Policy estricta y un bloqueo de red mediante CDP como defensa en profundidad. Como el puente procesa HTML potencialmente no confiable, su postura de transporte y aislamiento se documenta de forma explícita en la página /integrations/artisan/security-and-operations/ en lugar de resumirse aquí.

Este es el comportamiento observado del paquete tal como se publica, verificado con src/Artisan/ y la suite tests/Unit/Artisan/. No implica paridad píxel a píxel con un navegador Chrome interactivo: las animaciones se capturan en su fotograma final, la maquetación no depende de JavaScript y solo se importa la primera página de Chrome.

HTML fragment

ChromeSecurityPolicy::validate()

ChromeSecurityPolicy::wrapHtml()

CSP + reset CSS

BrowserPool

headless Chrome

CDP: Network.setBlockedURLs '*'

Page.setDocumentContent

Chrome printToPDF

NextPDF\\Parser\\PdfReader

PageImporter → Form XObject

Embedded in target PDF

(text selectable)

Diagram
ComponenteResponsabilidadOrigen
ChromeHtmlRendererOrquesta un único renderizado; devuelve ChromeRenderResultsrc/Artisan/ChromeHtmlRenderer.php
ChromeRendererConfigObjeto de valor de configuración inmutablesrc/Artisan/ChromeRendererConfig.php
ChromeSecurityPolicyValidación de entrada + envoltorio HTML segurosrc/Artisan/ChromeSecurityPolicy.php
BrowserPoolCiclo de vida del proceso de Chrome y política de reiniciosrc/Artisan/BrowserPool.php
ViewportCalculatorConversión de 72 pt/inch ↔ 96 px/inchsrc/Artisan/ViewportCalculator.php
ChromeRenderResultSalida de renderizado tipada (ChromeRenderResultInterface)src/Artisan/ChromeRenderResult.php
PageImporterPágina de Chrome analizada → ImportedFormXObjectsrc/Artisan/PageImporter.php
EInvoiceServiceFactoryFactory sin contenedor para los contratos de factura electrónica de Premiumsrc/Artisan/EInvoiceServiceFactory.php
  • Linaje de versiones. El artefacto publicado en Composer está etiquetado como v0.1.0. Los docblocks del código de origen llevan @since 1.7.0 (puente a Chrome) y @since 1.1.0 (factory de factura electrónica), ambos heredados de la línea de versiones nextpdf/core anterior al renombrado; el paquete se renombró a nextpdf/artisan en la entrada del CHANGELOG de 2.0.0. Se debe tratar la etiqueta de Composer como la versión de instalación autoritativa, y los marcadores @since como la procedencia de la versión del motor.
  • Solo la primera página. PageImporter::import() usa de forma predeterminada el índice de página 0. El contenido que se desborda a una segunda página de Chrome se recorta, a menos que se proporcione una altura explícita; esto se cubre en la página /integrations/artisan/production-usage/.
  • Sin contenedor de DI. Artisan funciona sin contenedor. EInvoiceServiceFactory proporciona una superficie de instanciación coherente a los entornos sin un contenedor de servicios; véase /integrations/artisan/boot-and-discovery/.

Cada renderizado paga el costo de la carga de página de Chrome y de printToPDF una vez por llamada. BrowserPool mantiene vivo el proceso de Chrome entre renderizados, y lo reinicia cada 100 renderizados para acotar el crecimiento de la memoria. La maquetación que Chrome hace de la entrada domina la complejidad Big-O, no el puente en sí. Para el presupuesto medido del flujo de referencia de esta página, véase performance_budget en el front-matter y la página /integrations/artisan/production-usage/.

El puente renderiza HTML potencialmente no confiable dentro de Chrome. La entrada se valida por tamaño y por contenido antes de que Chrome la vea. El documento envuelto incluye default-src 'none'. Un bloqueo a nivel de CDP detiene toda solicitud de subrecurso. El modelo completo de transporte y aislamiento —incluidos los límites explícitos del flag de sandbox de Chrome— está en la página /integrations/artisan/security-and-operations/. No se debe tratar esta sección como la postura de seguridad completa.

El puente de código abierto renderiza HTML a PDF. Los niveles Premium añaden, sobre el documento renderizado, la incrustación de facturas electrónicas conformes (Pro) y su validación (Enterprise). Cuando esos niveles no están instalados, EInvoiceServiceFactory devuelve null, de modo que la ruta de código abierto sigue siendo plenamente funcional incluso sin ellos.

  • /integrations/artisan/install/
  • /integrations/artisan/configuration/
  • /integrations/artisan/quickstart/
  • /integrations/artisan/chrome-renderer-setup/
  • /integrations/artisan/security-and-operations/
  • /integrations/artisan/production-usage/