Leer y escribir archivos CSV con Node.js

El término CSV es una abreviatura que significa valores separados por comas. Un archivo CSV es un archivo de texto sin formato que contiene datos formateados de acuerdo con el estándar CSV...

Introducción

El término [CSV] (https://en.wikipedia.org/wiki/Comma-separated_values) es una abreviatura que significa valores separados por comas.

Un archivo CSV es un archivo de texto sin formato que contiene datos formateados de acuerdo con el estándar CSV. Tiene líneas distintas que representan registros y cada campo en el registro está separado de otro por una coma.

Es muy conveniente almacenar datos tabulares en CSV:

1
2
3
4
Name,Surname,Age,Gender
John,Snow,26,M
Clair,White,33,F
Fancy,Brown,78,F

Aquí, la primera fila representa los títulos de las columnas/campos de nuestros registros CSV y luego hay 3 registros que representan a ciertas personas. Como puede ver, los valores están delimitados por comas y cada registro comienza en una nueva fila.

Oye, pero ¿y si queremos incluir comas o saltos de línea en algunos de los campos que se almacenan en formato CSV?

Hay varios enfoques para resolver este problema, por ejemplo, podríamos encerrar dichos valores entre comillas dobles. Sin embargo, algunas de las implementaciones de CVS no son compatibles con esta función por diseño.

Estandarización CSV

Uno de los estándares CSV más utilizados se describe en RFC4180.

Según él, el formato CSV está descrito por estas 7 reglas:

  1. Cada registro se ubica en una línea separada, delimitada por un salto de línea (CRLF).
  2. El último registro del archivo puede tener o no un salto de línea final.
  3. Puede haber una línea de encabezado opcional que aparezca como la primera línea del archivo con el mismo formato que las líneas de registro normales. Este encabezado contendrá los nombres correspondientes a los campos del archivo y debe contener el mismo número de campos que los registros en el resto del archivo (la presencia o ausencia de la línea del encabezado debe indicarse a través del parámetro opcional "header" de este tipo MIME).
  4. Dentro del encabezado y de cada registro, puede haber uno o más campos, separados por comas. Cada línea debe contener el mismo número de campos en todo el archivo. Los espacios se consideran parte de un campo y no deben ignorarse. El último campo del registro no debe ir seguido de una coma.
  5. Cada campo puede o no estar encerrado entre comillas dobles (sin embargo, algunos programas, como Microsoft Excel, no usan comillas dobles). Si los campos no están entre comillas dobles, es posible que no aparezcan comillas dobles dentro de los campos.
  6. Los campos que contienen saltos de línea (CRLF), comillas dobles y comas deben estar entre comillas dobles.
  7. Si se utilizan comillas dobles para encerrar campos, las comillas dobles que aparecen dentro de un campo deben escaparse precediéndolas de otras comillas dobles.

Si está interesado en leer más con múltiples ejemplos, puede estudiar el documento RFC4180 original, vinculado anteriormente.

Leer archivos CSV en Node.js

Para leer un archivo CSV en Node.js, no podemos usar nada más que el módulo fs, ya que, en esencia, el archivo CSV es un archivo de texto sin formato.

If you're interested in reading more about Lectura de archivos con Node.js or Escribir archivos con Node.js, we've got both covered!

Sin embargo, hay un par de módulos útiles que podrían generar o analizar el contenido CSV por nosotros. Comenzaremos instalando el módulo csv-parser:

1
$ npm i -s csv-parser

Luego, coloquemos los datos CSV desde el principio del artículo en un archivo llamado "data.csv" y sigamos con un ejemplo muy simple:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const csv = require('csv-parser');
const fs = require('fs');

fs.createReadStream('data.csv')
  .pipe(csv())
  .on('data', (row) => {
    console.log(row);
  })
  .on('end', () => {
    console.log('CSV file successfully processed');
  });

Aquí, creamos un readStream usando el módulo fs, lo canalizamos al objeto csv que luego activará el evento data cada vez que se procese una nueva fila del archivo CSV. El evento end se activa cuando se procesan todas las filas del archivo CSV y registramos un mensaje corto en la consola para indicarlo.

Para fines de demostración, solo console.log cada fila procesada y después de ejecutar el código, verá este resultado en su consola:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Row {
  Name: 'John',
  'Surname': 'Snow',
  'Age': '26',
  'Gender': 'M' }
Row {
  Name: 'Clair',
  'Surname': 'White',
  'Age': '33',
  'Gender': 'F' }
Row {
  Name: 'Fancy',
  'Surname': 'Brown',
  'Age': '78',
  'Gender': 'F' }
CSV file successfully processed

Escribir archivos CSV en Node.js

Recordando el hecho de que los archivos CSV son solo archivos de texto sin formato, siempre podemos limitarnos a usar solo el módulo fs nativo, pero para facilitarnos la vida, usaremos otro módulo npm común, csv-writer .

Primero va la instalación:

1
$ npm i -s csv-writer

Entonces, el código:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const csvWriter = createCsvWriter({
  path: 'out.csv',
  header: [
    {id: 'name', title: 'Name'},
    {id: 'surname', title: 'Surname'},
    {id: 'age', title: 'Age'},
    {id: 'gender', title: 'Gender'},
  ]
});

const data = [
  {
    name: 'John',
    surname: 'Snow',
    age: 26,
    gender: 'M'
  }, {
    name: 'Clair',
    surname: 'White',
    age: 33,
    gender: 'F',
  }, {
    name: 'Fancy',
    surname: 'Brown',
    age: 78,
    gender: 'F'
  }
];

csvWriter
  .writeRecords(data)
  .then(()=> console.log('The CSV file was written successfully'));

El módulo csv-writer requiere una configuración inicial donde le proporcionamos el nombre del archivo CSV resultante y la configuración header.

Nota: En nuestro objeto de JavaScript, todas las propiedades están en minúsculas, pero en el archivo CSV, las primeras letras deben estar en mayúsculas.

Una vez finalizada la configuración, todo lo que tenemos que hacer es llamar a la función writeRecords, pasar la matriz data que representa la estructura de datos que debe escribirse en el archivo CSV.

Una vez realizado este proceso, imprimiremos un mensaje informativo en la consola indicando que el programa se ha completado.

Usando el módulo fast-csv

El ecosistema Node.js y npm ofrece muchas opciones para leer y escribir archivos CSV. Mostraremos otro ejemplo de un módulo CSV popular y veremos cómo podemos escribir nuestra matriz de datos utilizando el módulo fast-csv como alternativa.

Primero, tenemos que instalar el módulo:

1
$ npm i -s fast-csv
1
2
3
4
5
6
const fastcsv = require('fast-csv');
const fs = require('fs');
const ws = fs.createWriteStream("out.csv");
fastcsv
  .write(data, { headers: true })
  .pipe(ws);

La API es un poco diferente, pero el resultado es idéntico. En solo un par de líneas de código, logramos escribir la matriz de objetos de JavaScript en un archivo CSV que luego podría ser utilizado por una variedad de otras aplicaciones.

Conclusión

Leer y escribir archivos CSV con Node.js es una tarea de desarrollo común, ya que el formato CSV se usa comúnmente para almacenar datos tabulares estructurados. Muchos módulos npm brindan esta funcionalidad, por lo que debe elegir el que mejor se adapte a sus necesidades y tenga soporte continuo.

Licensed under CC BY-NC-SA 4.0