Skip to content

Commit 79958aa

Browse files
committed
This closes #1903, made GetCellStyle, SetRowVisible and GetRowVisible functions concurrency safe
- Update comments of the functions and unit tests
1 parent 42ad4d6 commit 79958aa

File tree

4 files changed

+33
-9
lines changed

4 files changed

+33
-9
lines changed

cell_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
_ "image/jpeg"
66
"math"
7+
"math/rand"
78
"os"
89
"path/filepath"
910
"reflect"
@@ -42,6 +43,9 @@ func TestConcurrency(t *testing.T) {
4243
assert.NoError(t, err)
4344
// Concurrency set cell style
4445
assert.NoError(t, f.SetCellStyle("Sheet1", "A3", "A3", style))
46+
// Concurrency get cell style
47+
_, err = f.GetCellStyle("Sheet1", "A3")
48+
assert.NoError(t, err)
4549
// Concurrency add picture
4650
assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
4751
&GraphicOptions{
@@ -87,7 +91,12 @@ func TestConcurrency(t *testing.T) {
8791
// Concurrency get columns visible
8892
visible, err := f.GetColVisible("Sheet1", "A")
8993
assert.NoError(t, err)
90-
assert.Equal(t, true, visible)
94+
assert.True(t, visible)
95+
// Concurrency set row visible
96+
assert.NoError(t, f.SetRowVisible("Sheet1", 1+rand.Intn(1000), false))
97+
// Concurrency get row visible
98+
_, err = f.GetRowVisible("Sheet1", 1+rand.Intn(1000))
99+
assert.NoError(t, err)
91100
// Concurrency add data validation
92101
dv := NewDataValidation(true)
93102
dv.Sqref = fmt.Sprintf("A%d:B%d", val, val)

col.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,13 @@ func (f *File) SetColVisible(sheet, columns string, visible bool) error {
294294
if err != nil {
295295
return err
296296
}
297+
f.mu.Lock()
297298
ws, err := f.workSheetReader(sheet)
298299
if err != nil {
300+
f.mu.Unlock()
299301
return err
300302
}
303+
f.mu.Unlock()
301304
ws.mu.Lock()
302305
defer ws.mu.Unlock()
303306
colData := xlsxCol{

rows.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,37 +480,46 @@ func (f *File) sharedStringsReader() (*xlsxSST, error) {
480480
}
481481

482482
// SetRowVisible provides a function to set visible of a single row by given
483-
// worksheet name and Excel row number. For example, hide row 2 in Sheet1:
483+
// worksheet name and row number. This function is concurrency safe. For
484+
// example, hide row 2 in Sheet1:
484485
//
485486
// err := f.SetRowVisible("Sheet1", 2, false)
486487
func (f *File) SetRowVisible(sheet string, row int, visible bool) error {
487488
if row < 1 {
488489
return newInvalidRowNumberError(row)
489490
}
490-
491+
f.mu.Lock()
491492
ws, err := f.workSheetReader(sheet)
492493
if err != nil {
494+
f.mu.Unlock()
493495
return err
494496
}
497+
f.mu.Unlock()
498+
ws.mu.Lock()
499+
defer ws.mu.Unlock()
495500
ws.prepareSheetXML(0, row)
496501
ws.SheetData.Row[row-1].Hidden = !visible
497502
return nil
498503
}
499504

500505
// GetRowVisible provides a function to get visible of a single row by given
501-
// worksheet name and Excel row number. For example, get visible state of row
502-
// 2 in Sheet1:
506+
// worksheet name and row number. This function is concurrency safe. For
507+
// example, get visible state of row 2 in Sheet1:
503508
//
504509
// visible, err := f.GetRowVisible("Sheet1", 2)
505510
func (f *File) GetRowVisible(sheet string, row int) (bool, error) {
506511
if row < 1 {
507512
return false, newInvalidRowNumberError(row)
508513
}
509-
514+
f.mu.Lock()
510515
ws, err := f.workSheetReader(sheet)
511516
if err != nil {
517+
f.mu.Unlock()
512518
return false, err
513519
}
520+
f.mu.Unlock()
521+
ws.mu.Lock()
522+
defer ws.mu.Unlock()
514523
if row > len(ws.SheetData.Row) {
515524
return false, nil
516525
}

styles.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,19 +2186,22 @@ func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, a
21862186
}
21872187

21882188
// GetCellStyle provides a function to get cell style index by given worksheet
2189-
// name and cell reference.
2189+
// name and cell reference. This function is concurrency safe.
21902190
func (f *File) GetCellStyle(sheet, cell string) (int, error) {
2191+
f.mu.Lock()
21912192
ws, err := f.workSheetReader(sheet)
21922193
if err != nil {
2194+
f.mu.Unlock()
21932195
return 0, err
21942196
}
2197+
f.mu.Unlock()
2198+
ws.mu.Lock()
2199+
defer ws.mu.Unlock()
21952200
col, row, err := CellNameToCoordinates(cell)
21962201
if err != nil {
21972202
return 0, err
21982203
}
21992204
ws.prepareSheetXML(col, row)
2200-
ws.mu.Lock()
2201-
defer ws.mu.Unlock()
22022205
return ws.prepareCellStyle(col, row, ws.SheetData.Row[row-1].C[col-1].S), err
22032206
}
22042207

0 commit comments

Comments
 (0)