Skip to content

Commit 222bc57

Browse files
committed
Add threaded comments support for XLSX format with parsing, serialization, and person management
- Added `threaded_comments` module with `ThreadedComment`, `ThreadedComments`, `Person`, `PersonList`, and `Mention` structures for modern Excel comment threads - Implemented XML parsing for threaded comments and person lists with support for @mentions, replies, timestamps, and resolution status - Implemented XML serialization for threaded comments and person lists with proper namespace handling
1 parent 4242e15 commit 222bc57

11 files changed

Lines changed: 907 additions & 10 deletions

File tree

docs/FEATURE_MATRIX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ This document tracks the implementation status of features across all supported
128128
| Shapes/Drawing objects |||| DrawingML shapes, text boxes, connectors |
129129
| External links |||| Linked workbooks and external refs |
130130
| Data connections / Query tables |||| External data connections |
131-
| Threaded comments | | | | Modern comment threads (`threadedComments`) |
131+
| Threaded comments | | | | Modern comment threads with @mentions, replies, and resolution status |
132132
| Pivot charts |||| Charts bound to pivot caches |
133133
| Timeline controls |||| Timeline slicers |
134134
| Workbook/worksheet views |||| Custom views and sheet views |

src/ooxml/opc/constants.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ pub mod content_type {
9898
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml";
9999
pub const SML_PIVOT_TABLE: &str =
100100
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml";
101+
pub const SML_COMMENTS: &str =
102+
"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml";
103+
pub const SML_THREADED_COMMENTS: &str = "application/vnd.ms-excel.threadedcomments+xml";
104+
pub const SML_PERSONS: &str = "application/vnd.ms-excel.person+xml";
105+
pub const SML_SHEET_METADATA: &str =
106+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml";
101107

102108
// Excel Binary File Format content types
103109
pub const XLSB_BIN: &str = "application/vnd.ms-excel.sheet.binary.macroEnabled.main";
@@ -220,6 +226,11 @@ pub mod relationship_type {
220226
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords";
221227
pub const PIVOT_TABLE: &str =
222228
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable";
229+
pub const THREADED_COMMENTS: &str =
230+
"http://schemas.microsoft.com/office/2017/10/relationships/threadedComment";
231+
pub const PERSONS: &str = "http://schemas.microsoft.com/office/2017/10/relationships/person";
232+
pub const SHEET_METADATA: &str =
233+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
223234

224235
// Images and media
225236
pub const IMAGE: &str =

src/ooxml/xlsx/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub mod sparkline;
4141
pub mod styles;
4242
pub mod table;
4343
pub mod template;
44+
pub mod threaded_comments;
4445
pub mod views;
4546
pub mod workbook;
4647
pub mod worksheet;
@@ -84,3 +85,8 @@ pub use writer::{
8485
PageBreak as WriterPageBreak, PageSetup as WriterPageSetup, RichTextRun, SheetProtection,
8586
StylesBuilder, WorkbookProtection,
8687
};
88+
// Re-export threaded comments types
89+
pub use threaded_comments::{
90+
Mention, Person, PersonList, ThreadedComment, ThreadedComments, read_persons,
91+
read_threaded_comments, write_persons, write_threaded_comments,
92+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
3+
xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata"
4+
xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">
5+
<metadataTypes count="1">
6+
<metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1"
7+
merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1"
8+
coerce="1" cellMeta="1" />
9+
</metadataTypes>
10+
<futureMetadata name="XLDAPR" count="1">
11+
<bk>
12+
<extLst>
13+
<ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">
14+
<xda:dynamicArrayProperties fDynamic="1" fCollapsed="0" />
15+
</ext>
16+
</extLst>
17+
</bk>
18+
</futureMetadata>
19+
<cellMetadata count="1">
20+
<bk>
21+
<rc t="1" v="0" />
22+
</bk>
23+
</cellMetadata>
24+
</metadata>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//! Threaded comments module for XLSX files.
2+
//!
3+
//! This module provides structures and functions for reading and writing
4+
//! threaded comments (modern Excel comment threads) in XLSX workbooks.
5+
//!
6+
//! Threaded comments are a modern feature introduced in Office 365 that
7+
//! support conversation threads, @mentions, and richer collaboration features.
8+
9+
pub mod person;
10+
pub mod reader;
11+
pub mod writer;
12+
13+
pub use person::{Mention, Person, PersonList};
14+
pub use reader::{read_persons, read_threaded_comments};
15+
pub use writer::{write_persons, write_threaded_comments};
16+
17+
/// A threaded comment in an Excel worksheet.
18+
///
19+
/// Threaded comments support conversation-style threads with replies,
20+
/// mentions, timestamps, and resolution status.
21+
#[derive(Debug, Clone, Default)]
22+
pub struct ThreadedComment {
23+
/// Cell reference (e.g., "A1")
24+
pub cell_ref: Option<String>,
25+
/// Unique identifier for this comment
26+
pub id: String,
27+
/// ID of the parent comment (for replies)
28+
pub parent_id: Option<String>,
29+
/// Person ID who authored this comment
30+
pub person_id: String,
31+
/// Comment text content
32+
pub text: Option<String>,
33+
/// Timestamp when comment was created/edited
34+
pub date_time: Option<String>,
35+
/// Whether this comment thread is marked as done/resolved
36+
pub done: Option<bool>,
37+
/// List of @mentions in the comment
38+
pub mentions: Vec<Mention>,
39+
}
40+
41+
/// Collection of threaded comments for a worksheet.
42+
#[derive(Debug, Clone, Default)]
43+
pub struct ThreadedComments {
44+
/// List of threaded comments
45+
pub comments: Vec<ThreadedComment>,
46+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! Person and mention data structures for threaded comments.
2+
3+
/// A person who can author threaded comments.
4+
///
5+
/// Persons are tracked separately in a person list XML part and referenced
6+
/// by their unique ID in threaded comments.
7+
#[derive(Debug, Clone, Default)]
8+
pub struct Person {
9+
/// Display name of the person
10+
pub display_name: String,
11+
/// Unique identifier (GUID)
12+
pub id: String,
13+
/// Optional user ID from identity provider
14+
pub user_id: Option<String>,
15+
/// Optional provider ID (e.g., Active Directory)
16+
pub provider_id: Option<String>,
17+
}
18+
19+
/// Collection of persons who can author comments in a workbook.
20+
#[derive(Debug, Clone, Default)]
21+
pub struct PersonList {
22+
/// List of persons
23+
pub persons: Vec<Person>,
24+
}
25+
26+
/// An @mention within a threaded comment.
27+
///
28+
/// Mentions allow tagging specific people within comment text using @username syntax.
29+
#[derive(Debug, Clone, Default)]
30+
pub struct Mention {
31+
/// Person ID being mentioned
32+
pub mention_person_id: String,
33+
/// Unique ID for this mention
34+
pub mention_id: String,
35+
/// Character offset where mention starts in text
36+
pub start_index: u32,
37+
/// Length of the mention text
38+
pub length: u32,
39+
}

0 commit comments

Comments
 (0)