Materiales necesarios:
-Librería FPDF descargar
-Librería JGRAPG, descargar
Muchas veces al momento de estar realizando nuestros sistemas necesitamos reportes estadísticos en los mismo, mayormente lo que se necesita es un documento con los datos en formato PDF, es ahí donde utilizamos la librería FPDF, esta es una librería formada por una clase cuyos métodos nos ayudan a generar los documentos PDF, para mayor información en su sitio oficial http://www.fpdf.org/. Pero esta librería por sí sola no nos permite generar gráficos estadísticos es ahí donde entra la participación de la librería JGRAP, la cual es una librería que nos permite generar gráficos estadísticos escrita en PHP, para mas información de JGRAPH su sitio oficial es http://jpgraph.net/ .
Pero como trabajar estas librerías juntas??
En esta ocasión realizaremos una clase llamada reporte que extiende de FPDF y dentro de sus métodos utilizaremos uno para generar los gráficos mediante JGRAPH. Vamos a la acción.
Como Se indico lo primero que haremos es crear una clase que extiende FPDF esto para poder acceder a los métodos de esta librería y así crear nuestro documento PDF
class Reporte extends FPDF { public function __construct($orientation='P', $unit='mm', $format='A4') { parent::__construct($orientation, $unit, $format); } }Si nos fijamos el constructor de nuestra clase sobrescribe al constructor de la clase FPDF, de manera que cuando instanciamos nuestra clase si le damos algún parámetro el mismo pasara también a la clase padre.
Luego crearemos un método para generar los gráficos, en este articulo solo trabajaremos con los gráficos de tarta, si es necesario otro tendríamos que hacer algunas modificaciones a nuestro método.
public function gaficoPDF($datos = array(),$nombreGrafico = NULL,$ubicacionTamamo = array(),$titulo = NULL) { //construccion de los arrays de los ejes x e y if(!is_array($datos) || !is_array($ubicacionTamamo)){ echo "los datos del grafico y la ubicacion deben de ser arreglos"; } elseif($nombreGrafico == NULL){ echo "debe indicar el nombre del grafico a crear"; } else{ #obtenemos los datos del grafico foreach ($datos as $key => $value){ $data[] = $value[0]; $nombres[] = $key; $color[] = $value[1]; } $x = $ubicacionTamamo[0]; $y = $ubicacionTamamo[1]; $ancho = $ubicacionTamamo[2]; $altura = $ubicacionTamamo[3]; #Creamos un grafico vacio $graph = new PieGraph(600,400); #indicamos titulo del grafico si lo indicamos como parametro if(!empty($titulo)){ $graph->title->Set($titulo); } //Creamos el plot de tipo tarta $p1 = new PiePlot3D($data); $p1->SetSliceColors($color); #indicamos la leyenda para cada porcion de la tarta $p1->SetLegends($nombres); //Añadirmos el plot al grafico $graph->Add($p1); //mostramos el grafico en pantalla $graph->Stroke("$nombreGrafico.png"); $this->Image("$nombreGrafico.png",$x,$y,$ancho,$altura); } }Si se fijan dentro de los paramtros de nuestro método tenemos:
$datos: Es un arreglo asociativo con los datos que se desean graficar, para nuestro ejemplo es la cantidad de alumnos aprobados y reprobados de un salón de clase. El arreglo que contendrá los datos debe de tener la siguiente estructura.
Array(‘nombredeldato’=>array(valor,colorEnTarta));Cada uno de los valores tendrá que ser mediante este formato para obtener el grafico en la manera deseada.
$nombreGrafico: Es el nombre que llevara la imagen del grafico que se creara, el método “gaficoPDF” lo que hace es crear una imagen por medio de la librería JGRAPH y luego llamar a la misma desde FPDF para obtener así el grafico dentro del documento PDF, entonces este parámetro será el nombre con que se guardara nuestra imagen del grafico en nuestro servidor.
$ubicacionTamaño: Este parámetro es un arreglo donde indicaremos el lugar y el tamaño dentro de la página que deseemos que se encuentre nuestro grafico, el formato es el siguiente
array(posicionx,posicionY,ancho,alto);
$titulo: Es la única variable que será opcional, esto por motivado a que muchas veces colocamos el titulo desde FPDF y no es necesario colocárselo al grafico, pero si en algún momento es necesario solo con indicar este parámetro el titulo del grafico sera colocado en nuestra imagen por medio de JGRAPH.
Ahora que conocemos los parámetros que debemos indicarle a nuestro método solo nos queda instanciar la clase y llamar al metodo gaficoPDF de la misma para obtener un documento PDF con un grafico estadístico.
$pdf=new Reporte();//creamos el documento pdf $pdf->AddPage();//agregamos la pagina $pdf->SetFont("Arial","B",16);//establecemos propiedades del texto tipo de letra, negrita, tamaño //$pdf->Cell(40,10,'hola mundo',1); $pdf->Cell(0,5,"GRAFICO REALIZADO CON FPDF Y JGRAPH",0,0,'C'); $pdf->gaficoPDF(array('aprobados'=>array(1,'red'),'reprobados'=>array(1,'blue')),'Grafico',array(20,40,100,50),'grafico'); $pdf->Output();Sencillamente en este código instanciamos la clase Reportes y llamamos a varios de los métodos de la librería FPDF para crear el documento PDF y mediante el método creado en este tutorial creamos un grafico de tarta.
Les dejo el código completo del artículo:
/* clase para reportes autor Carlos Belisario */ require_once("fpdf/fpdf.php"); require_once('jpgraph/inc/jpgraph.php'); require_once('jpgraph/inc/jpgraph_pie.php'); require_once ("jpgraph/inc/jpgraph_pie3d.php"); class Reporte extends FPDF { public function __construct($orientation='P', $unit='mm', $format='A4') { parent::__construct($orientation, $unit, $format); } public function gaficoPDF($datos = array(),$nombreGrafico = NULL,$ubicacionTamamo = array(),$titulo = NULL) { //construccion de los arrays de los ejes x e y if(!is_array($datos) || !is_array($ubicacionTamamo)){ echo "los datos del grafico y la ubicacion deben de ser arreglos"; } elseif($nombreGrafico == NULL){ echo "debe indicar el nombre del grafico a crear"; } else{ #obtenemos los datos del grafico foreach ($datos as $key => $value){ $data[] = $value[0]; $nombres[] = $key; $color[] = $value[1]; } $x = $ubicacionTamamo[0]; $y = $ubicacionTamamo[1]; $ancho = $ubicacionTamamo[2]; $altura = $ubicacionTamamo[3]; #Creamos un grafico vacio $graph = new PieGraph(600,400); #indicamos titulo del grafico si lo indicamos como parametro if(!empty($titulo)){ $graph->title->Set($titulo); } //Creamos el plot de tipo tarta $p1 = new PiePlot3D($data); $p1->SetSliceColors($color); #indicamos la leyenda para cada porcion de la tarta $p1->SetLegends($nombres); //Añadirmos el plot al grafico $graph->Add($p1); //mostramos el grafico en pantalla $graph->Stroke("$nombreGrafico.png"); $this->Image("$nombreGrafico.png",$x,$y,$ancho,$altura); } } } $pdf=new Reporte();//creamos el documento pdf $pdf->AddPage();//agregamos la pagina $pdf->SetFont("Arial","B",16);//establecemos propiedades del texto tipo de letra, negrita, tamaño //$pdf->Cell(40,10,'hola mundo',1); $pdf->Cell(0,5,"GRAFICO REALIZADO CON FPDF Y JGRAPH",0,0,'C'); $pdf->gaficoPDF(array('aprobados'=>array(1,'red'),'reprobados'=>array(1,'blue')),'Grafico',array(20,40,100,50),'grafico'); $pdf->Output();
el resultado seria el siguiente:
Espero que le sea de utilidad a alguien cualquier correccion o sugerencia no duden es hacerla saludos
Interesante post este de graficos pero si se necesitara otro tipo de graficos como se haria??
ResponderEliminarImportas las librerias que si de BAR o LINE.. y le modificas..
EliminarPues la libreria JGRAPH tiene para crear ese tipo de graficos en el link que deje para la descarga hay como realizar cada uno, en el articulo coloque el de tarta porque es el que mas he utilizado y por eso hice un metodo directamente para el, pero este metodo pudiera mejorarse creando metodos privados con los tipos de graficos y llamandolo desde nuestro metodo grafico por medio de un parametro, a lo mejor sea un buen tema para otra entrada saludos
ResponderEliminarHola, se ve muy bueno e interesante el codigo, pues te digo que lo he probado pero me aparece la pantalla en blanco, ¿podiras darme el codigo en un archivo plano? pues depronto el que esta escrito aqui debe tener algun error. Gracias
ResponderEliminarEstimado.
ResponderEliminarLo probe y funciona bien. salvo que da un error con la variable $altura.
Gracias por el reporte, si había un error de dedo en el tuto, había declarado $alttura en la línea 35 en vez de colocar $altura, corregido, saludos
ResponderEliminaren la linea 39 creo que hay un empty sobrando.
ResponderEliminarExcelente articulo.
Gracias
gracias por el reporte, pero ese problema es del highlight del blog, que esta repitiendo si le das a la opción de ver código este error no aparece, y así debe de hacerse para poderlo copiar, de todas maneras voy a ver si subo esto a github para que sea mas fácil de utilizar, saludos
Eliminarlo prometido es deuda https://github.com/carlosbelisario/reportes_estadisticos_pdf, para que se descargue mas fácil los archivos, de hecho hice algunas modificaciones, cree un wrapper para crear cualquier gráfico no solo el pie, solo hay que indicar cual es el gráfico de JPGraph y crearle el método para generarlo, cree los dos que más he utilizado, pronto le agrego el gráfico de barras, saludos
ResponderEliminarme descarge tu ejercicio pero tiene problemas con nombre de archivos en el require_once y tambien sale un mensaje diciendo 'Fatal error: Exception thrown without a stack frame in Unknown on line 0' salu2
Eliminarbuenas, el error es mio por no indicar cual es el grafico de prueba que se necesita, e hice algunos cambios, ya acomode para que salga en el PDF y también si quieres ver el grafico directo en el navegador puedes verlos en el archivo graph/grahpTest.php, saludos y gracias por indicar el error en los ejemplos, saludos cualquier cosa me lo indicas
ResponderEliminarhola gracias por el aporte!!! Pero yo tengo un problema me funciona perfectamente tu ejemplo el detalle esta en que al generar mi reporte dejo un boton al dar click me genera el pdf y crea la imagen en mi directorio, al cerrar el pdf, y volver a dar click en el boton ya no me funciona porq dice que no puede ser eliminada la imagen a lafata de permisos, entons tengo que eliminarla directamente del directorio y funciona denuevo, entons veo que funciona para ejecutarse solo una vez, ahi mi problema, como hacer que de manera automatica elimine esa imagen si existe y volver a crearla?
ResponderEliminarespero me ayuden gracias
Buenas el problema es de lo permisos que tienes sobre la carpeta que estas creando la imagen, de hecho yo tengo las clases expuestas acá implementadas en un sistema que tengo en producción y no me ha generado problemas, las carpetas de las imágenes normalmente son públicas, en el método Stroke de la clase JPGraph tu puedes indicarle la ruta especifica donde quieres que quede la imagen ejemplo
ResponderEliminarStroke("../images/$nameGraph.png");
si sigue el problema me comentas a ver si indagamos un poco más en el tema, pero en teoría no debería de darte problema en carpetas públicas, saludos
Saludos !!! aun sigo con el problema..
ResponderEliminarEn efecto cambie la ruta en el metodo stroke y funciona bien, pero aun asi a la nueva carpeta creada incluso la comparti le di permisos de control total y nada, me manda el mismo mensaje de que no tengo permisos para eliminar,,, mi sistema esta en un Windows Xp Sp3 y pues acaso sera que tengo que crear mi carpeta en la raiz c:?? o alguna otra idea de como cambiar esos permisos?
De antemano gracias por la atencion presta!! buena tarde
Buenas gracias por tu comentario, la solución que creo que es la viable y la acabo de anexar al código que esta en github, es darle permisos a la imagen una vez creada (gracias por el dato), esto lo vas a hacer
Eliminar$graph->Stroke("../$nameGraph.png");
chmod($nameGraph . ".png", 0777);
saludos
Buen dia !!
ResponderEliminarSolucione mi problema pero tuve que primero eliminar la imagen con: unlink("$nombreGrafico.png");
$graph->Stroke("$nombreGrafico.png");
ya que dandole los permisos con chmod seguia con el mismo error.
Aun así agradesco la atención!! Muchas GRACIAS
Emanuelle.. podrias decirme como fue q se soluciono.. porfavor.. a mi me sige dando ese erroor...
ResponderEliminar¿cual es el error que te esta dando? el mismo de permisos? si te fijas Emanuelle elimina el gráfico anterior cada vez que va a crear un gráfico nuevo, haciendo esto
ResponderEliminar//línea para eliminar el gráfico anterior
unlink("$nombreGrafico.png");
$graph->Stroke("$nombreGrafico.png");
Antes de la creación de la imagen, yo le asigne todos los permisos a la imagen y también me la creaba sin problemas, a mi ambas me funcionan pero trabajo con linux, a lo mejor con windows el asignar los permisos no es tan factible y por eso es que el eliminarla como Emmanuel es la mejor solución, saludos
De los mejores ejemplos que encontré buscando. Sin embargo, no se como hacerlo para que salgan varios gráficos por documento pdf, ¿es posible? si lo es, no tengo la menos idea como sería..
ResponderEliminarClaro que es posible lo que tienes es que llamar al método que crea el gráfico la cantidad de veces que necesites, pasando los parámetros de datos, saludos
ResponderEliminarme gustaría saber como utilizar mas tipos de gráficos si alguien me puede ayudar lo agradecería
ResponderEliminarYo había hecho un wrapper para crear los gráficos, en el link del github que deje arriba se encuentra el código, sin embargo es simplemente sacarle el provecho a la librería jpgraph y a los gráficos que esta ofrece
ResponderEliminarDisculpa tengo que llamarlo mediante algún botón o algo? porque ejecuto el archivo php en mi servidor y no realiza nada, gracias...
ResponderEliminarAlgún error?? porque en teoría el código que deje al hacerlo en un archivo debe de funcionar
EliminarTengo un problema al enviar mi gráfica al pdf me muestra un error que es el 150009 illegal Pie Plot, espero puedas ayudarme gracias
ResponderEliminarel objeto que estas pasando no es correcto según la documentación, verifica que estes pasando bien los datos y nos comentas ya que el código que se dejo funciona correctamente, saludos
EliminarHola Carlos, mira estoy realizando tu ejemplo, pero al momento de de generar el grafico, practicamente me sale el grafico pero no en el pdf que quiero que salga.
ResponderEliminarLa grafica dibuja pero en html, que puede ser.
Saludos,
David
Soy la persona que no le genera el grafico al momento de comentar la linea
ResponderEliminar$pdf->gaficoPDF(array('aprobados'=>array(1,'red'),'reprobados'=>array(1,'blue')),'Grafico',array(20,40,100,50),'grafico');
ahi me genera el pdf, claro al comentarlo solo me genera el pdf con el titulo, favor ayudame
En la carpeta donde tienes el script te genera alguna imagen con el gráfico y el mismo nombre del gráfico??
ResponderEliminarGracias Carlos por contestarme, segun veo son los permisos estoy sobre fedora, le di permisos 777 como root, apache y no me sale el siguiente error, te pongo el error que me sale... david.php es el archivo donde lo escribi a tu ejemplo.
ResponderEliminarWarning: unlink(graficoPrecision.png): Permission denied in /var/www/html/labcalidadpro/site/tcpdf/examples/david.php on line 46
Warning: fopen(graficoPrecision.png): failed to open stream: Permission denied in /var/www/html/labcalidadpro/site/jpgraph/src/gd_image.inc.php on line 2136
Warning: flock() expects parameter 1 to be resource, boolean given in /var/www/html/labcalidadpro/site/jpgraph/src/gd_image.inc.php on line 2137
Warning: flock() expects parameter 1 to be resource, boolean given in /var/www/html/labcalidadpro/site/jpgraph/src/gd_image.inc.php on line 2142
JpGraph Error: 25111 Can't delete cached image graficoPrecision.png. Permission problem?
Amigo muchas gracias por la pista que me diste, era permisos,ahora funciona de maravilla, el problema era del contexto de selinux (por ahi lo lei, no estoy seguro, pero funciono), ejecute lo siguiente:
ResponderEliminarsudo chcon -R -t httpd_sys_content_rw_t /var/www/html/
Saludos,
David
Por cierto muy buen articulo
Excelente que hayas logrado resolver el problema, porque hice varias pruebas y me estaba funcionando correctamente y no encontraba que pudiera estarte pasando, en fin excelente que te haya resultado, saludos
EliminarMuchas Gracias, parte de este código me ayudó a solucionar tema IMAGEN en PDF (librería FPDF) trayéndolo desde ($imagen) con archivo comenzado con LETRA Ej P001.jpg
ResponderEliminarGRACIAS. / clamisch@hotmail.es
Hola Disculpa, presento un problema no hace nada el codigo :(, la pantalla queda en blanco que puede ser?
ResponderEliminaractiva el error_reporting o ve los logs de apache para ver si te da un error en la sintaxis
Eliminarque tal si tuviera que tomar los datos desde base de datos me podrias un topic o idea gracias
ResponderEliminararma el array con el formato que necesita el método de la clase y debería de funcionar, aunque actualmente no se si hubo algún cambio con el FPDF o el jpGraph
EliminarHola, excelente tu aporte, decidí llevarlo más allá y la intención es que la generación sea dinamica, es decir me genere el grafico sin yo saber el numero de partes que tendra lo trabajo con un ciclo cuando es hasta dos partes esta bien, pero, cuando son mas de dos se rompe y me dice que es ilegal y que la suma de todo el data es cero y pues en realidad ya no se que hacer te agradezco me ayudes!!
ResponderEliminarmuestras como lo estas creando a ver que puede estar pasando, saludos
EliminarSegún entiendo, debo borrar la imagen antes de crear la siguiente. ¿Puedo borrarla al momento de cerrar la página que la llamó? De ser así... ¿Cómo lo hago?
ResponderEliminarExcelente, muchas gracias, de verdad que me has ayudado como no tienes idea :)
ResponderEliminar