Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
I failed to notice that a cell's CellStyle property returns the generic ICellStyle, which has to be cast down to NPOI.XSSF.UserModel.XSSFCellStyle in order to gain access to the FillBackgroundXSSFC...
Answer
#2: Post edited
- I failed to notice that a cell's `CellStyle` property returns the generic `ICellStyle`, which has to be cast down to `NPOI.XSSF.UserModel.XSSFCellStyle` in order to gain access to the `FillBackgroundXSSFColor` and `FillForegroundXSSFColor` properties.
- Also, here's a summary of which property does what, quoting from [this answer]():
- > As said in my linked answer: Cell interior uses pattern fills. The fill background color is the color **behind** the pattern.The fill **foreground** color is the color of the pattern. To fill the cell using a plain color, you need using fill **foreground** color `CellStyle.setFillForegroundColor` and solid pattern `FillPatternType.SOLID_FOREGROUND`.
- In my case, I need `NPOI.SS.UserModel.FillPattern` and `FillForegroundXSSFColor` then. The full code:
- ```
- let setCellColor (cell: ICell) (rgb: byte array) =
- let xssfCell = cell :?> NPOI.XSSF.UserModel.XSSFCell
- let newCellStyle: NPOI.SS.UserModel.ICellStyle = xssfCell.Sheet.Workbook.CreateCellStyle()
- match xssfCell.CellStyle with
- | :? NPOI.XSSF.UserModel.XSSFCellStyle as xssfCellStyle ->
- let color = new NPOI.XSSF.UserModel.XSSFColor(rgb)
- xssfCellStyle.FillForegroundXSSFColor <- color
- xssfCellStyle.FillPattern <- NPOI.SS.UserModel.FillPattern.SolidForeground
- | _ -> failwith "'newCellStyle' cannot be cast to XSSFCellStyle"
- xssfCell.CellStyle <- newCellStyle
- ```
- To call with RGB colors:
- ```
- let getCell (workbook: NPOI.XSSF.UserModel.XSSFWorkbook) (sheetNumber: int) (address: string) =
- let sheet: ISheet = workbook.GetSheetAt(sheetNumber)
- let cellAddress = new CellAddress (address)
- getCellByAddress sheet cellAddress
- let rgb: byte array = [|255uy; 192uy; 150uy|]
- setCellColor (getCell o 3 "a7") rgb;;
- ```
- To call with hex color string:
- ```
- let hexStringToRGB (hexString: string) =
- let isHexColor (color: string) =
- "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
- |> fun regexPattern -> new System.Text.RegularExpressions.Regex(regexPattern)
- |> fun regex -> regex.IsMatch(color)
- match (isHexColor hexString) with
- | false ->
- failwith "Invalid hex color string."
- | true ->
- let hexString = hexString.TrimStart('#')
- let r = System.Convert.ToByte(hexString.Substring(0, 2), 16)
- let g = System.Convert.ToByte(hexString.Substring(2, 2), 16)
- let b = System.Convert.ToByte(hexString.Substring(4, 2), 16)
- [|r; g; b|]
- setCellColor (getCell o 3 "a7") (hexStringToRGB "#ffc096");;
- ```
- > NOTE: `setCellColor` replaces the input cell's style with a new one, so one has to take care of re-creating the previous style options if they are needed.
- > When I modified `setCellColor` to modify the cell's own style object instead of replacing it, the result was that the entire worksheet got painted to the color used from that specific cell going forward. Not sure where I screwed up, but beware.
- >
> **update** See the solution in [How to change the color of a cell to a user defined value while keeping its existing style using NPOI from F#?](https://stackoverflow.com/questions/77705384/how-to-change-the-color-of-a-cell-to-a-user-defined-value-while-keeping-its-exis).
- I failed to notice that a cell's `CellStyle` property returns the generic `ICellStyle`, which has to be cast down to `NPOI.XSSF.UserModel.XSSFCellStyle` in order to gain access to the `FillBackgroundXSSFColor` and `FillForegroundXSSFColor` properties.
- Also, here's a summary of which property does what, quoting from [this answer]():
- > As said in my linked answer: Cell interior uses pattern fills. The fill background color is the color **behind** the pattern.The fill **foreground** color is the color of the pattern. To fill the cell using a plain color, you need using fill **foreground** color `CellStyle.setFillForegroundColor` and solid pattern `FillPatternType.SOLID_FOREGROUND`.
- In my case, I need `NPOI.SS.UserModel.FillPattern` and `FillForegroundXSSFColor` then. The full code:
- ```
- let setCellColor (cell: ICell) (rgb: byte array) =
- let xssfCell = cell :?> NPOI.XSSF.UserModel.XSSFCell
- let newCellStyle: NPOI.SS.UserModel.ICellStyle = xssfCell.Sheet.Workbook.CreateCellStyle()
- match xssfCell.CellStyle with
- | :? NPOI.XSSF.UserModel.XSSFCellStyle as xssfCellStyle ->
- let color = new NPOI.XSSF.UserModel.XSSFColor(rgb)
- xssfCellStyle.FillForegroundXSSFColor <- color
- xssfCellStyle.FillPattern <- NPOI.SS.UserModel.FillPattern.SolidForeground
- | _ -> failwith "'newCellStyle' cannot be cast to XSSFCellStyle"
- xssfCell.CellStyle <- newCellStyle
- ```
- To call with RGB colors:
- ```
- let getCell (workbook: NPOI.XSSF.UserModel.XSSFWorkbook) (sheetNumber: int) (address: string) =
- let sheet: ISheet = workbook.GetSheetAt(sheetNumber)
- let cellAddress = new CellAddress (address)
- getCellByAddress sheet cellAddress
- let rgb: byte array = [|255uy; 192uy; 150uy|]
- setCellColor (getCell o 3 "a7") rgb;;
- ```
- To call with hex color string:
- ```
- let hexStringToRGB (hexString: string) =
- let isHexColor (color: string) =
- "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
- |> fun regexPattern -> new System.Text.RegularExpressions.Regex(regexPattern)
- |> fun regex -> regex.IsMatch(color)
- match (isHexColor hexString) with
- | false ->
- failwith "Invalid hex color string."
- | true ->
- let hexString = hexString.TrimStart('#')
- let r = System.Convert.ToByte(hexString.Substring(0, 2), 16)
- let g = System.Convert.ToByte(hexString.Substring(2, 2), 16)
- let b = System.Convert.ToByte(hexString.Substring(4, 2), 16)
- [|r; g; b|]
- setCellColor (getCell o 3 "a7") (hexStringToRGB "#ffc096");;
- ```
- > NOTE: `setCellColor` replaces the input cell's style with a new one, so one has to take care of re-creating the previous style options if they are needed.
- > When I modified `setCellColor` to modify the cell's own style object instead of replacing it, the result was that the entire worksheet got painted to the color used from that specific cell going forward. Not sure where I screwed up, but beware.
- >
- > **update** See the solution in [How to change the color of a cell to a user defined value while keeping its existing style using NPOI from F#?](https://software.codidact.com/posts/290557).
#1: Initial revision
I failed to notice that a cell's `CellStyle` property returns the generic `ICellStyle`, which has to be cast down to `NPOI.XSSF.UserModel.XSSFCellStyle` in order to gain access to the `FillBackgroundXSSFColor` and `FillForegroundXSSFColor` properties. Also, here's a summary of which property does what, quoting from [this answer](): > As said in my linked answer: Cell interior uses pattern fills. The fill background color is the color **behind** the pattern.The fill **foreground** color is the color of the pattern. To fill the cell using a plain color, you need using fill **foreground** color `CellStyle.setFillForegroundColor` and solid pattern `FillPatternType.SOLID_FOREGROUND`. In my case, I need `NPOI.SS.UserModel.FillPattern` and `FillForegroundXSSFColor` then. The full code: ``` let setCellColor (cell: ICell) (rgb: byte array) = let xssfCell = cell :?> NPOI.XSSF.UserModel.XSSFCell let newCellStyle: NPOI.SS.UserModel.ICellStyle = xssfCell.Sheet.Workbook.CreateCellStyle() match xssfCell.CellStyle with | :? NPOI.XSSF.UserModel.XSSFCellStyle as xssfCellStyle -> let color = new NPOI.XSSF.UserModel.XSSFColor(rgb) xssfCellStyle.FillForegroundXSSFColor <- color xssfCellStyle.FillPattern <- NPOI.SS.UserModel.FillPattern.SolidForeground | _ -> failwith "'newCellStyle' cannot be cast to XSSFCellStyle" xssfCell.CellStyle <- newCellStyle ``` To call with RGB colors: ``` let getCell (workbook: NPOI.XSSF.UserModel.XSSFWorkbook) (sheetNumber: int) (address: string) = let sheet: ISheet = workbook.GetSheetAt(sheetNumber) let cellAddress = new CellAddress (address) getCellByAddress sheet cellAddress let rgb: byte array = [|255uy; 192uy; 150uy|] setCellColor (getCell o 3 "a7") rgb;; ``` To call with hex color string: ``` let hexStringToRGB (hexString: string) = let isHexColor (color: string) = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" |> fun regexPattern -> new System.Text.RegularExpressions.Regex(regexPattern) |> fun regex -> regex.IsMatch(color) match (isHexColor hexString) with | false -> failwith "Invalid hex color string." | true -> let hexString = hexString.TrimStart('#') let r = System.Convert.ToByte(hexString.Substring(0, 2), 16) let g = System.Convert.ToByte(hexString.Substring(2, 2), 16) let b = System.Convert.ToByte(hexString.Substring(4, 2), 16) [|r; g; b|] setCellColor (getCell o 3 "a7") (hexStringToRGB "#ffc096");; ``` > NOTE: `setCellColor` replaces the input cell's style with a new one, so one has to take care of re-creating the previous style options if they are needed. > When I modified `setCellColor` to modify the cell's own style object instead of replacing it, the result was that the entire worksheet got painted to the color used from that specific cell going forward. Not sure where I screwed up, but beware. > > **update** See the solution in [How to change the color of a cell to a user defined value while keeping its existing style using NPOI from F#?](https://stackoverflow.com/questions/77705384/how-to-change-the-color-of-a-cell-to-a-user-defined-value-while-keeping-its-exis).