diff --git a/lib/xlsx/xform/strings/text-xform.js b/lib/xlsx/xform/strings/text-xform.js index c161da4c0..2d436ef36 100644 --- a/lib/xlsx/xform/strings/text-xform.js +++ b/lib/xlsx/xform/strings/text-xform.js @@ -28,7 +28,9 @@ utils.inherits(TextXform, BaseXform, { }, get model() { - return this._text.join(''); + return this._text.join('').replace(/_x([0-9A-F]{4})_/g, function($0, $1) { + return String.fromCharCode(parseInt($1, 16)); + }); }, parseOpen: function(node) { diff --git a/spec/integration/data/shared_string_with_escape.xlsx b/spec/integration/data/shared_string_with_escape.xlsx new file mode 100644 index 000000000..461548acc Binary files /dev/null and b/spec/integration/data/shared_string_with_escape.xlsx differ diff --git a/spec/integration/workbook-xlsx-reader.spec.js b/spec/integration/workbook-xlsx-reader.spec.js index dc6dedba0..ecbe23645 100644 --- a/spec/integration/workbook-xlsx-reader.spec.js +++ b/spec/integration/workbook-xlsx-reader.spec.js @@ -127,4 +127,20 @@ describe('WorkbookReader', function() { }); }); }); + + describe('with a spreadsheet that contains a shared string with an escaped underscore', function() { + before(function() { + var testContext = this; + var workbook = new Excel.Workbook(); + return workbook.xlsx.read(fs.createReadStream('./spec/integration/data/shared_string_with_escape.xlsx')) + .then(function() { + testContext.worksheet = workbook.getWorksheet(); + }); + }); + + it('should decode the underscore', function() { + const cell = this.worksheet.getCell('A1'); + expect(cell.value).to.equal('_x000D_'); + }); + }); });