【问题标题】:How to append new row in exist csv file in nodejs json2csv?如何在nodejs json2csv中的现有csv文件中追加新行?
【发布时间】:2017-04-05 04:33:19
【问题描述】:

我想在现有的 csv 文件中添加新行?如果 csv 文件存在,那么我不想添加列标题,只想在文件中存在的行之后添加新行。

这是我正在尝试的代码:

var fields = ['total', 'results[0].name.val'];
var fieldNames = ['Total', 'Name'];

var opts1 = {
  data: data,
  fields: fields,
  fieldNames: fieldNames,
  newLine: '\r\n'

};

var opts2 = {
  newLine: '\r\n',
  data: data,
  fields: fields,
  fieldNames: fieldNames,
  hasCSVColumnTitle: false,

};

fs.stat('file.csv', function (err, stat) {
  if (err == null) {
    console.log('File exists');
    var csv = json2csv(opts2);
    fs.appendFile('file.csv', csv, function (err) {
      if (err) throw err;
      console.log('The "data to append" was appended to file!');
    });
  } else if (err.code == 'ENOENT') {
    // file does not exist
    var csv = json2csv(opts1);
    fs.writeFile('file.csv', csv, function (err) {
      if (err) throw err;
      console.log('file saved');
    });
  } else {
    console.log('Some other error: ', err.code);
  }
});

【问题讨论】:

  • 那么问题出在哪里?
  • 如何在现有的 csv 文件中追加新行?
  • 你已经有代码来检查文件是否已经存在。现在只是 append a new row. CSV 只是意味着“逗号分隔值”。以这种方式格式化数据非常容易。
  • 谢谢。它的工作。但是如何在 csv 文件中添加新行。我尝试使用 \t\n 命令,但没有按预期工作。
  • 你为什么要使用\t?这就是一个标签。你需要做\n(或\r\n),然后是你的新行。例如:'\n' + row.

标签: javascript json node.js csv npm-install


【解决方案1】:

以下代码将按照您的要求进行:

  1. 第一次运行时 - 将写入标头
  2. 之后的每次运行 - 都会将 json 数据附加到 csv 文件中
var fs = require('fs');
var json2csv = require('json2csv');
var newLine = '\r\n';

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');
    });
  }
});

【讨论】:

    【解决方案2】:

    似乎,最新版本的json2csv 有一个名为.parse() 的专用方法来将JSON 转换为CSV 兼容字符串。我尝试了json2csv.parse() 转换器,它对我有用。

    常见问题:

    我在此处给出的解决方案中发现了一个常见问题。如果我们多次运行该方法,则解决方案不会在没有 HEADER 的情况下附加数据。

    解决方案:

    我使用json2csv 提供的header 布尔选项来解决此问题。如果我们使用{header:false} 选项解析,我们将获取数据作为行。

    // Rows without headers.
    rows = json2csv(data, { header: false });
    

    下面是我上面提到的代码:

    示例代码:

    下面是代码示例:

    const fs = require('fs');
    const path = require('path');
    const json2csv = require('json2csv').parse;
    const write = async (fileName, fields, data) => {
        // output file in the same folder
        const filename = path.join(__dirname, 'CSV', `${fileName}`);
        let rows;
        // If file doesn't exist, we will create new file and add rows with headers.    
        if (!fs.existsSync(filename)) {
            rows = json2csv(data, { header: true });
        } else {
            // Rows without headers.
            rows = json2csv(data, { header: false });
        }
    
        // Append file function can create new file too.
        fs.appendFileSync(filename, rows);
        // Always add new line if file already exists.
        fs.appendFileSync(filename, "\r\n");
    }
    

    调用Write函数

    我们有 3 个参数:

    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

    write('test.csv', fields, data);
    

    每次我们调用上述方法时,它都会从新行开始写入。如果文件不存在,它只会写入一次标题。

    【讨论】:

      【解决方案3】:

      我对函数的行为方式进行了一些更改,现在我使用 2 种方法验证是否有标题,如果存在,我忽略它并添加行,如果没有,我添加标题,从对象中删除引号并传递一些等待,因为它是同步的功能并且没有等待所以异步没有意义哈哈哈

      传递给 filename 的 CSV 值是节点将在项目根目录中查找以保存最终文档的文件夹的名称

      ??

      Fiz umas mudanças em como a função se comporta, agora eu valido com 2 métodos se existe cabeçalho, se existir 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 await então não fazia sentido ser async haha​​ha

      O valor CSV passado para o nome do arquivo é o nome da Pasta que o nó 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, "\r\n");
      };
      
      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"
      

      【讨论】:

        【解决方案4】:

        使用 csv-write-stream 函数将数据追加到 csv 文件中。

        https://www.npmjs.com/package/csv-write-stream 添加这一行,带有标志“a”

        writer.pipe(fs.createWriteStream('out.csv', {flags: 'a'}))

        【讨论】:

          【解决方案5】:

          使用json-2-csv:

          /**
           *  this function will create the file if not exists or append the 
           *   data if exists
           */
          
          function exportToCsvFile(headersArray, dataJsonArray, filename) {
          
              converter.json2csvAsync(dataJsonArray, {prependHeader: false}).then(function (csv) {
          
              fs.exists(filename + '.csv', async function (exists) {
          
                  if (!exists) {
                      var newLine = "\r\n";
                      var headers = ((headersArray ? headersArray : []) + newLine);
          
                      exists= await createFileAsync(filename+ '.csv', headers);
                  }
          
                  if (exists) {
                      fs.appendFile(filename + '.csv', csv, 'utf8', function (err) {
                          if (err) {
                              console.log('error csv file either not saved or corrupted file saved.');
                          } else {
                              console.log(filename + '.csv file appended successfully!');
                          }
                      });
                  }
              });
          }).catch(function (err) {
              console.log("error while converting from json to csv: " + err);
              return false;
          });
          }
          
          
          function createFileAsync(filename, content) {
              return new Promise(function (resolve, reject) {
                  fs.writeFile(filename, content, 'utf8', function (err) {
                      if (err) {
                          console.log('error '+filename +' file either not saved or corrupted file saved.');
                          resolve(0);
                      } else {
                          console.log(filename + ' file created successfully!');
                          resolve(1);
                      }
                  });
              });
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-03-31
            • 2015-03-03
            • 2013-11-21
            • 1970-01-01
            • 2022-01-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多