| 
									
										
										
										
											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-07-19 03:27:47 +00:00
										 |  |  | Traditional spreadsheet software, including Excel, support "Cell Links". The | 
					
						
							|  |  |  | entire cell text is clickable. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Modern spreadsheet software, including Numbers, support "Span Links". Links are | 
					
						
							|  |  |  | applied to text fragments within the cell content. This mirrors HTML semantics. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | | Formats           | Link  | Tooltip | Link Type | | 
					
						
							|  |  |  | |:------------------|:-----:|:-------:|:----------| | 
					
						
							|  |  |  | | XLSX / XLSM       |   ✔   |    ✔    | Cell Link | | 
					
						
							|  |  |  | | XLSB              |   ✔   |    ✔    | Cell Link | | 
					
						
							|  |  |  | | XLS (BIFF8)       |   ✔   |    ✔    | Cell Link | | 
					
						
							|  |  |  | | XLML              |   ✔   |    ✔    | Cell Link | | 
					
						
							|  |  |  | | ODS / FODS / UOS  |   ✔   |         | Span Link | | 
					
						
							|  |  |  | | HTML              |   ✔   |    ✕    | Span Link | | 
					
						
							|  |  |  | | NUMBERS           |   ✔   |    ✕    | Span Link | | 
					
						
							| 
									
										
										
										
											2022-05-27 14:59:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | X (✕) marks features that are not supported by the file formats. For example, | 
					
						
							|  |  |  | the NUMBERS file format does not support custom tooltips. | 
					
						
							| 
									
										
										
										
											2023-05-11 06:17:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 03:27:47 +00:00
										 |  |  | For example, the following snippet creates a link from cell `A1` to | 
					
						
							| 
									
										
										
										
											2022-05-27 14:59:53 +00:00
										 |  |  | <https://sheetjs.com> with the tip `"Find us @ SheetJS.com!"`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | ws["A1"].l = { Target: "https://sheetjs.com", Tooltip: "Find us @ SheetJS.com!" }; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 03:27:47 +00:00
										 |  |  | :::note pass | 
					
						
							| 
									
										
										
										
											2022-10-04 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 03:27:47 +00:00
										 |  |  | :::caution pass | 
					
						
							| 
									
										
										
										
											2023-05-11 06:17:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-16 18:54:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | <details><summary><b>Extract all links from a file</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The following example iterates through each worksheet and each cell to find all | 
					
						
							|  |  |  | links. The table shows sheet name, cell address, and target for each link. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSParseLinks(props) { | 
					
						
							|  |  |  |   const [rows, setRows] = React.useState([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( <> | 
					
						
							|  |  |  |     <input type="file" onChange={async(e) => { | 
					
						
							|  |  |  |       let rows = []; | 
					
						
							|  |  |  |       /* parse workbook */ | 
					
						
							|  |  |  |       const file = e.target.files[0]; | 
					
						
							|  |  |  |       const data = await file.arrayBuffer(); | 
					
						
							|  |  |  |       const wb = XLSX.read(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const html = []; | 
					
						
							|  |  |  |       wb.SheetNames.forEach(n => { | 
					
						
							|  |  |  |         var ws = wb.Sheets[n]; if(!ws) return; | 
					
						
							|  |  |  |         var ref = XLSX.utils.decode_range(ws["!ref"]); | 
					
						
							|  |  |  |         for(var R = 0; R <= ref.e.r; ++R) for(var C = 0; C <= ref.e.c; ++C) { | 
					
						
							|  |  |  |           var addr = XLSX.utils.encode_cell({r:R,c:C}); | 
					
						
							|  |  |  |           if(!ws[addr] || !ws[addr].l) continue; | 
					
						
							|  |  |  |           var link = ws[addr].l; | 
					
						
							|  |  |  |           rows.push({ws:n, addr, Target: link.Target}); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       setRows(rows); | 
					
						
							|  |  |  |     }}/> | 
					
						
							|  |  |  |     <table><tr><th>Sheet</th><th>Address</th><th>Link Target</th></tr> | 
					
						
							|  |  |  |     {rows.map(r => (<tr><td>{r.ws}</td><td>{r.addr}</td><td>{r.Target}</td></tr>))} | 
					
						
							|  |  |  |     </table> | 
					
						
							|  |  |  |   </> ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </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 */ | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 03:27:47 +00:00
										 |  |  | :::caution pass | 
					
						
							| 
									
										
										
										
											2022-07-28 05:36:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-16 18:54:32 +00:00
										 |  |  | :::caution pass | 
					
						
							| 
									
										
										
										
											2022-10-04 20:37:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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> |