¿Cómo puedo convertir HTML con CSS a PDF?

Un par de preguntas van en esta dirección en StackOverflow, pero están fuera de tema allí, así que tengamos una pregunta sobre el tema aquí.

Sería bueno si incluyera una captura de pantalla de ejemplo en sus respuestas para cada herramienta/biblioteca que sugiera.

Además, tenga en cuenta:

  • CSS: ¿La herramienta/biblioteca aplica CSS?
    • @page: ¿Aplica modo paisaje/retrato?
    • ¿Fuentes? ( Esta pregunta es solo para herramientas/bibliotecas que respetan @font-face)
    • ¿Colores?
  • JavaScript: ¿Aplica JavaScript antes de generar el PDF?
  • o no
  • o no
  • ¿Qué son los requerimientos?

Ejemplo 1

Puede usar lo siguiente como ejemplo para la prueba:

<!DOCTYPE html>
<html>
<head>
    <title>HTML 2 PDF print test</title>

    <style type="text/css">
        body {
            font-size: 14px;
            color:  #333;
        }

        table {
            width: 100%;
            max-width: 100%;
            border-spacing: 0;
            border-collapse: collapse;
            font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
        }

        th {
            text-align: left;
        }

        td, th {
            vertical-align: top;
            border-top: 1px solid #ddd;
            line-height: 1.42857143;
            padding: 8px;
        }

        tbody tr:nth-child(odd) {
           background-color: #f9f9f9 !important;
        }

        @media print{
            @page {size: landscape}
        }
    </style>
</head>
<body>
<table class="table table-striped">
    <tr>
        <th style="font-family:Courier New;">Country</th>
        <th style="color: red;">Code</th>
        <th style="color: red !important;">Phone</th>
        <th>Language</th>
        <th>Population</th>
        <th>Banana Rama</th>
        <th>Foo bar</th>
        <th>Constants</th>
        <th>Empty Cells</th>
        <th>More</th>
        <th>End</th>
    </tr>
    <tr>
        <td>Germany</td>
        <td>de</td>
        <td>+49</td>
        <td>German</td>
        <td>82 Million</td>
        <td id="cell">JavaScript does <span style="color: red">not</span> work.</td>
        <td>dasfd asfawerf asdfvas fwer </td>
        <td>asd fasdf asdfa sdfa sdf asdf asdf asdfa sdf asd</td>
        <td>-</td>
        <td>asdf asdfasd fasdf asdfa sdfasdf</td>
        <td>ad fasd fasd fasd fasdf asd fasdf as</td>
    </tr>
    <tr>
        <td>France</td>
        <td>fr</td>
        <td>+01</td>
        <td>French</td>
        <td>70 Million</td>
        <td>a &nbsp;asdfa sdf asdf asdf asdfasd asdf asdf asd fasd fasdfa sdf</td>
        <td>aerte fasf werwasdfa sd3e asdf adfasdfe werfa sdfas</td>
        <td>as dfasd fasd fasd fasd fasd&nbsp;</td>
        <td></td>
        <td>asd fasd fasdf asdf asd fasdf asdf asd fasdf asdf&nbsp;</td>
        <td>as dfa sd asfdas asfd&nbsp;</td>
    </tr>
    <tr>
        <td>Great Britain</td>
        <td>uk</td>
        <td>+02</td>
        <td>English</td>
        <td>60 Million</td>
        <td>asdfasdf asdf asdfa sdf asdfasdf&nbsp;</td>
        <td>asd fasdf asdf asdfwr wadfa sd f</td>
        <td>ada asdf asd</td>
        <td></td>
        <td>a sd fasd fasdf asdf asdfa sdf a</td>
        <td>asasd asdf asd fasd fas asd fasdf&nbsp;</td>
    </tr>
    <tr>
        <td>United States of America</td>
        <td>us</td>
        <td>+03</td>
        <td>English</td>
        <td>300 Million</td>
        <td>asdf asdfasd fasdfwerwfasdfasdf asdfasdfasd&nbsp;</td>
        <td>a dfasdf asdf asdf rt asdf asdfasd asdf asd fasd fas</td>
        <td>a dsfas fasd f</td>
        <td></td>
        <td>a dsfa sdfasd fasd f</td>
        <td>a dsfasd asdf asdf asd fafasd fas fas&nbsp;</td>
    </tr>
</table>
<script type="text/javascript">
    var cell = document.getElementById("cell");
    cell.innerHTML = "JavaScript <span style='color: green; font-weight:bold'>works</span>";
</script>
</body>
</html>

Chrome hace lo siguiente con su función de impresión:

ingrese la descripción de la imagen aquí

Cosas a tener en cuenta:

  • La página está en modo horizontal ✓
  • Se cambia la fuente por País ✓
  • El código es rojo ✓
  • El teléfono está rojo ✓
  • La mesa está rayada ✓
  • Se aplica JavaScript ✓
Lo que he visto hasta ahora: pdfkit, pandoc, PrinceXML, weasyprint, wkhtmltopdf.
Me recomendaron titiritero .

Respuestas (7)

wkhtmltopdf

wkhtmltopdf es una línea de comando y (LGPLv3, fuente ) para convertir archivos HTML a PDF. Tiene 5794 estrellas, 860 bifurcaciones y 53 colaboradores en GitHub. Está escrito en C++. La primera confirmación en GitHub fue el 7 de mayo de 2008.

