Generar un reporte en CSV desde el navegador es una de esas funcionalidades que parecen complicadas, pero con map en JavaScript puedes lograrlo en pocas líneas. Aquí verás cómo transformar una lista de hábitos en un archivo descargable, sin backend ni librerías externas.
¿Por qué usar map para exportar datos a CSV?
Cuando trabajas con un array de objetos o instancias de clase, map te permite transformar cada elemento en una estructura plana lista para convertirse en filas de un CSV. Es el mismo método que ya usas para renderizar listas, solo que ahora el destino es un archivo en vez del DOM.
¿Qué es un CSV? Es un archivo de texto plano donde cada fila representa un registro y los valores se separan por comas. Se abre en Excel, Google Drive o cualquier editor de texto.
La lógica detrás del ejercicio es construir un pipeline de transformación: tomas los datos crudos, los aplanas con map, los conviertes a líneas con comas, y los unes con saltos de línea para formar el contenido final del archivo.
¿Cómo construir el pipeline de transformación con map?
El primer paso es ubicar el botón en la interfaz. En el ejercicio se agrega junto al botón de registrar, con un identificador como export-habits [01:30]. Luego, en el archivo JS, se conecta un listener de click que dispara la función exportToCSV [02:15].
Dentro de esa función, el primer map recorre la lista de hábitos y crea un objeto plano con tres atributos:
- El nombre del hábito.
- La frecuencia con la que se repite.
- El conteo de veces registradas, calculado con el método
getBlocks().length de la clase [03:40].
Aquí entra un detalle importante: los hábitos vienen como instancias de una clase con métodos, no como objetos planos. Por eso necesitas esa primera transformación, para acceder a los datos calculados sin depender de la estructura interna del objeto original.
¿Se pueden encadenar varios map seguidos?
Sí, y es perfectamente válido. Puedes tener dos, cuatro o cinco map encadenados si eso hace tu código más legible [04:50]. El único costo es de rendimiento mínimo, ya que cada map recorre el array completo. En este caso, el segundo map toma cada objeto plano y lo convierte en una cadena con valores separados por comas, listo para el formato CSV.
¿Cuándo conviene encadenar map en lugar de combinar lógica? Cuando cada paso tiene una responsabilidad clara: aplanar datos, formatear strings, calcular agregados. La legibilidad pesa más que el microajuste de rendimiento.
Después de los dos map, se aplica join('\n') para unir todas las filas con saltos de línea. join también es uno de esos métodos que existe tanto para arrays como para strings, y aquí cierra el pipeline de procesamiento.
¿Cómo descargar el archivo CSV desde el navegador?
La parte de descarga es donde JavaScript se apoya en HTML para crear un archivo temporal. Necesitas tres piezas:
- Un objeto
Blob que envuelva el contenido en formato text/csv.
- Una URL temporal generada con
URL.createObjectURL().
- Una etiqueta ancla (
<a>) creada en memoria, con el atributo download apuntando a habits.csv, sobre la que se dispara un click programático [07:20].
El detalle que suele tropezar a quien lo hace por primera vez: Blob siempre recibe un array como primer argumento, nunca un string directo. Si le pasas el resultado del join sin envolverlo en corchetes, el navegador lanza un error de tipo de argumento [08:10].
js
const blob = new Blob([rows.join('\n')], { type: 'text/csv' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'habits.csv';
a.click();
Una vez corregido, el navegador descarga el archivo automáticamente. Lo abres en Excel, Google Drive o incluso en Visual Studio Code, y verás cada hábito con su frecuencia y conteo en columnas separadas.
¿Qué otros formatos puede generar Blob?
Blob no se limita a CSV. Puedes generar PDFs, imágenes, JSON o cualquier tipo de archivo, siempre que pases el contenido como array y especifiques el type correcto en el segundo argumento [08:40]. Esa flexibilidad lo convierte en la herramienta estándar para descargas dinámicas en el navegador.
¿Cómo mejorar el reporte con headers de columna?
El reporte actual exporta solo los datos, pero un CSV profesional incluye una primera fila con los nombres de columna: nombre,frecuencia,conteo. El reto de la clase es agregar esa cabecera antes de unir las filas con join, de modo que cualquier visualizador identifique las columnas automáticamente [10:15].
La idea es construir un array donde el primer elemento sea la cabecera y los siguientes sean los datos transformados. Después aplicas el mismo join('\n') y el archivo queda listo para abrirse en cualquier hoja de cálculo con los títulos en su lugar.
Este ejercicio muestra que map no solo sirve para renderizar en pantalla. El mismo método que usas para pintar tarjetas o listas en el DOM puede alimentar reportes, exportaciones y cualquier flujo donde necesites transformar datos de un formato a otro. ¿Ya intentaste agregar los headers a tu CSV? Cuéntame en los comentarios cómo te quedó el reto.