| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | --- | 
					
						
							| 
									
										
										
										
											2024-04-01 10:44:10 +00:00
										 |  |  | title: Cell Comments and Notes | 
					
						
							|  |  |  | sidebar_label: Cell Comments | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | sidebar_position: 4 | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>File Format Support</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  | Comments and Notes have evolved over the years. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Excel 2.0 - '95 "Notes" were displayed in a master list. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-24 01:17:05 +00:00
										 |  |  | Excel '97 - 2024 "Comments" float over the sheet and support styling. | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 08:38:23 +00:00
										 |  |  | Excel 365 introduced "Threaded Comments" which do not support rich text but do | 
					
						
							|  |  |  | allow users to "reply". The original "Comments" were renamed to "Notes". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | | Formats           | Notes | Comment | Threaded | | 
					
						
							|  |  |  | |:------------------|:-----:|:-------:|:--------:| | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  | | XLSX / XLSM       |   ✕   |    ✔    |    ✔     | | 
					
						
							|  |  |  | | XLSB              |   ✕   |    R    |    R     | | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | | NUMBERS           |   ✕   |    ✕    |    ✔     | | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  | | XLS (BIFF8)       |   ✕   |    ✔    |    ✕     | | 
					
						
							|  |  |  | | XLML              |   ✕   |    ✔    |    ✕     | | 
					
						
							|  |  |  | | ODS / FODS / UOS  |   ✕   |    ✔    |    ✕     | | 
					
						
							|  |  |  | | SYLK              |   ✔   |    ✕    |    ✕     | | 
					
						
							|  |  |  | | XLS (BIFF5)       |   ✔   |    ✕    |    ✕     | | 
					
						
							|  |  |  | | XLS (BIFF 2/3/4)  |   ✔   |    ✕    |    ✕     | | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | X (✕) marks features that are not supported by the file formats. For example, | 
					
						
							|  |  |  | the NUMBERS file format supports plaintext threaded comments but does not | 
					
						
							|  |  |  | support Excel styled comments or Excel legacy notes. | 
					
						
							| 
									
										
										
										
											2023-05-15 08:38:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The letter R (R) marks features parsed but not written in the format. | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 03:59:48 +00:00
										 |  |  | :::note pass | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | [SheetJS Pro](https://sheetjs.com/pro) supports comment rich text and styling. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-01 10:44:10 +00:00
										 |  |  | Comments and notes are cell annotations. Cells with comments or notes are marked | 
					
						
							|  |  |  | with a small triangle or `¬` in the upper-right corner. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Excel notes are standalone text boxes with adjustable background colors and | 
					
						
							|  |  |  | support for rich text. Historically people "replied" to comments by adding text | 
					
						
							|  |  |  | to the end of existing comments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Excel comments are simple text boxes that allow users to enter plain text. Users | 
					
						
							|  |  |  | can reply to comments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The following screenshot shows a spreadsheet with comments and a note. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - The note is associated with cell A1 (the cell with the red triangle). It has | 
					
						
							|  |  |  | a green gradient background fill. | 
					
						
							|  |  |  | - The comments are associated with cell A2 (the cell with the blue `¬`). There | 
					
						
							|  |  |  | are 2 comments from different authors. A "Reply" box appears below the thread. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::info pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Google Sheets "notes" do not currently support rich text or background colors. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Apple Numbers supports "comments" but does not support "notes". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | ## Basic Structure
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Cell comments are objects stored in the `c` array of cell objects. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The comment content is split into parts based on the comment author. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `a` field of each comment part is the author of the comment and the `t` | 
					
						
							|  |  |  | field is the plain text representation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For example, the following snippet appends a cell comment into cell `A1`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | /* get cell A1, creating an empty cell if necessary */ | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | var cell = ws["A1"]; | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | if(!ws["A1"]) ws["A1"] = { t: "z" }; | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* create comment array if it does not exist */ | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  | if(!cell.c) cell.c = []; | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* create a comment part */ | 
					
						
							|  |  |  | var comment_part = { | 
					
						
							| 
									
										
										
										
											2023-06-13 17:49:52 +00:00
										 |  |  |   a: "SheetJS", | 
					
						
							|  |  |  |   t: "I'm a little comment, short and stout!" | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Add comment part to the comment array */ | 
					
						
							|  |  |  | cell.c.push(comment_part); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note XLSB Author limits | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | XLSB enforces a 54 character limit on the Author name.  Names longer than 54 | 
					
						
							|  |  |  | characters may cause issues with other formats. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 03:59:48 +00:00
										 |  |  | ## Demos
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### Export
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details open> | 
					
						
							|  |  |  |   <summary><b>Live Export Example</b> (click to hide)</summary> | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This example creates a small worksheet with a comment in cell A1: | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSComments1() { | 
					
						
							|  |  |  |   return (<button onClick={() => { | 
					
						
							|  |  |  |     var ws = XLSX.utils.aoa_to_sheet([["SheetJS"]]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!ws.A1.c) ws.A1.c = []; | 
					
						
							|  |  |  |     ws.A1.c.push({a:"SheetJS", t:"I'm a little comment, short and stout!"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSComments1.xlsx"); | 
					
						
							|  |  |  |   }}>Click me to generate a sample file</button>); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-24 03:59:48 +00:00
										 |  |  | #### Import
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live Import Example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | This example displays every comment in the workbook: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSParseComments(props) { | 
					
						
							|  |  |  |   const [__html, setHTML] = React.useState(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( <> | 
					
						
							|  |  |  |     <input type="file" onChange={async(e) => { | 
					
						
							|  |  |  |       /* 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].c) continue; | 
					
						
							|  |  |  |           var comments = ws[addr].c; | 
					
						
							|  |  |  |           if(!comments.length) continue; | 
					
						
							|  |  |  |           var threaded = !!comments[0].T; | 
					
						
							|  |  |  |           var msg = comments.map(c => c.t).join(threaded ? "\n" : ""); | 
					
						
							|  |  |  |           console.log(comments); | 
					
						
							|  |  |  |           html.push(`${n}:${addr}:${+!!threaded}:${msg}`); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       setHTML(html.join("\n")); | 
					
						
							|  |  |  |     }}/> | 
					
						
							|  |  |  |     <pre dangerouslySetInnerHTML={{ __html }}/> | 
					
						
							|  |  |  |   </> ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | ## Visibility
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | The `hidden` property of the comment block indicates comment visibility. If set | 
					
						
							|  |  |  | to `true`, the comment will not be visible until users hover over the comment. | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | if(!cell.c) cell.c = []; | 
					
						
							|  |  |  | // highlight-next-line | 
					
						
							|  |  |  | cell.c.hidden = true; | 
					
						
							|  |  |  | cell.c.push({a:"SheetJS", t:"This comment will be hidden"}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Live Example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2023-09-24 03:59:48 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The following demo creates a worksheet with two comments. The comment in cell A1 | 
					
						
							|  |  |  | will be visibile and the comment in cell A2 will be hidden. | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							|  |  |  | function SheetJSComments2() { | 
					
						
							|  |  |  |   return (<button onClick={() => { | 
					
						
							|  |  |  |     var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!ws.A1.c) ws.A1.c = []; | 
					
						
							|  |  |  |     ws.A1.c.push({a:"SheetJS", t:"This comment is visible"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!ws.A2.c) ws.A2.c = []; | 
					
						
							|  |  |  |     ws.A2.c.hidden = true; | 
					
						
							|  |  |  |     ws.A2.c.push({a:"SheetJS", t:"This comment will be hidden"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSComments2.xlsx"); | 
					
						
							|  |  |  |   }}>Click me to generate a sample file</button>); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Threaded Comments
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  | Threaded comments are plain text comment snippets with author metadata and | 
					
						
							|  |  |  | parent references. They are supported in XLSX, XLSB, and NUMBERS files. | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | To mark a comment as threaded, each comment part must have a true `T` property: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | if(!cell.c) cell.c = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var part1 = { | 
					
						
							|  |  |  |   a:"SheetJS", | 
					
						
							|  |  |  |   t:"This is threaded", | 
					
						
							|  |  |  | // highlight-next-line | 
					
						
							|  |  |  |   T: true | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | cell.c.push(part1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var part2 = { | 
					
						
							|  |  |  |   a:"JSSheet", | 
					
						
							|  |  |  |   t:"This is also threaded", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | // The next line uses Object Spread syntax to add T: true | 
					
						
							|  |  |  | // highlight-next-line | 
					
						
							|  |  |  | cell.c.push({ ...part2, T: true}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There is no Active Directory or Office 365 metadata associated with authors. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 04:47:04 +00:00
										 |  |  | <details open> | 
					
						
							|  |  |  |   <summary><b>Live Example</b> (click to hide)</summary> | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```jsx live | 
					
						
							| 
									
										
										
										
											2023-09-24 03:59:48 +00:00
										 |  |  | function SheetJSThreadedComments() { | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  |   return ( <button onClick={() => { | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  |     var ws = XLSX.utils.aoa_to_sheet([["SheetJS"], [5433795]]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* normal comment */ | 
					
						
							|  |  |  |     if(!ws.A1.c) ws.A1.c = []; | 
					
						
							|  |  |  |     ws.A1.c.push({a:"SheetJS", t:"This is not threaded"}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  |     /* threaded comment */ | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  |     if(!ws.A2.c) ws.A2.c = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* add parts */ | 
					
						
							|  |  |  |     ws.A2.c.push({a:"SheetJS", t:"This is threaded", T: true}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var part = {a:"JSSheet", t:"This is also threaded"}; | 
					
						
							|  |  |  |     ws.A2.c.push({...part, T: true}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* create workbook and export */ | 
					
						
							|  |  |  |     var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); | 
					
						
							|  |  |  |     XLSX.writeFile(wb, "SheetJSThreadedComments.xlsx"); | 
					
						
							| 
									
										
										
										
											2023-06-14 19:32:34 +00:00
										 |  |  |   }}>Click me to generate a sample file</button> ); | 
					
						
							| 
									
										
										
										
											2022-09-02 07:16:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> |