From a35b976f9473fa9b146af386153309ab8a4770a6 Mon Sep 17 00:00:00 2001 From: Andreas Lind Date: Mon, 4 Jun 2018 15:25:42 +0200 Subject: [PATCH] Decode the _x<4 hex chars>_ escape notation in shared strings --- lib/xlsx/xform/strings/text-xform.js | 4 +++- .../data/shared_string_with_escape.xlsx | Bin 0 -> 8509 bytes spec/integration/workbook-xlsx-reader.spec.js | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 spec/integration/data/shared_string_with_escape.xlsx 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 0000000000000000000000000000000000000000..461548acc4bdec8c519fdc98221f0b8a7045959d GIT binary patch literal 8509 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 U1^#sb08IE51P|K<)Ib0IANNd|&j0`b literal 0 HcmV?d00001 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_'); + }); + }); });