Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

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

50%
+0 −0
Q&A How to set the cell color to a user defined value using NPOI from F#?

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...

posted 10mo ago by toraritte‭  ·  edited 10mo ago by toraritte‭

Answer
#2: Post edited by user avatar toraritte‭ · 2024-01-11T16:07:37Z (10 months ago)
  • 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 by user avatar toraritte‭ · 2024-01-11T16:04:57Z (10 months ago)
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).