2012-03-28 22 views
5

Tengo un diseño HTML/CSS bastante complicado que me gustaría convertir a PDF en mi servidor. Ya he probado DOMPDF, desafortunadamente no convirtió el HTML con el diseño correcto. He considerado HTMLDOC pero he escuchado que ignora CSS en gran medida, así que supongo que el diseño también se rompería con esa herramienta.HTML2PDF en PHP - convertir utilidades y scripts - ejemplos y demostraciones

Mi pregunta es si hay alguna demostración en línea para otras herramientas (como wkhtmltopdf, es decir) que pueda utilizar para verificar cómo se convierte mi HTML. Antes de pasar el resto de mi vida instalando & probando uno por uno?

Desafortunadamente, no puedo cambiar el diseño HTML para que se ajuste a esas herramientas. O mejor dicho: podría, si alguno de ellos se acerca a un resultado aceptable ...

+3

wkhtmltopdf no requiere mucho de una instalación - Creo que en realidad recomiendan simplemente descargue la versión estática de 32 o 64 bits y utilícela. No debe tomar más de 2 minutos para probarlo, y probablemente será la solución de más alta calidad disponible. Tenemos algunos HTML/CSS semi-complejos que se convierten a PDF con fines de impresión y wkhtmltopdf no nos ha fallado todavía. – Crontab

+2

wkhtmltopdf es realmente fácil de instalar (y creo que incluso está binario estáticamente vinculado por lo que no se requieren libs adicionales) ... el resultado es el mismo que el renderizado por un motor webkit (que está bajo el capó - simplemente sin cabeza) – poncha

+0

hola chicos , gracias, probaré dos cosas más: TCPDF y wkhtmltopdf :) ambos tienen razón, todo es fácil de instalar, pero lleva tiempo hacerlo, probarlo, leer la documentación :) – Michal

Respuesta

11

No es realmente una respuesta, pero para la pregunta anterior, pero intentaré aportar algo de mi experiencia, tal vez lo haga ayudar a alguien en algún lugar en el futuro.

  1. wkthmltopdf es realmente la única solución que trabajó para mí que podría producir lo que llamo resultados aceptables. Aún así, algunas modificaciones menores al CSS tuvieron que hacerse, sin embargo, funcionó muy bien cuando se trató de renderizar el contenido. Todos los otros paquetes son realmente adecuados solo si tiene un documento simple con una tabla básica, etc. No hay posibilidad de obtener resultados justos en documentos complejos con elementos de diseño, CSS, múltiples imágenes superpuestas, etc. Si hay documentos complejos en el juego - No pierdas el tiempo (como yo) - ve directamente a wkhtmltopdf.

  2. Cuidado - la instalación wkhtmltopdf es complicado. No fue tan fácil para mí como dijeron los chicos en sus comentarios (una de las razones podría ser que no estoy muy familiarizado con Linux). El binario estático no funcionó para mí por alguna razón que no puedo explicar. Sospecho que hubo problemas con la versión, aparentemente hay una diferencia entre las versiones para diferentes sistemas operativos y procesadores, tal vez tengo la versión vrong. Para instalar la versión no estática, antes que nada tienes que tener acceso de root al servidor, eso es obvio. Lo instalé con apt-get usando PuTTy, fue bastante bien. Tuve la suerte de que mi servidor ya tenía todas las predisposiciones para instalar wkhtmltopdf. Así que esta fue la parte más fácil para mí :) (por cierto, no tienes que preocuparte por enlaces simbólicos o envoltorios como muchos tutoriales te dicen; pasé horas tratando de descubrir cómo hacer esa parte, al final la di y todo funciona bien)

  3. Después de la instalación recibí el famoso error Cannot connect to X server. Esto se debe al hecho de que necesitamos ejecutar wkhtmltopdf sin cabeza en un 'virtual' x server. Moverse por esto también fue bastante simple (si a uno no le importan los enlaces simbólicos). Lo instalé con apt-get install xvfb. Esto también fue bastante bien para mí, sin problemas.

  4. Después de completar esto, pude ejecutar wkhtmltopdf. Cuidado, me tomó algo de tiempo descubrir que tratar de ejecutar xvfb fue el camino equivocado; en su lugar, debe ejecutar xvfb-run. Mi código PHP ahora se parece a este exec("xvfb-run wkhtmltopdf --margin-left 16 /data/web/domain.com/source.html /data/web/domain.com/target.pdf"); (observe la opción de línea de comando --margin-left 16 para wkhtmltopdf - hace que mi contenido esté más centrado; lo dejé en su lugar para demostrar cómo puede usar las opciones de línea de comando).

  5. También quería proteger los archivos PDF generados de la edición (en mi caso, también es posible proteger la impresión). Después de investigar un poco encontré this class de ID Security Suite. Antes que nada, tengo que decir: ES VIEJO (estoy ejecutando PHP 5+). Sin embargo, hice algunas mejoras. Antes que nada: es un contenedor alrededor de la biblioteca FPDF, por lo que hay un archivo llamado fpdf.php en el paquete. Reemplacé este archivo de la última versión FPDF que obtuve from here. Hizo que mis advertencias PHP parecieran más sostenibles. También cambié el $pdf =& new FPDI_Protection(); y eliminé el signo & porque recibía una advertencia obsoleta. Sin embargo, hay más de los que vendrán. En lugar de buscar y modificar el código, acabo de convertir el error que informaba lvl en 0 con error_reporting(0); (aunque apagar las advertencias solo debería ser suficiente). Ahora alguien dirá que esto no es una "buena práctica". Estoy usando todo esto en un sistema interno, así que realmente no me tiene que importar. Por supuesto, los scripts podrían modificarse para que coincidan con los últimos requisitos. Para mí, no quería pasar otras horas trabajando en ello. Tenga cuidado donde dice el script $pdf->SetProtection(array('print'), '', $password); (Permití imprimir mis documentos como puede ver). Me tomó un tiempo darme cuenta de que el primer argumento son los permisos. El segundo es la CONTRASEÑA DE USUARIO - si proporciona esto, los documentos requerirán una contraseña para abrir (lo dejé en blanco). La tercera es la contraseña de propietario - esto es lo que necesita para hacer los docs "garantizados" en contra de editar, copiar, etc.

