From 5400fd9b3240a2183d08b237c7308483d6d5130a Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Fri, 24 Jul 2026 10:02:12 -0500 Subject: [PATCH] fix: exportar Excel como SpreadsheetML (.xls) en vez de CSV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Abre directamente en Excel con columnas formateadas, sin asistente de importación ni apertura en VS Code. Co-Authored-By: Claude Sonnet 4.6 --- lab_domicilios.php | 12 +++++++++--- lab_reportes.php | 24 ++++++++++++++---------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lab_domicilios.php b/lab_domicilios.php index ddfb3c0..92f50e7 100644 --- a/lab_domicilios.php +++ b/lab_domicilios.php @@ -1614,10 +1614,16 @@ async function ffExportarExcel() { ...fieldCols.map(([l,d])=>{ const v=todos[lmap.get(l)||d]; return v==null?'':(Array.isArray(v)?v.join('; '):String(v)); }), ]); }); - const csv = '\uFEFF' + csvRows.map(r=>r.map(v=>'"'+String(v).replace(/"/g,'""')+'"').join(',')).join('\r\n'); - const blob = new Blob([csv],{type:'text/csv;charset=utf-8;'}); + const xlsEsc = v => String(v).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); + const toCell = v => `${xlsEsc(v)}`; + const xml = `\n\n` + + `` + + `\n` + + csvRows.map(r => `${r.map(toCell).join('')}`).join('\n') + + `\n
`; + const blob = new Blob([xml], {type:'application/vnd.ms-excel;charset=utf-8'}); const url = URL.createObjectURL(blob); - const a = Object.assign(document.createElement('a'),{href:url,download:'formularios_domicilios_'+new Date().toISOString().slice(0,10)+'.csv'}); + const a = Object.assign(document.createElement('a'),{href:url,download:'formularios_domicilios_'+new Date().toISOString().slice(0,10)+'.xls'}); document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); mostrarToast('✅ Excel descargado — ' + rows.length + ' registro(s)', 'success'); } diff --git a/lab_reportes.php b/lab_reportes.php index df87106..b6eac6c 100644 --- a/lab_reportes.php +++ b/lab_reportes.php @@ -35,7 +35,7 @@ if ($tipo) { ORDER BY o.created_at DESC", [$desde, $hasta] ); - $filename = "ordenes_$desde\_$hasta.csv"; + $filename = "ordenes_$desde\_$hasta.xls"; $headers = ['ID','Paciente','Documento','EPS','Estado','Médico','Fecha Orden','Exámenes','Ayuno','H.Ayuno','Creada','Revisada por','Autorizada por']; break; @@ -109,7 +109,7 @@ if ($tipo) { $sqlParams ); $rangoLabel = !empty($_GET['fecha']) ? $_GET['fecha'] : "{$desde}_{$hasta}"; - $filename = "domicilios_{$rangoLabel}.csv"; + $filename = "domicilios_{$rangoLabel}.xls"; $headers = [ 'ID','Paciente','Documento','Teléfono','EPS', 'Fecha','Hora programada','Hora llegada','Hora salida','Duración', @@ -133,7 +133,7 @@ if ($tipo) { ORDER BY p.nombre_completo", [] ); - $filename = "pacientes_" . date('Y-m-d') . ".csv"; + $filename = "pacientes_" . date('Y-m-d') . ".xls"; $headers = ['ID','Nombre','Tipo Doc.','Documento','Teléfono','Email','EPS','Ciudad','Barrio','Activo','Total Órdenes','Registrado']; break; @@ -191,7 +191,7 @@ if ($tipo) { ORDER BY d.fecha_programada ASC, d.id ASC", $pParams ); - $filename = "reporte_pagos_{$rangoNombre}.csv"; + $filename = "reporte_pagos_{$rangoNombre}.xls"; $headers = [ 'ID','Fecha programada','Fecha pago','Paciente','Documento', 'Enfermero/a','Tipo cliente','Seguro','Estado domicilio', @@ -204,17 +204,21 @@ if ($tipo) { exit('Tipo de exportación no válido'); } - header('Content-Type: text/csv; charset=utf-8'); + header('Content-Type: application/vnd.ms-excel; charset=utf-8'); header("Content-Disposition: attachment; filename=\"$filename\""); header('Pragma: no-cache'); - $f = fopen('php://output', 'w'); - fputs($f, "\xEF\xBB\xBF"); // BOM UTF-8 para Excel - fputcsv($f, $headers); + $esc = fn($v) => htmlspecialchars((string)$v, ENT_XML1, 'UTF-8'); + echo '' . "\n"; + echo '' . "\n"; + echo '' . "\n"; + echo '' . "\n"; + echo '' . implode('', array_map(fn($h) => '' . $esc($h) . '', $headers)) . '' . "\n"; foreach ($rows as $row) { - fputcsv($f, array_values($row)); + echo '' . implode('', array_map(fn($v) => '' . $esc($v) . '', array_values($row))) . '' . "\n"; } - fclose($f); + echo '
'; exit; }