如何使用 F# 中的 NPOI 将单元格颜色设置为用户定义的值?

问题描述 投票:0回答:1

据我所知(至少从 F# 来看),单元格只能使用预定义的

NPOI.SS.UserModel.IndexedColors
进行着色。从可用的方法/属性中,

val it: ICellStyle =
  NPOI.XSSF.UserModel.XSSFCellStyle
    { ...
     FillBackgroundColor = -494s;
     FillBackgroundColorColor = NPOI.XSSF.UserModel.XSSFColor;
     FillBackgroundXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     FillForegroundColor = 64s;
     FillForegroundColorColor = null;
     FillForegroundXSSFColor = null;
     FillPattern = NoFill;
    ...

只有

FillBackgroundColor
FillForegroundColor
FillPattern
可以设置为
int16
值,该值对应于
IndexedColors
值,其余模式是不可变的。我可以创建自定义

new NPOI.XSSF.UserModel.XSSFColor([|255uy; 192uy; 150uy|])

颜色,但我根本不知道如何将其分配给现有的单元格样式或全新的单元格样式。我能找到的所有文章也只使用

IndexedColors
(例如,123、)。

我错过了一些明显的东西还是这确实不可能?

在此上下文中,术语“前景”和“背景”的含义也具有误导性,但这是从 Apache POI 继承的,并且在线上有详细记录(例如,herehere)。


edit:找到了另外两个 C# 解决方案(thisthis),通过将

FillBackgroundColor
设置为自定义
XSSFColor
来实现显而易见的效果,但是,我再次不知道如何在 F# 中执行此操作:

> cs;;
val it: ICellStyle =
  NPOI.XSSF.UserModel.XSSFCellStyle
    {Alignment = General;
     BorderBottom = Thin;
     BorderDiagonal = None;
     BorderDiagonalColor = 8s;
     BorderDiagonalLineStyle = None;
     BorderLeft = Thin;
     BorderRight = Thin;
     BorderTop = Thin;
     BottomBorderColor = 64s;
     BottomBorderXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     DataFormat = 0s;
     DiagonalBorderXSSFColor = null;
     FillBackgroundColor = -494s;
     FillBackgroundColorColor = NPOI.XSSF.UserModel.XSSFColor;
     FillBackgroundXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     FillForegroundColor = 0s;
     FillForegroundColorColor = NPOI.XSSF.UserModel.XSSFColor;
     FillForegroundXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     FillPattern = NoFill;
     FontIndex = 3s;
     Indention = 0s;
     Index = 43s;
     IsHidden = false;
     IsLocked = false;
     LeftBorderColor = 64s;
     LeftBorderXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     RightBorderColor = 64s;
     RightBorderXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     Rotation = 0s;
     ShrinkToFit = false;
     TopBorderColor = 64s;
     TopBorderXSSFColor = NPOI.XSSF.UserModel.XSSFColor;
     VerticalAlignment = Bottom;
     WrapText = false;}

> c;;
val it: XSSFColor =
  NPOI.XSSF.UserModel.XSSFColor {ARGB = [|255uy; 255uy; 192uy; 150uy|];
                                 ARGBHex = "FFFFC096";
                                 HasAlpha = false;
                                 HasTint = false;
                                 Index = 0s;
                                 Indexed = 0s;
                                 IsAuto = false;
                                 IsIndexed = false;
                                 IsRGB = true;
                                 IsThemed = false;
                                 RGB = [|255uy; 192uy; 150uy|];
                                 RGBWithTint = [|255uy; 192uy; 150uy|];
                                 Theme = 0;
                                 Tint = 0.0;}

> cs.FillBackgroundColor;;   
val it: int16 = -494s

> cs.FillBackgroundColor <- c;;

  cs.FillBackgroundColor <- c;;
  --------------------------^

/Users/toraritte/dev/clones/dotNET/slate-excel-reports/stdin(332,27): error FS0001: This expression was expected to have type
    'int16'    
but here has type
    'XSSFColor'    

> cs.FillBackgroundColorColor;;
val it: IColor = NPOI.XSSF.UserModel.XSSFColor {ARGB = null;
                                                ARGBHex = null;
                                                HasAlpha = false;
                                                HasTint = false;
                                                Index = -494s;
                                                Indexed = -494s;
                                                IsAuto = false;
                                                IsIndexed = true;
                                                IsRGB = false;
                                                IsThemed = false;
                                                RGB = null;
                                                RGBWithTint = null;
                                                Theme = 0;
                                                Tint = 0.0;}

> cs.FillBackgroundColorColor <- c;;

  cs.FillBackgroundColorColor <- c;;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^

/Users/toraritte/dev/clones/dotNET/slate-excel-reports/stdin(334,1): error FS0810: Property 'FillBackgroundColorColor' cannot be set
excel f# npoi
1个回答
0
投票

我没有注意到单元格的

CellStyle
属性返回通用
ICellStyle
,必须将其强制转换为
NPOI.XSSF.UserModel.XSSFCellStyle
才能访问
FillBackgroundXSSFColor
FillForegroundXSSFColor
属性。

此外,这里总结了哪个属性的作用,引用了这个答案:

正如我的链接答案中所述:单元格内部使用图案填充。填充背景颜色是图案后面的颜色。填充前景颜色是图案的颜色。要使用纯色填充单元格,您需要使用填充前景颜色

CellStyle.setFillForegroundColor
和纯色图案
FillPatternType.SOLID_FOREGROUND

就我而言,我需要

NPOI.SS.UserModel.FillPattern
FillForegroundXSSFColor
。完整代码:

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

使用 RGB 颜色调用:

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

使用十六进制颜色字符串调用:

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");;

注意:

setCellColor
将输入单元格的样式替换为新样式,因此如果需要,必须重新创建以前的样式选项。 当我修改
setCellColor
以修改单元格自己的样式对象而不是替换它时,结果是整个工作表被绘制为该特定单元格今后使用的颜色。不知道我哪里搞砸了,但要小心。

更新 请参阅如何使用 F# 中的 NPOI 将单元格的颜色更改为用户定义的值,同时保持其现有样式?

中的解决方案
© www.soinside.com 2019 - 2024. All rights reserved.