Toda mi código de ahora queda como:

// get the HTML content of the file we want to convert 
$invoice = file_get_contents("http://www.domain.com/index.php?s=invoices-print&invoice_no=".$_GET['invoice_no']; 
// replace the CSS style from a print version to a specially modified PDF version 
$invoice = str_replace('href="design/css/base.print.css"','href="design/css/base.pdf.css"',$invoice); 

// write the modified file to disk 
file_put_contents("docs/invoices/tmp/".$_GET['invoice_no'].".html", $invoice); 

// do the PDF magic 
exec("xvfb-run wkhtmltopdf --margin-left 16 /data/web/domain.com/web/docs/invoices/tmp/".$_GET['invoice_no'].".html /data/web/domain.com/web/docs/invoices/".$_GET['invoice_no'].".pdf"); 

// delete the temporary HTML data - we don't need that anymore since our PDF is created 
unlink("docs/invoices/tmp/".$_GET['invoice_no'].".html"); 

// workaround the warnings 
error_reporting(0); 

// script from ID Security Suite 
function pdfEncrypt ($origFile, $password, $destFile){ 
    require_once('libraries/fpdf/FPDI_Protection.php'); 
    $pdf = new FPDI_Protection(); 
    $pdf->FPDF('P', 'in'); 
    //Calculate the number of pages from the original document. 
    $pagecount = $pdf->setSourceFile($origFile); 
    //Copy all pages from the old unprotected pdf in the new one. 
    for ($loop = 1; $loop <= $pagecount; $loop++) { 
     $tplidx = $pdf->importPage($loop); 
     $pdf->addPage(); 
     $pdf->useTemplate($tplidx); 
    } 

    //Protect the new pdf file, and allow no printing, copy, etc. and 
    //leave only reading allowed. 
    $pdf->SetProtection(array('print'), '', $password); 
    $pdf->Output($destFile, 'F'); 
    return $destFile; 
} 

//Password for the PDF file (I suggest using the email adress of the purchaser). 
$password = md5(date("Ymd")).md5(date("Ymd")); 
//Name of the original file (unprotected). 
$origFile = "docs/invoices/".$_GET['invoice_no'].".pdf"; 
//Name of the destination file (password protected and printing rights removed). 
$destFile = "docs/invoices/".$_GET['invoice_no'].".pdf"; 
//Encrypt the book and create the protected file. 
pdfEncrypt($origFile, $password, $destFile); 

Esperanza esta ayuda a alguien a ahorrar algo de tiempo en el futuro. Esta solución completa tardó 12 horas en implementarse en nuestro sistema de facturación. Si hubiera una mejor información en wkhtmltopdf para usuarios como yo, que no están familiarizados con Linux/UNIX, podría haber ahorrado algunas de las horas dedicadas a esto.

Sin embargo - lo que no te mata te hace más fuerte :) así que estoy un poco más perfecto ahora que hice esta carrera :)

+0

Son ¿Estás ejecutando SELinux en modo forzado? –