Skip to content

Commit

Permalink
fix: Escape quotes excel (#512)
Browse files Browse the repository at this point in the history
* fix: properly escape quotes when using excel mode

* refactor: fix typo in comments

* perf: do quote replacement in a single pass
  • Loading branch information
juanjoDiaz authored Jan 27, 2021
1 parent e1ba2c1 commit ab3bf8a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 11 deletions.
16 changes: 9 additions & 7 deletions lib/JSON2CSVBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,16 @@ class JSON2CSVBase {
}

if (typeof value === 'string') {
if(value.includes(this.opts.quote)) {
value = value.replace(new RegExp(this.opts.quote, 'g'), this.opts.escapedQuote);
}

value = `${this.opts.quote}${value}${this.opts.quote}`;

if (this.opts.excelStrings) {
value = `"="${value}""`;
if(value.includes(this.opts.quote)) {
value = value.replace(new RegExp(this.opts.quote, 'g'), `${this.opts.escapedQuote}${this.opts.escapedQuote}`);
}
value = `"=""${value}"""`;
} else {
if(value.includes(this.opts.quote)) {
value = value.replace(new RegExp(this.opts.quote, 'g'), this.opts.escapedQuote);
}
value = `${this.opts.quote}${value}${this.opts.quote}`;
}
}

Expand Down
13 changes: 12 additions & 1 deletion test/CLI.js
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
});
});

// Excell
// Excel

testRunner.add('should format strings to force excel to view the values as strings', (t) => {
const opts = '--fields carModel,price,color --excel-strings';
Expand All @@ -443,6 +443,17 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
});
});

testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => {
const opts = '--excel-strings';

exec(`${cli} -i "${getFixturePath('/json/quotes.json')}" ${opts}`, (err, stdout, stderr) => {
t.notOk(stderr);
const csv = stdout;
t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted);
t.end();
});
});

// Escaping and preserving values

testRunner.add('should parse JSON values with trailing backslashes', (t) => {
Expand Down
18 changes: 17 additions & 1 deletion test/JSON2CSVAsyncParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =
t.end();
});

// Excell
// Excel

testRunner.add('should format strings to force excel to view the values as strings', async (t) => {
const opts = {
Expand All @@ -787,6 +787,22 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =
t.end();
});

testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', async (t) => {
const opts = {
excelStrings:true
};
const parser = new AsyncParser(opts);

try {
const csv = await parser.fromInput(jsonFixtures.quotes()).promise();
t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted);
} catch(err) {
t.fail(err.message);
}

t.end();
});

// Escaping and preserving values

testRunner.add('should parse JSON values with trailing backslashes', async (t) => {
Expand Down
14 changes: 13 additions & 1 deletion test/JSON2CSVParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
t.end();
});

// Excell
// Excel

testRunner.add('should format strings to force excel to view the values as strings', (t) => {
const opts = {
Expand All @@ -530,6 +530,18 @@ module.exports = (testRunner, jsonFixtures, csvFixtures) => {
t.end();
});

testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => {
const opts = {
excelStrings:true
};

const parser = new Json2csvParser(opts);
const csv = parser.parse(jsonFixtures.quotes);

t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted);
t.end();
});

// Escaping and preserving values

testRunner.add('should parse JSON values with trailing backslashes', (t) => {
Expand Down
23 changes: 22 additions & 1 deletion test/JSON2CSVTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =
});
});

// Excell
// Excel

testRunner.add('should format strings to force excel to view the values as strings', (t) => {
const opts = {
Expand All @@ -866,6 +866,27 @@ module.exports = (testRunner, jsonFixtures, csvFixtures, inMemoryJsonFixtures) =
});
});

testRunner.add('should format strings to force excel to view the values as strings with escaped quotes', (t) => {
const opts = {
excelStrings:true
};

const transform = new Json2csvTransform(opts);
const processor = jsonFixtures.quotes().pipe(transform);

let csv = '';
processor
.on('data', chunk => (csv += chunk.toString()))
.on('end', () => {
t.equal(csv, csvFixtures.excelStringsWithEscapedQuoted);
t.end();
})
.on('error', err => {
t.fail(err.message);
t.end();
});
});

// Escaping and preserving values

testRunner.add('should parse JSON values with trailing backslashes', (t) => {
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/csv/excelStringsWithEscapedQuoted.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"=""a string"""
"=""with a description"""
"=""with a description and """"quotes"""""""

0 comments on commit ab3bf8a

Please sign in to comment.