Lenguaje PHP

Crear PDF con FPDF usando PHP & MySQL

Crear un reporte con FPDF, MySQL y PHP

Crear PDF con FPDF usando PHP & MySQL. En este artículo vamos a implementar un pequeño sistema para mostrar un reporte en extensión PDF usando la librería FPDF.

¿Cómo funciona el script?

Este script realiza el historial clínico de múltiples pacientes. Por lo tanto, a través de un CRUD mostraremos los datos del paciente y haciendo uso de un vínculo podemos ver los datos generales de dicho paciente y un resumen de las consultas médicas que realizó el paciente en la clínica, el reporte historial estará en formato PDF listo para la impresión.

Crear PDF con FPDF usando PHP & MySQL

Si deseamos lograr este objetivo utilizaremos varios compontes que detallaré a continuación:

  • Lenguaje de programación PHP
  • Gestor de base de datos MySQL
  • Librería FPDF.
  • HTML5

Crear PDF con FPDF: Estructura

A continuación, detallaremos los elementos y partes del script para el correcto funcionamiento del script.

Primer paso: Crear base de datos y tablas

Para este ejemplo necesitaremos 3 tablas con los siguientes nombres para armar nuestro reporte y estas son:

consultas_medicas. – Encargado de almacenar las consultas de todos los pacientes.

medicos. –  Tabla que almacena a todos los médicos de la clínica

pacientes. – Tabla que almacena a todos los pacientes que se atienden en la clínica.

