--- sidebar_position: 4 --- # Cell Comments
File Format Support (click to show) Comments and Notes have evolved over the years. "Notes" (powered by VML) were the original comments. "Comments" were added later. 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 | |:------------------|:-----:|:-------:|:--------:| | XLSX / XLSM | ✔ | ✔ | ✔ | | XLSB | ✔ | ✔ | R | | XLS | R | R | * | | XLML | ✔ | ✔ | * | | SYLK | | * | * | | ODS / FODS / UOS | ✔ | R | * | Asterisks (*) mark features that are not supported by the file formats. There is no way to specify a threaded comment in the SYLK format. The letter R (R) marks features parsed but not written in the format.
## 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 var cell = ws["A1"]; /* create comment array if it does not exist */ if(!cell.c) ws.A1.c = []; /* create a comment part */ var comment_part = { a:"SheetJS", t:"I'm a little comment, short and stout!" }; /* 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. :::
Live Export Example (click to hide) This example creates a small worksheet with a comment in cell A1: ```jsx live function SheetJSComments1() { return (); } ```
Live Import Example (click to hide) This example displays every comment in the workbook: ```jsx live function SheetJSParseComments(props) { const [__html, setHTML] = React.useState(""); return ( <> { /* 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")); }}/>
   );
}
```

## Visibility To mark a comment as normally hidden, set the `hidden` property: ```js if(!cell.c) cell.c = []; // highlight-next-line cell.c.hidden = true; cell.c.push({a:"SheetJS", t:"This comment will be hidden"}); ```
Live Example (click to hide) ```jsx live function SheetJSComments2() { return (); } ```
## Threaded Comments Introduced in Excel 365, threaded comments are plain text comment snippets with author metadata and parent references. They are supported in XLSX and XLSB. 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.
Live Example (click to hide) ```jsx live function SheetJSComments2() { return (); } ```