summaryrefslogtreecommitdiff
path: root/comment.go
diff options
context:
space:
mode:
Diffstat (limited to 'comment.go')
-rw-r--r--comment.go209
1 files changed, 209 insertions, 0 deletions
diff --git a/comment.go b/comment.go
new file mode 100644
index 0000000..4919ae1
--- /dev/null
+++ b/comment.go
@@ -0,0 +1,209 @@
+package excelize
+
+import (
+ "encoding/json"
+ "encoding/xml"
+ "strconv"
+ "strings"
+)
+
+// parseFormatCommentsSet provides function to parse the format settings of the
+// comment with default value.
+func parseFormatCommentsSet(formatSet string) *formatComment {
+ format := formatComment{
+ Author: "Author:",
+ Text: " ",
+ }
+ json.Unmarshal([]byte(formatSet), &format)
+ return &format
+}
+
+// AddComment provides the method to add comment in a sheet by given worksheet
+// index, cell and format set (such as author and text). For example, add a
+// comment in Sheet1!$A$30:
+//
+// xlsx.AddComment("Sheet1", "A30", `{"author":"Excelize","text":"This is a comment."}`)
+//
+func (f *File) AddComment(sheet, cell, format string) {
+ formatSet := parseFormatCommentsSet(format)
+ // Read sheet data.
+ xlsx := f.workSheetReader(sheet)
+ commentID := f.countComments() + 1
+ drawingVML := "xl/drawings/vmlDrawing" + strconv.Itoa(commentID) + ".vml"
+ sheetRelationshipsComments := "../comments" + strconv.Itoa(commentID) + ".xml"
+ sheetRelationshipsDrawingVML := "../drawings/vmlDrawing" + strconv.Itoa(commentID) + ".vml"
+ if xlsx.LegacyDrawing != nil {
+ // The worksheet already has a comments relationships, use the relationships drawing ../drawings/vmlDrawing%d.vml.
+ sheetRelationshipsDrawingVML = f.getSheetRelationshipsTargetByID(sheet, xlsx.LegacyDrawing.RID)
+ commentID, _ = strconv.Atoi(strings.TrimSuffix(strings.TrimPrefix(sheetRelationshipsDrawingVML, "../drawings/vmlDrawing"), ".vml"))
+ drawingVML = strings.Replace(sheetRelationshipsDrawingVML, "..", "xl", -1)
+ } else {
+ // Add first comment for given sheet.
+ rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingVML, sheetRelationshipsDrawingVML, "")
+ f.addSheetRelationships(sheet, SourceRelationshipComments, sheetRelationshipsComments, "")
+ f.addSheetLegacyDrawing(sheet, rID)
+ }
+ commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"
+ f.addComment(commentsXML, cell, formatSet)
+ f.addDrawingVML(commentID, drawingVML, cell)
+ f.addCommentsContentTypePart(commentID)
+}
+
+// addDrawingVML provides function to create comment as
+// xl/drawings/vmlDrawing%d.vml by given commit ID and cell.
+func (f *File) addDrawingVML(commentID int, drawingVML, cell string) {
+ col := string(strings.Map(letterOnlyMapF, cell))
+ row, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
+ xAxis := row - 1
+ yAxis := titleToNumber(col)
+ vml := vmlDrawing{
+ XMLNSv: "urn:schemas-microsoft-com:vml",
+ XMLNSo: "urn:schemas-microsoft-com:office:office",
+ XMLNSx: "urn:schemas-microsoft-com:office:excel",
+ XMLNSmv: "http://macVmlSchemaUri",
+ Shapelayout: &xlsxShapelayout{
+ Ext: "edit",
+ IDmap: &xlsxIDmap{
+ Ext: "edit",
+ Data: commentID,
+ },
+ },
+ Shapetype: &xlsxShapetype{
+ ID: "_x0000_t202",
+ Coordsize: "21600,21600",
+ Spt: 202,
+ Path: "m0,0l0,21600,21600,21600,21600,0xe",
+ Stroke: &xlsxStroke{
+ Joinstyle: "miter",
+ },
+ VPath: &vPath{
+ Gradientshapeok: "t",
+ Connecttype: "rect",
+ },
+ },
+ }
+ sp := encodeShape{
+ Fill: &vFill{
+ Color2: "#fbfe82",
+ Angle: -180,
+ Type: "gradient",
+ Fill: &oFill{
+ Ext: "view",
+ Type: "gradientUnscaled",
+ },
+ },
+ Shadow: &vShadow{
+ On: "t",
+ Color: "black",
+ Obscured: "t",
+ },
+ Path: &vPath{
+ Connecttype: "none",
+ },
+ Textbox: &vTextbox{
+ Style: "mso-direction-alt:auto",
+ Div: &xlsxDiv{
+ Style: "text-align:left",
+ },
+ },
+ ClientData: &xClientData{
+ ObjectType: "Note",
+ Anchor: "3, 15, 8, 6, 4, 54, 13, 2",
+ AutoFill: "False",
+ Row: xAxis,
+ Column: yAxis,
+ },
+ }
+ s, _ := xml.Marshal(sp)
+ shape := xlsxShape{
+ ID: "_x0000_s1025",
+ Type: "#_x0000_t202",
+ Style: "position:absolute;73.5pt;width:108pt;height:59.25pt;z-index:1;visibility:hidden",
+ Fillcolor: "#fbf6d6",
+ Strokecolor: "#edeaa1",
+ Val: string(s[13 : len(s)-14]),
+ }
+ c, ok := f.XLSX[drawingVML]
+ if ok {
+ d := decodeVmlDrawing{}
+ xml.Unmarshal([]byte(c), &d)
+ for _, v := range d.Shape {
+ s := xlsxShape{
+ ID: "_x0000_s1025",
+ Type: "#_x0000_t202",
+ Style: "position:absolute;73.5pt;width:108pt;height:59.25pt;z-index:1;visibility:hidden",
+ Fillcolor: "#fbf6d6",
+ Strokecolor: "#edeaa1",
+ Val: v.Val,
+ }
+ vml.Shape = append(vml.Shape, s)
+ }
+ }
+ vml.Shape = append(vml.Shape, shape)
+ v, _ := xml.Marshal(vml)
+ f.XLSX[drawingVML] = string(v)
+}
+
+// addComment provides function to create chart as xl/comments%d.xml by given
+// cell and format sets.
+func (f *File) addComment(commentsXML, cell string, formatSet *formatComment) {
+ comments := xlsxComments{
+ Authors: []xlsxAuthor{
+ xlsxAuthor{
+ Author: formatSet.Author,
+ },
+ },
+ }
+ cmt := xlsxComment{
+ Ref: cell,
+ AuthorID: 0,
+ Text: xlsxText{
+ R: []xlsxR{
+ xlsxR{
+ RPr: &xlsxRPr{
+ B: " ",
+ Sz: &attrValInt{Val: 9},
+ Color: &xlsxColor{
+ Indexed: 81,
+ },
+ RFont: &attrValString{Val: "Calibri"},
+ Family: &attrValInt{Val: 2},
+ },
+ T: formatSet.Author + ": ",
+ },
+ xlsxR{
+ RPr: &xlsxRPr{
+ Sz: &attrValInt{Val: 9},
+ Color: &xlsxColor{
+ Indexed: 81,
+ },
+ RFont: &attrValString{Val: "Calibri"},
+ Family: &attrValInt{Val: 2},
+ },
+ T: formatSet.Text,
+ },
+ },
+ },
+ }
+ c, ok := f.XLSX[commentsXML]
+ if ok {
+ d := xlsxComments{}
+ xml.Unmarshal([]byte(c), &d)
+ comments.CommentList.Comment = append(comments.CommentList.Comment, d.CommentList.Comment...)
+ }
+ comments.CommentList.Comment = append(comments.CommentList.Comment, cmt)
+ v, _ := xml.Marshal(comments)
+ f.saveFileList(commentsXML, string(v))
+}
+
+// countComments provides function to get comments files count storage in the
+// folder xl.
+func (f *File) countComments() int {
+ count := 0
+ for k := range f.XLSX {
+ if strings.Contains(k, "xl/comments") {
+ count++
+ }
+ }
+ return count
+}