239 lines
10 KiB
PHP
239 lines
10 KiB
PHP
<?php
|
|
// export.php
|
|
require_once 'database/database.php'; // Ajusta esta ruta si es necesario
|
|
require('fpdf186/fpdf.php'); // Asegúrate que esta ruta a FPDF sea correcta
|
|
|
|
if ($conexion->connect_error) {
|
|
die("Error de conexión a la base de datos: " . $conexion->connect_error);
|
|
}
|
|
|
|
$type = $_GET['type'] ?? 'csv'; // csv o pdf
|
|
$report = $_GET['report'] ?? 'all_users'; // all_users o by_date_range
|
|
|
|
$startDate = $_GET['startDate'] ?? null;
|
|
$endDate = $_GET['endDate'] ?? null;
|
|
|
|
// Validar y limpiar fechas para evitar SQL Injection (¡muy importante!)
|
|
if ($startDate) $startDate = $conexion->real_escape_string($startDate);
|
|
if ($endDate) $endDate = $conexion->real_escape_string($endDate);
|
|
|
|
|
|
$query = "SELECT id_usuario, nombre, correo, telefono, genero, edad, estado_procedencia, identificacion, empresa, examen, certificacion, h_entrada, fecha FROM entrada";
|
|
$params = [];
|
|
$paramTypes = "";
|
|
|
|
// Construir la consulta SQL basada en el tipo de reporte
|
|
if ($report === 'by_date_range' && $startDate && $endDate) {
|
|
// Si queremos "todo el mes anterior" o "todo el año anterior", las fechas ya vendrán
|
|
// calculadas desde el frontend.
|
|
$query .= " WHERE fecha BETWEEN ? AND ?";
|
|
$params = [$startDate, $endDate];
|
|
$paramTypes = "ss"; // 's' para string, dos strings
|
|
} else {
|
|
// Si 'all_users' o no hay fechas válidas, exporta todo.
|
|
// Esto ya no debería ser el caso si el JS siempre envía fechas.
|
|
// Podrías poner un error aquí si esperas siempre un rango.
|
|
// Forzar un rango predeterminado si no llega nada?
|
|
// current month by default
|
|
$startDate = date('Y-m-01');
|
|
$endDate = date('Y-m-t');
|
|
$query .= " WHERE fecha BETWEEN ? AND ?";
|
|
$params = [$startDate, $endDate];
|
|
$paramTypes = "ss";
|
|
}
|
|
|
|
$stmt = $conexion->prepare($query);
|
|
|
|
if ($stmt === false) {
|
|
die("Error al preparar la consulta: " . $conexion->error);
|
|
}
|
|
|
|
if (!empty($params)) {
|
|
$stmt->bind_param($paramTypes, ...$params);
|
|
}
|
|
|
|
$stmt->execute();
|
|
$result = $stmt->get_result();
|
|
|
|
if ($result === false) {
|
|
die("Error al ejecutar la consulta: " . $conexion->error);
|
|
}
|
|
|
|
$data = [];
|
|
while ($row = $result->fetch_assoc()) {
|
|
$data[] = $row;
|
|
}
|
|
|
|
$stmt->close();
|
|
$conexion->close();
|
|
|
|
if (empty($data)) {
|
|
// No hay datos para exportar
|
|
if ($type === 'csv') {
|
|
header('Content-Type: text/csv');
|
|
header('Content-Disposition: attachment; filename="reporte_vacio.csv"');
|
|
echo "No hay datos para el rango de fechas seleccionado.";
|
|
} elseif ($type === 'pdf') {
|
|
class PDF_Empty extends FPDF {
|
|
function Header() { $this->SetFont('Arial','B',12); $this->Cell(0,10,utf8_decode('Reporte de Usuarios Registrados'),0,1,'C'); }
|
|
function Footer() { $this->SetY(-15); $this->SetFont('Arial','I',8); $this->Cell(0,10,utf8_decode('Página ').$this->PageNo().'/{nb}',0,0,'C'); }
|
|
function Content() {
|
|
$this->SetFont('Arial','',10);
|
|
$this->Cell(0, 10, utf8_decode('No hay datos para el rango de fechas seleccionado.'), 0, 1, 'C');
|
|
}
|
|
}
|
|
$pdfEmpty = new PDF_Empty();
|
|
$pdfEmpty->AddPage();
|
|
$pdfEmpty->Content();
|
|
$pdfEmpty->Output('I', 'reporte_vacio.pdf');
|
|
}
|
|
exit();
|
|
}
|
|
|
|
|
|
if ($type === 'csv') {
|
|
header('Content-Type: text/csv');
|
|
header('Content-Disposition: attachment; filename="reporte_usuarios_' . date('Ymd_His') . '.csv"');
|
|
|
|
$output = fopen('php://output', 'w');
|
|
|
|
// Nombres de las columnas (encabezado del CSV)
|
|
fputcsv($output, array_keys($data[0]));
|
|
|
|
// Datos
|
|
foreach ($data as $row) {
|
|
fputcsv($output, $row);
|
|
}
|
|
|
|
fclose($output);
|
|
} elseif ($type === 'pdf') {
|
|
class PDF extends FPDF
|
|
{
|
|
protected $startDate;
|
|
protected $endDate;
|
|
|
|
function setDateRange($start, $end) {
|
|
$this->startDate = $start;
|
|
$this->endDate = $end;
|
|
}
|
|
|
|
function Header()
|
|
{
|
|
$this->SetFont('Arial', 'B', 12);
|
|
$this->Cell(0, 10, utf8_decode('Reporte de Usuarios Registrados'), 0, 1, 'C');
|
|
$this->SetFont('Arial', '', 10);
|
|
if ($this->startDate && $this->endDate) {
|
|
$this->Cell(0, 10, utf8_decode('Rango de Fechas: ' . $this->startDate . ' a ' . $this->endDate), 0, 1, 'C');
|
|
}
|
|
$this->Ln(5);
|
|
}
|
|
|
|
function Footer()
|
|
{
|
|
$this->SetY(-15);
|
|
$this->SetFont('Arial', 'I', 8);
|
|
$this->Cell(0, 10, utf8_decode('Página ') . $this->PageNo() . '/{nb}', 0, 0, 'C');
|
|
}
|
|
|
|
function ImprovedTable($header, $data)
|
|
{
|
|
// Anchuras de las columnas (reajusta según tus datos y el tamaño de la página A4 apaisada ~277mm)
|
|
// Haz pruebas para que quepan todos tus datos. Si tienes demasiadas columnas, considera una fuente más pequeña.
|
|
$w = [10, 25, 40, 20, 15, 15, 25, 20, 20, 20, 20, 20, 20]; // Suma: 270mm (ajusta hasta 277mm)
|
|
// id, nombre, correo, telefono, genero, edad, estado, identificacion, empresa, examen, certificacion, h_entrada, fecha
|
|
|
|
$this->SetFillColor(200, 220, 255);
|
|
$this->SetTextColor(0);
|
|
$this->SetDrawColor(0, 0, 0);
|
|
$this->SetLineWidth(.3);
|
|
$this->SetFont('Arial', 'B', 7); // Fuente más pequeña para el encabezado
|
|
|
|
// Cabecera
|
|
for ($i = 0; $i < count($header); $i++) {
|
|
$this->Cell($w[$i], 7, utf8_decode($header[$i]), 1, 0, 'C', true);
|
|
}
|
|
$this->Ln();
|
|
|
|
$this->SetFillColor(224, 235, 255);
|
|
$this->SetTextColor(0);
|
|
$this->SetFont('Arial', '', 7); // Fuente más pequeña para los datos
|
|
|
|
$fill = false;
|
|
foreach ($data as $row) {
|
|
// Para calcular la altura de la fila basándose en el contenido de las celdas
|
|
$maxHeight = 6;
|
|
$cellContents = [];
|
|
|
|
foreach ($row as $key => $value) {
|
|
$cellContents[$key] = utf8_decode($value);
|
|
}
|
|
|
|
// Ajusta los índices de las columnas y sus anchos correspondientes
|
|
$columnsToCheck = [
|
|
'nombre' => $w[1], 'correo' => $w[2], 'estado_procedencia' => $w[6],
|
|
'empresa' => $w[8], 'examen' => $w[9], 'certificacion' => $w[10]
|
|
];
|
|
|
|
foreach($columnsToCheck as $colName => $colWidth) {
|
|
// Calcula la altura mínima para el texto si se ajusta al ancho de la celda
|
|
$neededHeight = $this->GetStringWidth($cellContents[$colName]) / $colWidth * $this->FontSize / 2.5; // Estimación
|
|
if ($neededHeight > $maxHeight) {
|
|
$maxHeight = $neededHeight;
|
|
}
|
|
}
|
|
$maxHeight = max($maxHeight, $this->FontSize + 2); // Asegura una altura mínima
|
|
|
|
// Verificar si se necesita una nueva página
|
|
if ($this->GetY() + $maxHeight > $this->PageBreakTrigger) {
|
|
$this->AddPage($this->CurOrientation);
|
|
// Volver a imprimir la cabecera de la tabla en la nueva página
|
|
$this->SetFillColor(200, 220, 255);
|
|
$this->SetTextColor(0);
|
|
$this->SetDrawColor(0, 0, 0);
|
|
$this->SetLineWidth(.3);
|
|
$this->SetFont('Arial', 'B', 7);
|
|
for ($i = 0; $i < count($header); $i++) {
|
|
$this->Cell($w[$i], 7, utf8_decode($header[$i]), 1, 0, 'C', true);
|
|
}
|
|
$this->Ln();
|
|
$this->SetFillColor(224, 235, 255);
|
|
$this->SetTextColor(0);
|
|
$this->SetFont('Arial', '', 7);
|
|
}
|
|
|
|
// Imprimir las celdas de la fila
|
|
$this->Cell($w[0], $maxHeight, $row['id_usuario'], 'LR', 0, 'C', $fill);
|
|
$this->Cell($w[1], $maxHeight, utf8_decode(mb_strimwidth($row['nombre'], 0, floor($w[1]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[2], $maxHeight, utf8_decode(mb_strimwidth($row['correo'], 0, floor($w[2]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[3], $maxHeight, utf8_decode($row['telefono']), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[4], $maxHeight, utf8_decode($row['genero']), 'LR', 0, 'C', $fill);
|
|
$this->Cell($w[5], $maxHeight, utf8_decode($row['edad']), 'LR', 0, 'C', $fill);
|
|
$this->Cell($w[6], $maxHeight, utf8_decode(mb_strimwidth($row['estado_procedencia'], 0, floor($w[6]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[7], $maxHeight, utf8_decode($row['identificacion']), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[8], $maxHeight, utf8_decode(mb_strimwidth($row['empresa'], 0, floor($w[8]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[9], $maxHeight, utf8_decode(mb_strimwidth($row['examen'], 0, floor($w[9]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[10], $maxHeight, utf8_decode(mb_strimwidth($row['certificacion'], 0, floor($w[10]/1.5), "...")), 'LR', 0, 'L', $fill);
|
|
$this->Cell($w[11], $maxHeight, utf8_decode($row['h_entrada']), 'LR', 0, 'C', $fill);
|
|
$this->Cell($w[12], $maxHeight, utf8_decode($row['fecha']), 'LR', 0, 'C', $fill);
|
|
|
|
$this->Ln($maxHeight);
|
|
$fill = !$fill;
|
|
}
|
|
$this->Cell(array_sum($w), 0, '', 'T');
|
|
}
|
|
}
|
|
|
|
$pdf = new PDF();
|
|
$pdf->AliasNbPages();
|
|
$pdf->AddPage('L'); // 'L' para orientación horizontal
|
|
$pdf->setDateRange($startDate, $endDate); // Pasar las fechas a la clase PDF
|
|
|
|
// Encabezados de la tabla (ajusta estos a tus columnas de la BD)
|
|
$header = array('ID', 'Nombre', 'Correo', 'Teléfono', 'Género', 'Edad', 'Estado', 'Identificación', 'Empresa', 'Examen', 'Certificación', 'H. Entrada', 'Fecha');
|
|
|
|
$pdf->ImprovedTable($header, $data);
|
|
$pdf->Output('I', 'reporte_usuarios_' . date('Ymd_His') . '.pdf');
|
|
} else {
|
|
echo "Tipo de exportación no soportado.";
|
|
}
|
|
?>
|