CREATE TABLE `consultas_medicas` (
`consulta_id` bigint(20) UNSIGNED NOT NULL,
`fecha_consulta` date NOT NULL,
`id_paciente` int(5) NOT NULL,
`id_medico` int(5) NOT NULL,
`consultorio` varchar(20) NOT NULL,
`diagnostico` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `consultas_medicas` (`consulta_id`, `fecha_consulta`, `id_paciente`, `id_medico`, `consultorio`, `diagnostico`) VALUES
(1, '2020-04-14', 1, 3, 'B-05', 'Sinusitis Aguda'),
(2, '2020-05-11', 1, 1, 'A-09', 'Hematoma severa'),
(3, '2020-06-17', 2, 2, 'B-06', 'Gastritis'),
(4, '2020-07-18', 1, 3, 'D-90', 'Gripe aguda'),
(5, '2020-08-19', 3, 2, 'Z-11', 'Fractura Clavicula');

CREATE TABLE `medicos` (
`medico_id` bigint(20) UNSIGNED NOT NULL,
`cedula` varchar(10) NOT NULL,
`nombre_medico` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `medicos` (`medico_id`, `cedula`, `nombre_medico`) VALUES
(1, '78452596', 'Dr. Juan Medina'),
(2, '74582125', 'Dr. Maria Prada'),
(3, '96352145', 'Dr. Carlos Kim'),
(4, '78965412', 'Dr. Luis Tejada');

CREATE TABLE `pacientes` (
`paciente_id` int(11) NOT NULL,
`dni` varchar(10) NOT NULL,
`nombre` varchar(80) NOT NULL,
`apellido_paterno` varchar(80) NOT NULL,
`apellido_materno` varchar(80) NOT NULL,
`sexo` varchar(2) NOT NULL,
`domicilio` text NOT NULL,
`foto` varchar(250) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `pacientes` (`paciente_id`, `dni`, `nombre`, `apellido_paterno`, `apellido_materno`, `sexo`, `domicilio`, `foto`) VALUES
(1, '45125236', 'Pedro', 'Carrillo', 'Gonzales', 'H', 'Av. Santiago Mayolo #2840', 'pedro.jpg'),
(2, '21526356', 'Joaquin', 'Flores', 'Valencia', 'H', 'Av. Los molinos #41', 'joaquin.jpg'),
(3, '74582145', 'Lucia', 'Espinoza', 'Zavaleta', 'F', 'Av. Los Florales #327', 'lucia.jpg');

ALTER TABLE `consultas_medicas`
ADD PRIMARY KEY (`consulta_id`);

ALTER TABLE `medicos`
ADD PRIMARY KEY (`medico_id`);

ALTER TABLE `pacientes`
ADD PRIMARY KEY (`paciente_id`);

ALTER TABLE `consultas_medicas`
MODIFY `consulta_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;

ALTER TABLE `medicos`
MODIFY `medico_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

ALTER TABLE `pacientes`
MODIFY `paciente_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

Segundo paso: Crear conexión

La conexión es importante y utilizaremos la clase conexión para conectar PHP con la base de datos. Sin embargo, para lograr la conexión usaremos mysqli.

Class Conexion {

public function conectar(){
$mysqli = new mysqli('localhost','root','','db_clinica',3306);

if ($mysqli->connect_errno)
header('Location: /');

$mysqli->set_charset('utf8');

return $mysqli;
}

}

Tercer paso: Clase pacientes

Aquí creamos nuestra clase pacientes para listar en nuestro index.php y poder acceder a un enlace para generar el historial consultas médicas del paciente.

<?php
require_once 'conexion.php';
class Paciente extends Conexion {

public $mysqli;
public $data;

public function __construct() {
$this->mysqli = parent::conectar();
$this->data = array();
}

//*****************************************************************
// LISTAMOS DE PACIENTES
//*****************************************************************

public function pacientes(){
$resultado = $this->mysqli->query("SELECT * FROM pacientes");

while( $fila = $resultado->fetch_assoc() ){
$data[] = $fila;
}

if (isset($data)) {
return $data; 
} 

}

//*****************************************************************
// PACIENTE POR ID
//*****************************************************************

public function paciente_id($id){

$consulta = sprintf("SELECT
*
FROM
pacientes
WHERE
paciente_id = %s", 
parent::comillas_inteligentes($id)
);

$resultado = $this->mysqli->query($consulta);
$fila = $resultado->fetch_array();
return $fila;
}

}

Cuarto paso: Clase consulta

Este aparado es importante porque crearemos la clase consulta para generar el listado de las consultas médicas del paciente en el reporte con extensión PDF.

<?php
require_once 'conexion.php';
class Consulta extends Conexion {

public $mysqli;
public $data;

public function __construct() {
$this->mysqli = parent::conectar();
$this->data = array();
}

//*****************************************************************
// LISTAMOS DE CONSULTAS
//*****************************************************************

public function consultasPaciente($id){
$consulta = sprintf("SELECT
consultas_medicas.fecha_consulta,
consultas_medicas.consultorio,
consultas_medicas.diagnostico,
medicos.nombre_medico
FROM
consultas_medicas
INNER JOIN medicos ON consultas_medicas.id_medico = medicos.medico_id
WHERE
consultas_medicas.id_paciente = %s", 
parent::comillas_inteligentes($id)
);

$resultado = $this->mysqli->query($consulta);

while( $fila = $resultado->fetch_assoc() ){
$data[] = $fila;
}

if (isset($data)) {
return $data; 
} 
}

}

Quinto paso: Crear el archivo index.php

Este fichero será primordial porque en él se mostrará una lista de pacientes. Además, haciendo uso de un botón podremos ver el historial clínico de un determinado paciente.

Esta tabla está conformada por HTML5 y datatables que es una extensión de jQuery para darle dinamismo a los resultados encontrados.

Para mostrar el historial clínico usaremos el método GET con el ID del paciente.

<?php
require("class/paciente.php");
include "header.php";

$objpaciente = new Paciente();
$pacientes = $objpaciente->pacientes();
if(sizeof($pacientes) > 0){
?>
<table id="clinica" class="display table table-bordered table-stripe" cellspacing="0" width="100%">
<thead>
<tr>
<th>DNI</th>
<th>NOMBRE</th>
<th>GENERO</th>
<th>DIRECCION</th>
<th>HISTORIAL</th>
</tr>
</thead>
<tbody>
<?php
foreach ($pacientes as $row){
?>
<tr>
<td><?php echo $row['dni']; ?></td>
<td><?php echo $row['nombre'].' '.$row['apellido_paterno'].' '.$row['apellido_materno']; ?></td>
<td><?php echo $row['sexo']; ?></td>
<td><?php echo $row['domicilio']; ?></td>
<td>
<a href="historial.php?id=<?php echo $row['paciente_id'] ?>"><span class="glyphicon glyphicon-file" aria-hidden="true"></span> Historial Clinico</a>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
<?php
}else{
echo "No hay resultados...";
}

include "footer.php";

Sexto paso: Historial.php

Sera el encargado de mostrar el documento PDF en donde podemos observar las consultas que realizo el paciente en la clínica, listada por fecha de atención, médico que lo atendió y el diagnostico.

<?php
require('fpdf/fpdf.php');
require("class/paciente.php");
require("class/consulta.php");
class PDF extends FPDF
{
var $widths;
var $aligns;

function SetWidths($w)
{

$this->widths=$w;
}

function SetAligns($a)
{

$this->aligns=$a;
}

function Row($data)
{

$nb=0;
for($i=0;$i<count($data);$i++)
$nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));
$h=8*$nb;

$this->CheckPageBreak($h);

for($i=0;$i<count($data);$i++)
{
$w=$this->widths[$i];
$a=isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';

$x=$this->GetX();
$y=$this->GetY();


$this->Rect($x,$y,$w,$h);

$this->MultiCell($w,8,$data[$i],0,$a,'true');

$this->SetXY($x+$w,$y);
}

$this->Ln($h);
}

function CheckPageBreak($h)
{

if($this->GetY()+$h>$this->PageBreakTrigger)
$this->AddPage($this->CurOrientation);
}

function NbLines($w,$txt)
{

$cw=&$this->CurrentFont['cw'];
if($w==0)
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
$s=str_replace("\r",'',$txt);
$nb=strlen($s);
if($nb>0 and $s[$nb-1]=="\n")
$nb--;
$sep=-1;
$i=0;
$j=0;
$l=0;
$nl=1;
while($i<$nb)
{
$c=$s[$i];
if($c=="\n")
{
$i++;
$sep=-1;
$j=$i;
$l=0;
$nl++;
continue;
}
if($c==' ')
$sep=$i;
$l+=$cw[$c];
if($l>$wmax)
{
if($sep==-1)
{
if($i==$j)
$i++;
}
else
$i=$sep+1;
$sep=-1;
$j=$i;
$l=0;
$nl++;
}
else
$i++;
}
return $nl;
}

function Header()
{
$this->SetFont('Arial','',10);
$this->Text(20,14,'Historial clinico - Clinica la Luz',0,'C', 0);
$this->Ln(10);
}

function Footer()
{
$this->SetY(-15);
$this->SetFont('Arial','B',8);
$this->Cell(100,10,'Historial del paciente',0,0,'L');

}

}
// Obtenemos el id del paciente
$paciente_id= $_GET['id'];
// Creamos nuestro objeto paciente
$objpaciente = new Paciente();
// obtenemos los datos del paciente por el id
$paciente = $objpaciente->paciente_id($paciente_id);
// Creamos nuestro objeto pdf
$pdf=new Pdf();
// Agregamos una pagina al archivo
$pdf->AddPage();
// Personalizamos los amrgenes
$pdf->SetMargins(20,20,20);
// Creamos un espacio
$pdf->Ln(10);
// Definimos la fuente y tamaño
$pdf->SetFont('Arial','',12);
// Creamos una celda para mostrar la información
$pdf->Cell(30,6,'DNI: ',0,0);
$pdf->Cell(0,6,$paciente['dni'],0,1);
$pdf->Cell(30,6,'NOMBRE: ',0,0);
$pdf->Cell(0,6,$paciente['nombre'].' '.$paciente['apellido_paterno'].' '.$paciente['apellido_materno'],0,1);
$pdf->Cell(30,6,'SEXO: ',0,0);
$pdf->Cell(0,6,$paciente['sexo'],0,1);
$pdf->Cell(30,6,'DOMICILIO: ',0,0); 
$pdf->Cell(0,6,$paciente['domicilio'],0,1);
// Usamos la funcio imagen, para obtenr la ruta de la imagen usamos nuestra funcion ruta de conexion
$pdf->Image(Conexion::ruta().'upload/pacientes/'.$paciente['foto'],155,20,30,30);

$pdf->Ln(10);

$pdf->SetWidths(array(10, 20, 50, 50, 40));
$pdf->SetFont('Arial','B',10);
$pdf->SetFillColor(29,29,29);
$pdf->SetTextColor(255);
// usamos nuestra funcion creada para listar celdas con varias lineas
$pdf->Row(array('#','FECHA', 'MEDICO', 'CONSULTORIO', 'DIAGNOSTICO'));
// Creamos nuestra funcion consulta
$objconsulta = new Consulta();
$consultas = $objconsulta->consultasPaciente($paciente_id);

$i = 0;
// listamos las consultas
$n=0;
foreach ($consultas as $consulta) {$n++;
$pdf->SetFont('Arial','',9);

if($i%2 == 1){
$pdf->SetFillColor(181,175,173);
$pdf->SetTextColor(0);
$pdf->Row(array($n,$consulta['fecha_consulta'], $consulta['nombre_medico'], $consulta['consultorio'], $consulta['diagnostico']));
$i++;
}else{
$pdf->SetFillColor(212,204,202);
$pdf->SetTextColor(0);
$pdf->Row(array($n,$consulta['fecha_consulta'], $consulta['nombre_medico'], $consulta['consultorio'], $consulta['diagnostico']));
$i++;
}
}
// Salida del archivo y nombre
$pdf->Output('reporte.pdf','I');
?>

Conclusión

  • En este breve artículo hemos aprendido a manejar un CRUD en PHP con un listado de pacientes.
  • Para mostrar las consultas de los pacientes hemos aprendido a manejar la librería FPDF para visualizar el reporte en formato PDF
  • Hemos aprendo a darle colores, ancho personalizado a las celdas de tablas y exporta en PDF

Script corregido y actualizado

Nestor Tapia

Bloggero, amante de la programación PHP, innovador y me fascina compartir información. Desde que conocí el entorno informatico y el internet me llamó la atención la programación, Por tal motivo he creado mi blog BAULPHP.COM para compartir mis experiencias con todos ustedes. ¡Gracias por leerme!.

8 comentarios

  1. Saludos. Excelente explicacion y muy buena ejemplos. Tengo una consulta: Me funciona correctamente en localhost, pero cuando lo paso a la web funciona, solo que cuando doy clic en historial clinico no me genera el pdf….podrias guiarme…

    Gracias.

    1. Hola howard

      Echale un vistazo a la versión del PHP, verifica que version trabaja en localhost y luego verifica la versión del PHP de tu servidor.

      Otro detalle puede ser las rutas de carpetas.

      Saludos

      1. Saludos Nestor.
        gracias por responder.

        Mira las versiones del php son

        localhost es: PHP Version 5.6.39
        servidor web es: PHP Version 8.1.13

        creería que debería correr normal el script. cierto ¿?

        En cuanto a las carpetas as copie tal cual están. Reitero en localhost me funciona perfecto. el detalle esta al dar clic en generar historial clínico en la web, se queda con la ruta en en navegador: http://xxxxxxx/xxxxxxxx/historial.php?id=1.
        tanto para cada uno de los items existentes en la DB

      2. Saludos nuevamente Nestor:

        mira estas lineas:
        Dice que en la 32 es donde me da error segun el error_log

        Uncaught Error: Call to undefined function get_magic_quotes_gpc() in /home/xxxxxxxx/xxxxxxxxxxxxx/xxxxxxx/class/conexion.php:32

        *-* linea 32 aqui abajo en: if (get_magic_quotes_gpc()) {

        public function comillas_inteligentes($valor) {

        // Retirar las barras
        if (get_magic_quotes_gpc()) {
        $valor = stripslashes($valor);
        }
        // Colocar comillas si no es entero
        if (!is_numeric($valor)) {
        $valor = «‘» . $this->mysqli->real_escape_string($valor) . «‘»;
        }
        return $valor;
        }

        }

        1. Hola Howard
          La función get_magic_quotes_gpc() ha quedado Obsoleta a partir de PHP 7.4.0. Si desea usar esta funcion es preciso usar versión de PHP inferiores a 7.4.

          Según PHP no es recomendable usar esa función, he eliminado esa función y he actualizado el script para su descarga, revise en la parte final de este artículo.

          Saludos cordiales

          1. Nestor.

            Buenos Días.

            Efectivamente era esa linea. Agradezco mucho tu apoyo y tiempo.
            Ya funcionó.

            Muchas Gracias Nestor.

            Feliz Navidad !!!

  2. Buenas tardes Nestor.
    Al instalar tu aplicación me funciona perfectamente salvo que se ve todo el código que hay insertado en la base de datos como pueden ser las b de negrita o las p de los párrafos por poner 2 ejemplos.
    ¿Hay alguna forma de que se vea solo el texto como en cualquier pagina html?
    Gracias por adelantado.

    1. seguro no estas lanzando correctamente tu app, no puedes estar abriendo dandole clic derecho al archivo e iniciar con un navegador, debes al menos instalar xampp y correrlo con el servidor de apache

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba
Esta web utiliza cookies propias para su correcto funcionamiento. Contiene enlaces a sitios web de terceros con políticas de privacidad ajenas que podrás aceptar o no cuando accedas a ellos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad