Skip to content

Commit 76f3368

Browse files
authored
This closes #849, add new function DeleteComment for delete comment (#1317)
- Update unit tests for the delete comment - Add 3 errors function for error messages
1 parent d1e76fc commit 76f3368

File tree

8 files changed

+88
-15
lines changed

8 files changed

+88
-15
lines changed

comment.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,39 @@ func (f *File) AddComment(sheet, cell, format string) error {
140140
return err
141141
}
142142

143+
// DeleteComment provides the method to delete comment in a sheet by given
144+
// worksheet. For example, delete the comment in Sheet1!$A$30:
145+
//
146+
// err := f.DeleteComment("Sheet1", "A30")
147+
func (f *File) DeleteComment(sheet, cell string) (err error) {
148+
sheetXMLPath, ok := f.getSheetXMLPath(sheet)
149+
if !ok {
150+
err = newNoExistSheetError(sheet)
151+
return
152+
}
153+
commentsXML := f.getSheetComments(filepath.Base(sheetXMLPath))
154+
if !strings.HasPrefix(commentsXML, "/") {
155+
commentsXML = "xl" + strings.TrimPrefix(commentsXML, "..")
156+
}
157+
commentsXML = strings.TrimPrefix(commentsXML, "/")
158+
if comments := f.commentsReader(commentsXML); comments != nil {
159+
for i, cmt := range comments.CommentList.Comment {
160+
if cmt.Ref == cell {
161+
if len(comments.CommentList.Comment) > 1 {
162+
comments.CommentList.Comment = append(
163+
comments.CommentList.Comment[:i],
164+
comments.CommentList.Comment[i+1:]...,
165+
)
166+
continue
167+
}
168+
comments.CommentList.Comment = nil
169+
}
170+
}
171+
f.Comments[commentsXML] = comments
172+
}
173+
return
174+
}
175+
143176
// addDrawingVML provides a function to create comment as
144177
// xl/drawings/vmlDrawing%d.vml by given commit ID and cell.
145178
func (f *File) addDrawingVML(commentID int, drawingVML, cell string, lineCount, colCount int) error {

comment_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,32 @@ func TestAddComments(t *testing.T) {
4646
assert.EqualValues(t, len(NewFile().GetComments()), 0)
4747
}
4848

49+
func TestDeleteComment(t *testing.T) {
50+
f, err := prepareTestBook1()
51+
if !assert.NoError(t, err) {
52+
t.FailNow()
53+
}
54+
55+
assert.NoError(t, f.AddComment("Sheet2", "A40", `{"author":"Excelize: ","text":"This is a comment1."}`))
56+
assert.NoError(t, f.AddComment("Sheet2", "A41", `{"author":"Excelize: ","text":"This is a comment2."}`))
57+
assert.NoError(t, f.AddComment("Sheet2", "C41", `{"author":"Excelize: ","text":"This is a comment3."}`))
58+
59+
assert.NoError(t, f.DeleteComment("Sheet2", "A40"))
60+
61+
assert.EqualValues(t, 2, len(f.GetComments()["Sheet2"]))
62+
assert.EqualValues(t, len(NewFile().GetComments()), 0)
63+
64+
// Test delete all comments in a worksheet
65+
assert.NoError(t, f.DeleteComment("Sheet2", "A41"))
66+
assert.NoError(t, f.DeleteComment("Sheet2", "C41"))
67+
assert.EqualValues(t, 0, len(f.GetComments()["Sheet2"]))
68+
// Test delete comment on not exists worksheet
69+
assert.EqualError(t, f.DeleteComment("SheetN", "A1"), "sheet SheetN is not exist")
70+
// Test delete comment with worksheet part
71+
f.Pkg.Delete("xl/worksheets/sheet1.xml")
72+
assert.NoError(t, f.DeleteComment("Sheet1", "A22"))
73+
}
74+
4975
func TestDecodeVMLDrawingReader(t *testing.T) {
5076
f := NewFile()
5177
path := "xl/drawings/vmlDrawing1.xml"

docProps.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ package excelize
1414
import (
1515
"bytes"
1616
"encoding/xml"
17-
"fmt"
1817
"io"
1918
"reflect"
2019
)
@@ -76,7 +75,7 @@ func (f *File) SetAppProps(appProperties *AppProperties) (err error) {
7675
app = new(xlsxProperties)
7776
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
7877
Decode(app); err != nil && err != io.EOF {
79-
err = fmt.Errorf("xml decode error: %s", err)
78+
err = newDecodeXMLError(err)
8079
return
8180
}
8281
fields = []string{"Application", "ScaleCrop", "DocSecurity", "Company", "LinksUpToDate", "HyperlinksChanged", "AppVersion"}
@@ -103,7 +102,7 @@ func (f *File) GetAppProps() (ret *AppProperties, err error) {
103102
app := new(xlsxProperties)
104103
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
105104
Decode(app); err != nil && err != io.EOF {
106-
err = fmt.Errorf("xml decode error: %s", err)
105+
err = newDecodeXMLError(err)
107106
return
108107
}
109108
ret, err = &AppProperties{
@@ -181,7 +180,7 @@ func (f *File) SetDocProps(docProperties *DocProperties) (err error) {
181180
core = new(decodeCoreProperties)
182181
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
183182
Decode(core); err != nil && err != io.EOF {
184-
err = fmt.Errorf("xml decode error: %s", err)
183+
err = newDecodeXMLError(err)
185184
return
186185
}
187186
newProps, err = &xlsxCoreProperties{
@@ -236,7 +235,7 @@ func (f *File) GetDocProps() (ret *DocProperties, err error) {
236235

237236
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
238237
Decode(core); err != nil && err != io.EOF {
239-
err = fmt.Errorf("xml decode error: %s", err)
238+
err = newDecodeXMLError(err)
240239
return
241240
}
242241
ret, err = &DocProperties{

drawing.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ package excelize
1414
import (
1515
"bytes"
1616
"encoding/xml"
17-
"fmt"
1817
"io"
1918
"log"
2019
"reflect"
@@ -1322,7 +1321,7 @@ func (f *File) deleteDrawing(col, row int, drawingXML, drawingType string) (err
13221321
deTwoCellAnchor = new(decodeTwoCellAnchor)
13231322
if err = f.xmlNewDecoder(strings.NewReader("<decodeTwoCellAnchor>" + wsDr.TwoCellAnchor[idx].GraphicFrame + "</decodeTwoCellAnchor>")).
13241323
Decode(deTwoCellAnchor); err != nil && err != io.EOF {
1325-
err = fmt.Errorf("xml decode error: %s", err)
1324+
err = newDecodeXMLError(err)
13261325
return
13271326
}
13281327
if err = nil; deTwoCellAnchor.From != nil && decodeTwoCellAnchorFuncs[drawingType](deTwoCellAnchor) {

errors.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,23 @@ func newCellNameToCoordinatesError(cell string, err error) error {
7070
return fmt.Errorf("cannot convert cell %q to coordinates: %v", cell, err)
7171
}
7272

73+
// newNoExistSheetError defined the error message on receiving the not exist
74+
// sheet name.
75+
func newNoExistSheetError(name string) error {
76+
return fmt.Errorf("sheet %s is not exist", name)
77+
}
78+
79+
// newNotWorksheetError defined the error message on receiving a sheet which
80+
// not a worksheet.
81+
func newNotWorksheetError(name string) error {
82+
return fmt.Errorf("sheet %s is not a worksheet", name)
83+
}
84+
85+
// newDecodeXMLError defined the error message on decode XML error.
86+
func newDecodeXMLError(err error) error {
87+
return fmt.Errorf("xml decode error: %s", err)
88+
}
89+
7390
var (
7491
// ErrStreamSetColWidth defined the error message on set column width in
7592
// stream writing mode.

excelize.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
231231
ok bool
232232
)
233233
if name, ok = f.getSheetXMLPath(sheet); !ok {
234-
err = fmt.Errorf("sheet %s is not exist", sheet)
234+
err = newNoExistSheetError(sheet)
235235
return
236236
}
237237
if worksheet, ok := f.Sheet.Load(name); ok && worksheet != nil {
@@ -240,7 +240,7 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
240240
}
241241
for _, sheetType := range []string{"xl/chartsheets", "xl/dialogsheet", "xl/macrosheet"} {
242242
if strings.HasPrefix(name, sheetType) {
243-
err = fmt.Errorf("sheet %s is not a worksheet", sheet)
243+
err = newNotWorksheetError(sheet)
244244
return
245245
}
246246
}
@@ -251,7 +251,7 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
251251
}
252252
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readBytes(name)))).
253253
Decode(ws); err != nil && err != io.EOF {
254-
err = fmt.Errorf("xml decode error: %s", err)
254+
err = newDecodeXMLError(err)
255255
return
256256
}
257257
err = nil
@@ -424,7 +424,7 @@ func (f *File) UpdateLinkedValue() error {
424424
for _, name := range f.GetSheetList() {
425425
ws, err := f.workSheetReader(name)
426426
if err != nil {
427-
if err.Error() == fmt.Sprintf("sheet %s is not a worksheet", trimSheetName(name)) {
427+
if err.Error() == newNotWorksheetError(name).Error() {
428428
continue
429429
}
430430
return err

picture.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"bytes"
1616
"encoding/json"
1717
"encoding/xml"
18-
"fmt"
1918
"image"
2019
"io"
2120
"io/ioutil"
@@ -554,15 +553,15 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
554553
deWsDr = new(decodeWsDr)
555554
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(drawingXML)))).
556555
Decode(deWsDr); err != nil && err != io.EOF {
557-
err = fmt.Errorf("xml decode error: %s", err)
556+
err = newDecodeXMLError(err)
558557
return
559558
}
560559
err = nil
561560
for _, anchor := range deWsDr.TwoCellAnchor {
562561
deTwoCellAnchor = new(decodeTwoCellAnchor)
563562
if err = f.xmlNewDecoder(strings.NewReader("<decodeTwoCellAnchor>" + anchor.Content + "</decodeTwoCellAnchor>")).
564563
Decode(deTwoCellAnchor); err != nil && err != io.EOF {
565-
err = fmt.Errorf("xml decode error: %s", err)
564+
err = newDecodeXMLError(err)
566565
return
567566
}
568567
if err = nil; deTwoCellAnchor.From != nil && deTwoCellAnchor.Pic != nil {

stream.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ type StreamWriter struct {
9292
func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
9393
sheetID := f.getSheetID(sheet)
9494
if sheetID == -1 {
95-
return nil, fmt.Errorf("sheet %s is not exist", sheet)
95+
return nil, newNoExistSheetError(sheet)
9696
}
9797
sw := &StreamWriter{
9898
File: f,

0 commit comments

Comments
 (0)