summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cell.go15
-rw-r--r--cell_test.go19
-rw-r--r--col.go31
-rw-r--r--excelize_test.go22
-rw-r--r--merge.go4
-rw-r--r--picture.go4
-rw-r--r--rows.go3
-rw-r--r--styles.go13
8 files changed, 79 insertions, 32 deletions
diff --git a/cell.go b/cell.go
index dd6b169..251cab8 100644
--- a/cell.go
+++ b/cell.go
@@ -60,7 +60,7 @@ var cellTypes = map[string]CellType{
// worksheet name and axis in spreadsheet file. If it is possible to apply a
// format to the cell value, it will do so, if not then an error will be
// returned, along with the raw value of the cell. All cells' values will be
-// the same in a merged range.
+// the same in a merged range. This function is concurrency safe.
func (f *File) GetCellValue(sheet, axis string, opts ...Options) (string, error) {
return f.getCellStringFunc(sheet, axis, func(x *xlsxWorksheet, c *xlsxC) (string, bool, error) {
val, err := c.getValueFrom(f, f.sharedStringsReader(), parseOptions(opts...).RawCellValue)
@@ -85,10 +85,10 @@ func (f *File) GetCellType(sheet, axis string) (CellType, error) {
return cellType, err
}
-// SetCellValue provides a function to set the value of a cell. The specified
-// coordinates should not be in the first row of the table, a complex number
-// can be set with string text. The following shows the supported data
-// types:
+// SetCellValue provides a function to set the value of a cell. This function
+// is concurrency safe. The specified coordinates should not be in the first
+// row of the table, a complex number can be set with string text. The
+// following shows the supported data types:
//
// int
// int8
@@ -1047,8 +1047,9 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
}
// SetSheetRow writes an array to row by given worksheet name, starting
-// coordinate and a pointer to array type 'slice'. For example, writes an
-// array to row 6 start with the cell B6 on Sheet1:
+// coordinate and a pointer to array type 'slice'. This function is
+// concurrency safe. For example, writes an array to row 6 start with the cell
+// B6 on Sheet1:
//
// err := f.SetSheetRow("Sheet1", "B6", &[]interface{}{"1", nil, 2})
func (f *File) SetSheetRow(sheet, axis string, slice interface{}) error {
diff --git a/cell_test.go b/cell_test.go
index 45970fc..5b8e639 100644
--- a/cell_test.go
+++ b/cell_test.go
@@ -64,7 +64,24 @@ func TestConcurrency(t *testing.T) {
_, err := cols.Rows()
assert.NoError(t, err)
}
-
+ // Concurrency set columns style
+ assert.NoError(t, f.SetColStyle("Sheet1", "C:E", style))
+ // Concurrency get columns style
+ styleID, err := f.GetColStyle("Sheet1", "D")
+ assert.NoError(t, err)
+ assert.Equal(t, style, styleID)
+ // Concurrency set columns width
+ assert.NoError(t, f.SetColWidth("Sheet1", "A", "B", 10))
+ // Concurrency get columns width
+ width, err := f.GetColWidth("Sheet1", "A")
+ assert.NoError(t, err)
+ assert.Equal(t, 10.0, width)
+ // Concurrency set columns visible
+ assert.NoError(t, f.SetColVisible("Sheet1", "A:B", true))
+ // Concurrency get columns visible
+ visible, err := f.GetColVisible("Sheet1", "A")
+ assert.NoError(t, err)
+ assert.Equal(t, true, visible)
wg.Done()
}(i, t)
}
diff --git a/col.go b/col.go
index b998f65..adc7f85 100644
--- a/col.go
+++ b/col.go
@@ -184,7 +184,8 @@ func columnXMLHandler(colIterator *columnXMLIterator, xmlElement *xml.StartEleme
}
// Cols returns a columns iterator, used for streaming reading data for a
-// worksheet with a large data. For example:
+// worksheet with a large data. This function is concurrency safe. For
+// example:
//
// cols, err := f.Cols("Sheet1")
// if err != nil {
@@ -239,8 +240,8 @@ func (f *File) Cols(sheet string) (*Cols, error) {
}
// GetColVisible provides a function to get visible of a single column by given
-// worksheet name and column name. For example, get visible state of column D
-// in Sheet1:
+// worksheet name and column name. This function is concurrency safe. For
+// example, get visible state of column D in Sheet1:
//
// visible, err := f.GetColVisible("Sheet1", "D")
func (f *File) GetColVisible(sheet, col string) (bool, error) {
@@ -252,6 +253,8 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
if err != nil {
return false, err
}
+ ws.Lock()
+ defer ws.Unlock()
if ws.Cols == nil {
return true, err
}
@@ -266,7 +269,7 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
}
// SetColVisible provides a function to set visible columns by given worksheet
-// name, columns range and visibility.
+// name, columns range and visibility. This function is concurrency safe.
//
// For example hide column D on Sheet1:
//
@@ -284,6 +287,8 @@ func (f *File) SetColVisible(sheet, columns string, visible bool) error {
if err != nil {
return err
}
+ ws.Lock()
+ defer ws.Unlock()
colData := xlsxCol{
Min: start,
Max: end,
@@ -399,9 +404,9 @@ func (f *File) SetColOutlineLevel(sheet, col string, level uint8) error {
}
// SetColStyle provides a function to set style of columns by given worksheet
-// name, columns range and style ID. Note that this will overwrite the
-// existing styles for the columns, it won't append or merge style with
-// existing styles.
+// name, columns range and style ID. This function is concurrency safe. Note
+// that this will overwrite the existing styles for the columns, it won't
+// append or merge style with existing styles.
//
// For example set style of column H on Sheet1:
//
@@ -426,6 +431,7 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
if err != nil {
return err
}
+ ws.Lock()
if ws.Cols == nil {
ws.Cols = &xlsxCols{}
}
@@ -444,6 +450,7 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
fc.Width = c.Width
return fc
})
+ ws.Unlock()
if rows := len(ws.SheetData.Row); rows > 0 {
for col := start; col <= end; col++ {
from, _ := CoordinatesToCellName(col, 1)
@@ -455,7 +462,7 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
}
// SetColWidth provides a function to set the width of a single column or
-// multiple columns. For example:
+// multiple columns. This function is concurrency safe. For example:
//
// f := excelize.NewFile()
// err := f.SetColWidth("Sheet1", "A", "H", 20)
@@ -479,6 +486,8 @@ func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error
if err != nil {
return err
}
+ ws.Lock()
+ defer ws.Unlock()
col := xlsxCol{
Min: min,
Max: max,
@@ -623,6 +632,8 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
// sheet name and column number.
func (f *File) getColWidth(sheet string, col int) int {
ws, _ := f.workSheetReader(sheet)
+ ws.Lock()
+ defer ws.Unlock()
if ws.Cols != nil {
var width float64
for _, v := range ws.Cols.Col {
@@ -639,7 +650,7 @@ func (f *File) getColWidth(sheet string, col int) int {
}
// GetColStyle provides a function to get column style ID by given worksheet
-// name and column name.
+// name and column name. This function is concurrency safe.
func (f *File) GetColStyle(sheet, col string) (int, error) {
var styleID int
colNum, err := ColumnNameToNumber(col)
@@ -663,7 +674,7 @@ func (f *File) GetColStyle(sheet, col string) (int, error) {
}
// GetColWidth provides a function to get column width by given worksheet name
-// and column name.
+// and column name. This function is concurrency safe.
func (f *File) GetColWidth(sheet, col string) (float64, error) {
colNum, err := ColumnNameToNumber(col)
if err != nil {
diff --git a/excelize_test.go b/excelize_test.go
index 93cd2bf..9d60b1c 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -1201,14 +1201,26 @@ func TestHSL(t *testing.T) {
assert.Equal(t, 0.0, hueToRGB(0, 0, 1.0/7))
assert.Equal(t, 0.0, hueToRGB(0, 0, 0.4))
assert.Equal(t, 0.0, hueToRGB(0, 0, 2.0/4))
- t.Log(RGBToHSL(255, 255, 0))
- h, s, l := RGBToHSL(0, 255, 255)
+ h, s, l := RGBToHSL(255, 255, 0)
+ assert.Equal(t, 0.16666666666666666, h)
+ assert.Equal(t, 1.0, s)
+ assert.Equal(t, 0.5, l)
+ h, s, l = RGBToHSL(0, 255, 255)
assert.Equal(t, 0.5, h)
assert.Equal(t, 1.0, s)
assert.Equal(t, 0.5, l)
- t.Log(RGBToHSL(250, 100, 50))
- t.Log(RGBToHSL(50, 100, 250))
- t.Log(RGBToHSL(250, 50, 100))
+ h, s, l = RGBToHSL(250, 100, 50)
+ assert.Equal(t, 0.041666666666666664, h)
+ assert.Equal(t, 0.9523809523809524, s)
+ assert.Equal(t, 0.5882352941176471, l)
+ h, s, l = RGBToHSL(50, 100, 250)
+ assert.Equal(t, 0.625, h)
+ assert.Equal(t, 0.9523809523809524, s)
+ assert.Equal(t, 0.5882352941176471, l)
+ h, s, l = RGBToHSL(250, 50, 100)
+ assert.Equal(t, 0.9583333333333334, h)
+ assert.Equal(t, 0.9523809523809524, s)
+ assert.Equal(t, 0.5882352941176471, l)
}
func TestProtectSheet(t *testing.T) {
diff --git a/merge.go b/merge.go
index d7400a2..c31416a 100644
--- a/merge.go
+++ b/merge.go
@@ -60,6 +60,8 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
if err != nil {
return err
}
+ ws.Lock()
+ defer ws.Unlock()
ref := hCell + ":" + vCell
if ws.MergeCells != nil {
ws.MergeCells.Cells = append(ws.MergeCells.Cells, &xlsxMergeCell{Ref: ref, rect: rect})
@@ -81,6 +83,8 @@ func (f *File) UnmergeCell(sheet string, hCell, vCell string) error {
if err != nil {
return err
}
+ ws.Lock()
+ defer ws.Unlock()
rect1, err := areaRefToCoordinates(hCell + ":" + vCell)
if err != nil {
return err
diff --git a/picture.go b/picture.go
index 07d18cc..30a255d 100644
--- a/picture.go
+++ b/picture.go
@@ -39,7 +39,7 @@ func parseFormatPictureSet(formatSet string) (*formatPicture, error) {
// AddPicture provides the method to add picture in a sheet by given picture
// format set (such as offset, scale, aspect ratio setting and print settings)
-// and file path. For example:
+// and file path. This function is concurrency safe. For example:
//
// package main
//
@@ -469,7 +469,7 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
// GetPicture provides a function to get picture base name and raw content
// embed in spreadsheet by given worksheet and cell name. This function
// returns the file name in spreadsheet and file contents as []byte data
-// types. For example:
+// types. This function is concurrency safe. For example:
//
// f, err := excelize.OpenFile("Book1.xlsx")
// if err != nil {
diff --git a/rows.go b/rows.go
index fdb9374..561f64b 100644
--- a/rows.go
+++ b/rows.go
@@ -238,7 +238,8 @@ func (rows *Rows) rowXMLHandler(rowIterator *rowXMLIterator, xmlElement *xml.Sta
}
// Rows returns a rows iterator, used for streaming reading data for a
-// worksheet with a large data. For example:
+// worksheet with a large data. This function is concurrency safe. For
+// example:
//
// rows, err := f.Rows("Sheet1")
// if err != nil {
diff --git a/styles.go b/styles.go
index 87c4863..ded7c30 100644
--- a/styles.go
+++ b/styles.go
@@ -1005,8 +1005,9 @@ func parseFormatStyleSet(style interface{}) (*Style, error) {
return &fs, err
}
-// NewStyle provides a function to create the style for cells by given JSON or
-// structure pointer. Note that the color field uses RGB color code.
+// NewStyle provides a function to create the style for cells by given
+// structure pointer or JSON. This function is concurrency safe. Note that the
+// color field uses RGB color code.
//
// The following shows the border styles sorted by excelize index number:
//
@@ -2493,10 +2494,10 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
}
// SetCellStyle provides a function to add style attribute for cells by given
-// worksheet name, coordinate area and style ID. Note that diagonalDown and
-// diagonalUp type border should be use same color in the same coordinate
-// area. SetCellStyle will overwrite the existing styles for the cell, it
-// won't append or merge style with existing styles.
+// worksheet name, coordinate area and style ID. This function is concurrency
+// safe. Note that diagonalDown and diagonalUp type border should be use same
+// color in the same coordinate area. SetCellStyle will overwrite the existing
+// styles for the cell, it won't append or merge style with existing styles.
//
// For example create a borders of cell H9 on Sheet1:
//