diff --git a/lib/xlsx/xform/sheet/hyperlink-xform.js b/lib/xlsx/xform/sheet/hyperlink-xform.js index 3fb560a6d..88f4ee2ec 100644 --- a/lib/xlsx/xform/sheet/hyperlink-xform.js +++ b/lib/xlsx/xform/sheet/hyperlink-xform.js @@ -6,11 +6,20 @@ class HyperlinkXform extends BaseXform { } render(xmlStream, model) { - xmlStream.leafNode('hyperlink', { - ref: model.address, - 'r:id': model.rId, - tooltip: model.tooltip, - }); + if (this.isInternalLink(model)) { + xmlStream.leafNode('hyperlink', { + ref: model.address, + 'r:id': model.rId, + tooltip: model.tooltip, + location: model.target, + }); + } else { + xmlStream.leafNode('hyperlink', { + ref: model.address, + 'r:id': model.rId, + tooltip: model.tooltip, + }); + } } parseOpen(node) { @@ -20,6 +29,11 @@ class HyperlinkXform extends BaseXform { rId: node.attributes['r:id'], tooltip: node.attributes.tooltip, }; + + // This is an internal link + if (node.attributes.location) { + this.model.target = node.attributes.location; + } return true; } return false; @@ -30,6 +44,11 @@ class HyperlinkXform extends BaseXform { parseClose() { return false; } + + isInternalLink(model) { + // @example: Sheet2!D3, return true + return model.target && /^[^!]+![a-zA-Z]+[\d]+$/.test(model.target); + } } module.exports = HyperlinkXform; diff --git a/spec/unit/xlsx/xform/sheet/hyperlink-xform.spec.js b/spec/unit/xlsx/xform/sheet/hyperlink-xform.spec.js index 4292dfe9d..9e25bbc61 100644 --- a/spec/unit/xlsx/xform/sheet/hyperlink-xform.spec.js +++ b/spec/unit/xlsx/xform/sheet/hyperlink-xform.spec.js @@ -15,6 +15,18 @@ const expectations = [ xml: '', tests: ['render', 'renderIn', 'parse'], }, + { + title: 'Internal Link', + create() { + return new HyperlinkXform(); + }, + preparedModel: {address: 'B6', rId: 'rId1', target: 'sheet1!B2'}, + get parsedModel() { + return this.preparedModel; + }, + xml: '', + tests: ['render', 'renderIn', 'parse'], + }, ]; describe('HyperlinkXform', () => {