Solución:
El siguiente código hará lo que solicitó:
- Cuando se ejecuta por primera vez, escribirá los encabezados.
- Cada ejecución después de eso, agregará json los datos al archivo csv
var fs = require('fs');
var json2csv = require('json2csv');
var newLine="rn";
var fields = ['Total', 'Name'];
var appendThis = [
{
Total: '100',
Name: 'myName1',
},
{
Total: '200',
Name: 'myName2',
},
];
var toCsv = {
data: appendThis,
fields: fields,
header: false,
};
fs.stat('file.csv', function (err, stat) {
if (err == null) {
console.log('File exists');
//write the actual data and end with newline
var csv = json2csv(toCsv) + newLine;
fs.appendFile('file.csv', csv, function (err) {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
} else {
//write the headers and newline
console.log('New file, just writing headers');
fields = fields + newLine;
fs.writeFile('file.csv', fields, function (err) {
if (err) throw err;
console.log('file saved');
});
}
});
Hice algunos cambios en cómo se comporta la función, ahora valido con 2 métodos si hay un encabezado, si existe lo ignoro y agrego las filas, si no agrego el encabezado, elimino las comillas de los objetos y paso algunas espera, porque la función estaba sincronizada y no había espera, por lo que no tenía sentido ser asíncrono jajaja
El valor CSV pasado al nombre de archivo es el nombre de la carpeta que el nodo buscará en la raíz del proyecto para guardar su documento final.
Fiz umas mudanças em como a função se comporta, agora eu valido com 2 métodos se existe cabeçalho, se exist eu ignoro ele e adiciono as rows, se não eu adiciono o cabeçalho, removi as aspas dos objetos e passe uns awaits, porque a função era sync e não tinha nenhum espera então não fazia sentido ser async jajaja
O valor CSV passado para o nome do arquivo é o nome da pasta que o no procurará na raiz do projeto para salvar seu documento final
const fs = require("fs");
const path = require("path");
const json2csv = require("json2csv").parse;
// Constructor method to assist our ReadFileSync
const readFileSync = filePath =>
fs.readFileSync(filePath, { encoding: "utf-8" });
// A helper to search for values in files =D
const findWord = async (text, filePath) => {
const result = await readFileSync(path.join(__dirname, filePath));
return Promise.resolve(RegExp("\b" + text + "\b").test(result));
};
const write = async (fileName, fields, data) => {
// output file in the same folder
const filename = path.join(__dirname, "CSV", `${fileName}`);
let rows;
// I check if there is a header with these items
const hasValue = await findWord("Name,Position,Salary", "./CSV/test.csv");
// If there is a header I add the other lines without it if I don't follow the natural flow
if (hasValue) {
rows = json2csv(data, { header: false });
} else if (!fs.existsSync(fields)) {
// If file doesn't exist, we will create new file and add rows with headers.
rows = json2csv(data, { header: true });
} else {
// Rows without headers.
rows = json2csv(data, { header: false });
}
// I deal with the information by removing the quotes
const newRows = rows.replace(/[\"]/g, "");
// Append file function can create new file too.
await fs.appendFileSync(filename, newRows);
// Always add new line if file already exists.
await fs.appendFileSync(filename, "rn");
};
fields = ["Name", "Position", "Salary"];
data = [
{
Name: "Test1",
Position: "Manager",
Salary: "$10500",
},
{
Name: "Test2",
Position: "Tester",
Salary: "$5500",
},
{
Name: "Test3",
Position: "Developer",
Salary: "$5500",
},
{
Name: "Test4",
Position: "Team Lead",
Salary: "$7500",
},
];
write("test.csv", fields, data);
Output:
"Name","Position","Salary"
"Test1","Manager","$10500"
"Test2","Tester","$5500"
"Test3","Developer","$5500"
"Test4","Team Lead","$7500"