diff --git a/col.go b/col.go index 7fbeebab..d2eba8b0 100644 --- a/col.go +++ b/col.go @@ -398,7 +398,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. +// name, columns range and style ID. Note that this will overwrite the +// existing styles for the cell, it won't append or merge style with existing +// styles. // // For example set style of column H on Sheet1: // diff --git a/errors.go b/errors.go index aee44200..4cfd12e9 100644 --- a/errors.go +++ b/errors.go @@ -46,6 +46,11 @@ func newUnzipSizeLimitError(unzipSizeLimit int64) error { return fmt.Errorf("unzip size exceeds the %d bytes limit", unzipSizeLimit) } +// newInvalidStyleID defined the error message on receiving the invalid style ID. +func newInvalidStyleID(styleID int) error { + return fmt.Errorf("invalid style ID %d, negative values are not supported", styleID) +} + var ( // ErrStreamSetColWidth defined the error message on set column width in // stream writing mode. @@ -76,6 +81,8 @@ var ( ErrAddVBAProject = errors.New("unsupported VBA project extension") // ErrToExcelTime defined the error message on receive a not UTC time. ErrToExcelTime = errors.New("only UTC time expected") + // ErrMaxRows defined the error message on receive a row number exceeds maximum limit. + ErrMaxRows = errors.New("row number exceeds maximum limit") // ErrMaxRowHeight defined the error message on receive an invalid row // height. ErrMaxRowHeight = errors.New("the height of the row must be smaller than or equal to 409 points") diff --git a/lib.go b/lib.go index 81f1e53b..424d3f9b 100644 --- a/lib.go +++ b/lib.go @@ -196,7 +196,7 @@ func CellNameToCoordinates(cell string) (int, int, error) { return -1, -1, fmt.Errorf(msg, cell, err) } if row > TotalRows { - return -1, -1, fmt.Errorf("row number exceeds maximum limit") + return -1, -1, ErrMaxRows } col, err := ColumnNameToNumber(colname) return col, row, err diff --git a/rows.go b/rows.go index 5fa2cb45..fb03bba5 100644 --- a/rows.go +++ b/rows.go @@ -23,8 +23,9 @@ import ( "github.com/mohae/deepcopy" ) -// GetRows return all the rows in a sheet by given worksheet name (case -// sensitive). For example: +// GetRows return all the rows in a sheet by given worksheet name +// (case sensitive). GetRows fetched the rows with value or formula cells, +// the tail continuously empty cell will be skipped. For example: // // rows, err := f.GetRows("Sheet1") // if err != nil { @@ -719,6 +720,43 @@ func checkRow(ws *xlsxWorksheet) error { return nil } +// SetRowStyle provides a function to set style of rows by given worksheet +// name, row range and style ID. Note that this will overwrite the existing +// styles for the cell, it won't append or merge style with existing styles. +// +// For example set style of row 1 on Sheet1: +// +// err = f.SetRowStyle("Sheet1", 1, style) +// +// Set style of rows 1 to 10 on Sheet1: +// +// err = f.SetRowStyle("Sheet1", 1, 10, style) +// +func (f *File) SetRowStyle(sheet string, start, end, styleID int) error { + if end < start { + start, end = end, start + } + if start < 1 { + return newInvalidRowNumberError(start) + } + if end > TotalRows { + return ErrMaxRows + } + if styleID < 0 { + return newInvalidStyleID(styleID) + } + ws, err := f.workSheetReader(sheet) + if err != nil { + return err + } + prepareSheetXML(ws, 0, end) + for row := start - 1; row < end; row++ { + ws.SheetData.Row[row].S = styleID + ws.SheetData.Row[row].CustomFormat = true + } + return nil +} + // convertRowHeightToPixels provides a function to convert the height of a // cell from user's units to pixels. If the height hasn't been set by the user // we use the default value. If the row is hidden it has a value of zero. diff --git a/rows_test.go b/rows_test.go index 76824693..a54e755d 100644 --- a/rows_test.go +++ b/rows_test.go @@ -889,6 +889,18 @@ func TestCheckRow(t *testing.T) { assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`) } +func TestSetRowStyle(t *testing.T) { + f := NewFile() + styleID, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":1}}`) + assert.NoError(t, err) + assert.EqualError(t, f.SetRowStyle("Sheet1", 10, -1, styleID), newInvalidRowNumberError(-1).Error()) + assert.EqualError(t, f.SetRowStyle("Sheet1", 1, TotalRows+1, styleID), ErrMaxRows.Error()) + assert.EqualError(t, f.SetRowStyle("Sheet1", 1, 1, -1), newInvalidStyleID(-1).Error()) + assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, styleID), "sheet SheetN is not exist") + assert.NoError(t, f.SetRowStyle("Sheet1", 10, 1, styleID)) + assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetRowStyle.xlsx"))) +} + func TestNumberFormats(t *testing.T) { f, err := OpenFile(filepath.Join("test", "Book1.xlsx")) if !assert.NoError(t, err) { diff --git a/styles.go b/styles.go index 2a99a4dc..d925ea9a 100644 --- a/styles.go +++ b/styles.go @@ -2603,7 +2603,8 @@ 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. +// area, this 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: //