From 7593dcfadc1a07de96c51044128c14cf077db4ee Mon Sep 17 00:00:00 2001 From: hmalphettes Date: Tue, 23 Aug 2016 10:01:25 +0800 Subject: [PATCH] Support for mapHeaders to filter columns and edit the printed headers Setting the mapHeaders function in the options will skip some columns and edit the printed headers line. For example: ``` var writer = csv({ mapHeaders: function (header) { return header === 'skipthisone' ? null : header.substring(0,1).toUpperCase() + header.substring(1) } }) ``` This the reverse of csv-parser's `mapHeaders` --- index.js | 22 ++++++++++++++++++---- test.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index e550bd4..847236b 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ var CsvWriteStream = function(opts) { if (!opts) opts = {} stream.Transform.call(this, {objectMode:true, highWaterMark:16}) + this.mapHeaders = opts.mapHeaders || function(header) { return header } this.sendHeaders = opts.sendHeaders !== false this.headers = opts.headers || null this.separator = opts.separator || opts.seperator || ',' @@ -51,6 +52,18 @@ CsvWriteStream.prototype._transform = function(row, enc, cb) { if (!isArray && !this.headers) this.headers = Object.keys(row) if (this._first && this.headers) { + + var printedHeaders = []; + + for (var i = 0; i < this.headers.length; i++) { + var key = this.headers[i] + var printedHeader = this.mapHeaders(key, i) + printedHeaders.push(printedHeader) + if (typeof printedHeader !== 'string') { + this.headers[i] = null + } + } + this._first = false var objProps = [] @@ -58,14 +71,15 @@ CsvWriteStream.prototype._transform = function(row, enc, cb) { var heads = [] for (var i = 0; i < this.headers.length; i++) { - arrProps.push('obj['+i+']') - objProps.push(gen('obj', this.headers[i])) + if (this.headers[i] !== null) { + arrProps.push('obj['+i+']') + objProps.push(gen('obj', this.headers[i])) + } } this._objRow = this._compile(objProps) this._arrRow = this._compile(arrProps) - - if (this.sendHeaders) this.push(this._arrRow(this.headers)) + if (this.sendHeaders) this.push(this._arrRow(printedHeaders || this.headers)) } if (isArray) { diff --git a/test.js b/test.js index 7fec402..9eb2ff7 100644 --- a/test.js +++ b/test.js @@ -86,6 +86,56 @@ test('encode from object w/ auto headers', function(t) { writer.end() }) +test('encode from object w/ auto headers and one header skipped', function(t) { + var writer = csv({ + mapHeaders: function (header) { + return header !== 'foo' ? header : null + } + }) + + writer.pipe(concat(function(data) { + t.equal(data.toString(), 'hello,baz\nworld,taco\n') + t.end() + })) + + writer.write({hello: "world", foo: "bar", baz: "taco"}) + writer.end() +}) + +test('encode from object w/ auto headers and change the header', function(t) { + var writer = csv({ + mapHeaders: function (header) { + return header !== 'foo' ? header : 'Foo' + } + }) + + writer.pipe(concat(function(data) { + t.equal(data.toString(), 'hello,Foo,baz\nworld,bar,taco\n') + t.end() + })) + + writer.write({hello: "world", foo: "bar", baz: "taco"}) + writer.end() +}) + +test('encode from object edit header and filter one column', function(t) { + var writer = csv({ + headers: ['hello', 'foo', 'baz'], + mapHeaders: function (header) { + return header === 'foo' ? null + : header.substring(0,1).toUpperCase() + header.substring(1) + } + }) + + writer.pipe(concat(function(data) { + t.equal(data.toString(), 'Hello,Baz\nworld,taco\n') + t.end() + })) + + writer.write(["world", "bar", "taco"]) + writer.end() +}) + test('no headers specified', function(t) { var writer = csv()