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', () => {