在nodejs中转换csv时缺少标头

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

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

  1. A,B,C
  2. asia,west,4
  3. us,east,5
  4. asia,north,4

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

  1. import fs from "fs";
  2. import {parse} from "csv-parse";
  3. import through2 from "through2";
  4. const myTransform = (row) => {
  5. return {
  6. A: row.A + "-" + row.B,
  7. B: row.C
  8. }
  9. }
  10. fs.createReadStream("input.csv", {objectMode: true})
  11. .pipe(parse({columns: true}))
  12. .pipe(through2.obj(function(chunk, encoding, callback) {
  13. this.push(myTransform(chunk))
  14. callback()
  15. }))
  16. .pipe(through2.obj(function(chunk, encoding, callback) {
  17. this.push(Object.values(chunk).join(",")+"\n")
  18. callback()
  19. }))
  20. .pipe(fs.WriteStream("output.csv"));

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

  1. asia-west,4
  2. us-east,5
  3. asia-north,4

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

os8fio9y

os8fio9y1#

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

  1. const { Transform } = require('node:stream');
  2. const myTransform = new Transform({
  3. let isHeader = true;
  4. transform(chunk, encoding, callback) {
  5. // If this is the first line (i.e. the header)
  6. if (this.isHeader) {
  7. // Turn the given array back to a string and pass it along to write stream
  8. callback(null, chunk.join(',') + '\n');
  9. // Set this as false as the first line is completed
  10. this.isHeader = false;
  11. }
  12. // Get the values out of the array passed in from the parse method
  13. const [A, B, C] = chunk;
  14. // Build the new string row for the output csv
  15. const builtString = `${A}-${B},${C}\n`;
  16. // Pass along to the write string
  17. callback(null, builtString);
  18. },
  19. });
  20. fs.createReadStream("input.csv")
  21. .pipe(parse({delimiter: ","}))
  22. .pipe(myTransform)
  23. .pipe(fs.WriteStream("output.csv"));

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

展开查看全部

相关问题