Instalación

$ sudo apt-get install wkhtmltopdf

Uso

$ wkhtmltopdf input.html output.pdf

Ejemplo 1

ingrese la descripción de la imagen aquí

  • La página no está en modo horizontal ✘ (ver solicitud de funciones ), pero se puede configurar con-O landscape
  • Se cambia la fuente por País ✓
  • El código es rojo ✓
  • El teléfono está rojo ✓
  • La mesa está rayada ✓
  • JavaScript funciona ✓
Una mejor documentación sería buena, pero por lo demás funciona como se anuncia y es justo la herramienta que necesito.

Divulgación: trabajo en Sejda y participo en el desarrollo de esta función.

Sejda PDF

Sejda PDF es un paquete de software comercial para procesar archivos PDF, incluida la conversión de HTML a PDF .

Se admiten Javascript, CSS3 y fuentes personalizadas.

La función HTML a PDF se encuentra actualmente en versión beta (¡sus comentarios son bienvenidos!)

Instalación

No se requiere instalación.

La función de HTML a PDF de Sejda se proporciona como un servicio en línea que funciona en el navegador. https://www.sejda.com/html-to-pdf

El servicio en línea se puede utilizar de forma gratuita hasta 3 conversiones por hora.

También está disponible una API REST para la conversión de HTML a PDF .

Uso

Convierta HTML a PDF en su navegador usando Sejda PDF

Ejemplo 1

ingrese la descripción de la imagen aquí

  • La página está en modo horizontal ✓
  • Se cambia la fuente por País ✓
  • El código es rojo ✓
  • El teléfono está rojo ✓
  • La mesa está rayada ✓
  • JavaScript funciona ✓
La fuente no se cambia por país. Mira el y. Si se cambiara, ytendría una barra inferior. En tu caso, no lo ha sido.
Hola Martin, creo que la fuente cambió , pero en lugar de Courier New estaba usando una fuente alternativa. Acabo de actualizar la captura de pantalla con la última salida, ahora se usa Courier New.
Interesante. Entonces, ¿supongo que eres el desarrollador de esa página?
Trabajo en Sejda y participo en el desarrollo de esta característica.

huellapequeña

weasyprint es un paquete de Python y que viene con un ejecutable. La documentación está en línea, el código está en Github . La última confirmación fue el 19.09.2017. Tiene 1484 estrellas, 155 forks y 41 colaboradores.

Instalación

$ pip install weasyprint

Uso

$ weasyprint input.html output.pdf

Ejemplo 1

ingrese la descripción de la imagen aquí

Tenga en cuenta:

  • La página está en modo horizontal ✓
  • Se cambia la fuente por País ✓
  • El código es rojo ✓
  • El teléfono está rojo ✓
  • La mesa está rayada ✓
  • JavaScript no funciona ✘

PríncipeXML

PrinceXML es un paquete de software comercial. Se puede instalar de varias formas, incluido un paquete Debian. Hay disponible una documentación de usuario .

Tiene una versión gratuita que agrega un icono al PDF generado. La licencia del servidor cuesta US$3800.

Instalación

Ver la guía de instalación

Después de instalar PrinceXML, debe tener princeen su RUTA:

$ prince --version
Prince 11.3
Copyright 2002-2017 YesLogic Pty. Ltd.
Non-commercial License

Uso

$ prince input.html -o output.pdf

Ejemplo 1

Esto se parece mucho a Weasyprint. De hecho, no puedo ver ninguna diferencia.

ingrese la descripción de la imagen aquí

  • La página está en modo horizontal ✓
  • Se cambia la fuente por País ✓
  • El código es rojo ✓
  • El teléfono está rojo ✓
  • La mesa no está rayada ✓
  • JavaScript no se aplica ✘
DocRaptor es una herramienta API de pago que utiliza la biblioteca Prince en segundo plano (pero tiene un motor de JavaScript mucho más potente). Además de JS y un equipo de soporte más grande, DocRaptor ofrece un precio de entrada mucho más bajo que los $3k de Prince.
Además, Prince admite JavaScript (aunque su compatibilidad se está quedando atrás en los navegadores modernos), solo tiene que habilitarlo. Está desactivado de forma predeterminada para acelerar el análisis de documentos.

Probé Chrome en sí mismo con éxito.

Este es el ejemplo de línea de comando que usé:

chrome.exe --headless --print-to-pdf=out.pdf file:///input.html

Ejemplo de línea de comando real (Windows):

"C:\Archivos de programa (x86)\Google\Chrome\Application\chrome.exe" --headless --print-to-pdf=C:\reports\example.pdf file:///C:\reports\example .html

Como de costumbre, debe envolver sus nombres de archivo con comillas si hay espacios dentro.

Puedes usar el script de python: https://github.com/labadze/html2pdf-pyhton

Hay una descripción completa y uso. La esperanza te ayuda.

Obtenga un controlador de impresión que no imprima en una impresora, imprima en un PDF. Adobe Distiller viene con uno. También hay impresoras PDF de terceros.

  1. Ver página web en el navegador.
  2. Haga clic en Imprimir, luego elija la impresora PDF.
  3. La impresora PDF le preguntará dónde desea guardar el archivo. Introduzca una ruta y un nombre de archivo.
  4. Hecho.