diff options
-rw-r--r-- | cell.go | 15 | ||||
-rw-r--r-- | cell_test.go | 19 | ||||
-rw-r--r-- | col.go | 31 | ||||
-rw-r--r-- | excelize_test.go | 22 | ||||
-rw-r--r-- | merge.go | 4 | ||||
-rw-r--r-- | picture.go | 4 | ||||
-rw-r--r-- | rows.go | 3 | ||||
-rw-r--r-- | styles.go | 13 |
8 files changed, 79 insertions, 32 deletions
@@ -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) } @@ -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) { @@ -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 @@ -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 { @@ -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 { @@ -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: // |