据我所知(至少从 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
(例如,1、2、3、)。
我错过了一些明显的东西还是这确实不可能?
在此上下文中,术语“前景”和“背景”的含义也具有误导性,但这是从 Apache POI 继承的,并且在线上有详细记录(例如,here 和 here)。
edit:找到了另外两个 C# 解决方案(this 和 this),通过将
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
我没有注意到单元格的
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