在nodejs中转换csv时缺少标头

xuo3flqw  于 2023-03-21  发布在  其他
关注(0)|答案(1)|浏览(119)

我有一个名为“foo.csv”的csv文件,其中包含以下数据

A,B,C
asia,west,4
us,east,5
asia,north,4

我在nodejs中编写了一个函数,使用流来处理csv,它将前两列与-合并

import fs from "fs";
import {parse} from "csv-parse";
import through2 from "through2";

const myTransform = (row) => {
    return {
        A: row.A + "-" + row.B,
        B: row.C
    }
}

fs.createReadStream("input.csv", {objectMode: true})
    .pipe(parse({columns: true}))
    .pipe(through2.obj(function(chunk, encoding, callback) {
        this.push(myTransform(chunk))
        callback()
    }))
    .pipe(through2.obj(function(chunk, encoding, callback) {
        this.push(Object.values(chunk).join(",")+"\n")
        callback()
    }))
    .pipe(fs.WriteStream("output.csv"));

我在output.csv中正确地获得了如下输出

asia-west,4
us-east,5
asia-north,4

这显然漏掉了头,但是我怎样修改上面的代码来包含头呢?
此外,我可以删除throught2的使用,根据他们的文档,我认为这是可能的,但我不知道如何!!

os8fio9y

os8fio9y1#

标头不存在的原因是因为你使用了选项columns,这是在创建一个标头值为键的对象,这就是你如何通过row.A访问transform方法中的数据。
为了获得头,您需要沿着属性值,或者使用另一个选项解析出数据。
为了保存时间,我也会回答你问题的第二部分.是的,你可以不用through2,使用nodejs标准流API的transform流来轻松地完成这一点.它看起来非常接近你现在所拥有的:

const { Transform } = require('node:stream');

const myTransform = new Transform({
  let isHeader = true;
  transform(chunk, encoding, callback) {
    // If this is the first line (i.e. the header)
    if (this.isHeader) {
      // Turn the given array back to a string and pass it along to write stream
      callback(null, chunk.join(',') + '\n');
      // Set this as false as the first line is completed
      this.isHeader = false;
    }
    // Get the values out of the array passed in from the parse method
    const [A, B, C] = chunk;
    // Build the new string row for the output csv
    const builtString = `${A}-${B},${C}\n`;
    // Pass along to the write string
    callback(null, builtString);
  },
});

fs.createReadStream("input.csv")
  .pipe(parse({delimiter: ","}))
  .pipe(myTransform)
  .pipe(fs.WriteStream("output.csv"));

这样做将允许您稍微清理代码并处理转换流中的所有内容,而不是使用列将数据转换为需要重新格式化为字符串的对象。

相关问题