docs.sheetjs.com/docz/docs/07-csf/07-features/02-hyperlinks.md

234 lines
7.0 KiB
Markdown
Raw Normal View History

2022-06-09 21:43:33 +00:00
---
sidebar_position: 2
---
2022-05-27 14:59:53 +00:00
# Hyperlinks
<details>
2023-05-11 06:17:10 +00:00
<summary><b>File Format Support</b> (click to show)</summary>
2022-05-27 14:59:53 +00:00
2023-05-11 06:17:10 +00:00
| Formats | Link | Tooltip | Storage Representation |
|:------------------|:-----:|:-------:|:-----------------------|
| XLSX / XLSM | ✔ | ✔ | Cell Link + Tooltip |
| XLSB | ✔ | ✔ | Cell Link + Tooltip |
| XLS (BIFF8) | ✔ | ✔ | Cell Link + Tooltip |
| XLML | ✔ | ✔ | Cell Link + Tooltip |
| ODS / FODS / UOS | ✔ | | Span Link + Tooltip |
| HTML | ✔ | * | Span Link |
| NUMBERS | | * | Span Link ** |
2022-05-27 14:59:53 +00:00
2023-05-11 06:17:10 +00:00
Asterisks (*) mark features that are not supported by the file formats.
For "Span Link" formats, parsers apply the first hyperlink to the entire cell
and writers apply the hyperlink to the entire cell text.
2022-05-27 14:59:53 +00:00
</details>
Hyperlinks are stored in the `l` key of cell objects. The `Target` field of the
hyperlink object is the target of the link, including the URI fragment. Tooltips
are stored in the `Tooltip` field and are displayed when hovering over the text.
For example, the following snippet creates a link from cell `A3` to
<https://sheetjs.com> with the tip `"Find us @ SheetJS.com!"`:
```js
ws["A1"].l = { Target: "https://sheetjs.com", Tooltip: "Find us @ SheetJS.com!" };
```
2022-10-04 20:37:38 +00:00
:::note
2023-05-11 06:17:10 +00:00
Following traditional software, hyperlinks are applied to entire cell objects.
Some formats (including HTML) attach links to text spans. The parsers apply the
first link to the entire cell. Writers apply links to the entire cell text.
:::
:::caution
2022-10-04 20:37:38 +00:00
Excel does not automatically style hyperlinks. They will be displayed using
2023-05-11 06:17:10 +00:00
the default cell style.
<a href="https://sheetjs.com/pro">SheetJS Pro Basic</a> includes support for
general hyperlink styling.
2022-05-27 14:59:53 +00:00
2022-10-04 20:37:38 +00:00
:::
<details open><summary><b>Live Example</b> (click to hide)</summary>
2022-08-29 20:34:30 +00:00
```jsx live
/* The live editor requires this function wrapper */
2022-10-04 20:37:38 +00:00
function ExportSimpleLink(props) { return ( <button onClick={() => {
/* Create worksheet */
var ws = XLSX.utils.aoa_to_sheet([ [ "Link", "No Link" ] ]);
/* Add link */
ws["A1"].l = {
Target: "https://sheetjs.com",
Tooltip: "Find us @ SheetJS.com!"
};
/* Export to file (start a download) */
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
XLSX.writeFile(wb, "SheetJSSimpleLink.xlsx");
}}><b>Export XLSX!</b></button> ); }
2022-08-29 20:34:30 +00:00
```
</details>
2022-05-27 14:59:53 +00:00
## Remote Links
HTTP / HTTPS links can be used directly:
```js
2022-07-28 05:36:09 +00:00
ws["A2"].l = { Target: "https://docs.sheetjs.com/docs/csf/features/hyperlinks" };
2022-05-27 14:59:53 +00:00
ws["A3"].l = { Target: "http://localhost:7262/yes_localhost_works" };
```
Excel also supports `mailto` email links with subject line:
```js
ws["A4"].l = { Target: "mailto:ignored@dev.null" };
ws["A5"].l = { Target: "mailto:ignored@dev.null?subject=Test Subject" };
```
2022-10-04 20:37:38 +00:00
<details><summary><b>Live Example</b> (click to show)</summary>
**This demo creates a XLSX spreadsheet with a `mailto` email link. The email
address input in the form never leaves your machine.**
```jsx live
/* The live editor requires this function wrapper */
function ExportRemoteLink(props) {
const [email, setEmail] = React.useState("ignored@dev.null");
const set_email = React.useCallback((evt) => setEmail(evt.target.value));
/* Callback invoked when the button is clicked */
const xport = React.useCallback(() => {
/* Create worksheet */
var ws = XLSX.utils.aoa_to_sheet([ [ "HTTPS", "mailto" ] ]);
/* Add links */
ws["A1"].l = { Target: "https://sheetjs.com" };
ws["B1"].l = { Target: `mailto:${email}` };
/* Export to file (start a download) */
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
XLSX.writeFile(wb, "SheetJSRemoteLink.xlsx");
});
2023-02-28 11:40:44 +00:00
return ( <>
2022-10-04 20:37:38 +00:00
<b>Email: </b><input type="text" value={email} onChange={set_email} size="50"/>
<br/><button onClick={xport}><b>Export XLSX!</b></button>
2023-02-28 11:40:44 +00:00
</> );
2022-10-04 20:37:38 +00:00
}
```
</details>
2022-05-27 14:59:53 +00:00
## Local Links
Links to absolute paths should use the `file://` URI scheme:
```js
ws["B1"].l = { Target: "file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */
ws["B2"].l = { Target: "file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */
```
Links to relative paths can be specified without a scheme:
```js
ws["B3"].l = { Target: "SheetJS.xlsb" }; /* Link to SheetJS.xlsb */
ws["B4"].l = { Target: "../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */
```
2022-07-28 05:36:09 +00:00
:::caution
2022-05-27 14:59:53 +00:00
Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel
2019 will treat a `..\` parent mark as two levels up.
2022-07-28 05:36:09 +00:00
:::
2022-05-27 14:59:53 +00:00
## Internal Links
Links where the target is a cell or range or defined name in the same workbook
("Internal Links") are marked with a leading hash character:
```js
ws["C1"].l = { Target: "#E2" }; /* Link to cell E2 */
ws["C2"].l = { Target: "#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */
2022-10-04 20:37:38 +00:00
ws["C3"].l = { Target: "#SheetJSDName" }; /* Link to Defined Name */
```
<details><summary><b>Live Example</b> (click to show)</summary>
```jsx live
/* The live editor requires this function wrapper */
function ExportInternalLink(props) { return ( <button onClick={() => {
/* Create empty workbook */
var wb = XLSX.utils.book_new();
/* Create worksheet */
var ws = XLSX.utils.aoa_to_sheet([ [ "Same", "Cross", "Name" ] ]);
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
/* Create links */
ws["A1"].l = { Target: "#B2:D4", Tooltip: "Same-Sheet" };
ws["B1"].l = { Target: "#Sheet2!B2:D4", Tooltip: "Cross-Sheet" };
ws["C1"].l = { Target: "#SheetJSDN", Tooltip: "Defined Name" };
/* Create stub Sheet2 */
var ws2 = XLSX.utils.aoa_to_sheet([["This is Sheet2"]]);
XLSX.utils.book_append_sheet(wb, ws2, "Sheet2");
/* Create defined name */
wb.Workbook = {
Names: [{Name: "SheetJSDN", Ref:"Sheet2!A1:B2"}]
}
/* Export to file (start a download) */
XLSX.writeFile(wb, "SheetJSInternalLink.xlsx");
}}><b>Export XLSX!</b></button> ); }
2022-05-27 14:59:53 +00:00
```
2022-10-04 20:37:38 +00:00
</details>
:::caution
Some third-party tools like Google Sheets do not correctly parse hyperlinks in
XLSX documents. A workaround was added in library version 0.18.12.
:::
2022-05-27 14:59:53 +00:00
## HTML
The HTML DOM parser will process `<a>` links in the table:
2022-10-04 20:37:38 +00:00
<details open><summary><b>Live Example</b> (click to hide)</summary>
2022-05-27 14:59:53 +00:00
```jsx live
/* The live editor requires this function wrapper */
function ExportHyperlink(props) {
/* Callback invoked when the button is clicked */
const xport = React.useCallback(() => {
/* Create worksheet from HTML DOM TABLE */
const table = document.getElementById("TableLink");
const wb = XLSX.utils.table_to_book(table);
/* Export to file (start a download) */
2022-08-29 20:34:30 +00:00
XLSX.writeFile(wb, "SheetJSHTMLHyperlink.xlsx");
2022-05-27 14:59:53 +00:00
});
2023-02-28 11:40:44 +00:00
return ( <>
2022-05-27 14:59:53 +00:00
<button onClick={xport}><b>Export XLSX!</b></button>
<table id="TableLink"><tbody><tr><td>
Do not click here, for it is link-less.
</td></tr><tr><td>
<a href="https://sheetjs.com">Click here for more info</a>
</td></tr></tbody></table>
2023-02-28 11:40:44 +00:00
</> );
2022-05-27 14:59:53 +00:00
}
```
2022-10-04 20:37:38 +00:00
</details>