我在使用 NPOI 时遇到的问题 - Color 博客分类: C# .Net开源软件 NPOI
NPOI 版本信息:
Binary: 2.1.3.1
Source Code: https://github.com/tonyqus/npoi (2015-06-15)
本期问题:Color
1. Custom Color / Color Palette / Color List
> NPOI(HSSF)中,一般设置颜色都会赋一个 Int16 (表示颜色的索引)。
style1.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Blue.Index;
但是有时候需要的颜色并没有在 HSSFColor 中定义。这时候就需要设置自定义的颜色。
一般是先将自定义的颜色(RGB值)添加到 Workbook 的调色板(HSSFPalette)中。然后将该新颜色的 Index 赋给目标属性。(具体示例可参照 Github 上的官方示例代码)
<2015-11-17>
- 调色板(NPOI.HSSF.UserModel.HSSFPalette)的大小是56(最多只能放56种颜色);
- b. 从常见的 Excel 文件导入的 Workbook 中,调色板的56个坑位都已占满;
- c. NPOI 新建调色板时,默认会加入56种颜色;
所以一般往调色板添加颜色都会失败(没坑位了),只能把其中的一种颜色替换成所需的颜色。替换颜色会导致某些预定义颜色和其默认索引在调色板中表示的颜色不同。所以一般比较保守的设置颜色做法是:
- 用 RGB 值查找调色板中是否存在相应的颜色。如果存在该颜色,使用该颜色在调色板中的索引(完成);如果不存在,到 2。
- 用所需颜色替换调色板中某种颜色,然后使用该新颜色的索引。把那种颜色替换掉呢?如果有其它地方引用到了被替换的颜色,这个地方的颜色也会被改成新颜色。同理,后续的操作也可能会替换现在的新颜色。很麻烦啊,未来的事情是无法预料的,无解了。大家换到 xlsx 吧。
</2015-11-17>
public class HSSFPalette { //... public HSSFColor AddColor(byte red, byte green, byte blue); public void SetColorAtIndex(short index, byte red, byte green, byte blue); //... }
> XSSF 中一般可以直接实例化一个自定义的 XSSFColor,并将其赋给相应属性。
<2015-11-17>
由于 NPOI 不够完善,有时候在 XSSF 中不得不用 Color Index 来设置颜色(如:设置 Sheet Tab Color)。
这时候一般做法就是:
- 获取 StylesTable;(XSSFWorkbook.GetStylesSource())
- 获取 CT_Stylesheet;(StylesTable.GetCTStylesheet(); 该方法为 internal,需要用到反射)
- 获取颜色列表;(CT_Stylesheet.colors.indexedColors)
- 如果颜色列表中存在所需颜色,使用其相应的索引;如果不存在,则添加该颜色到列表中,使用该新颜色在列表中的索引。
</2015-11-17>
2. Colors by Name (System.Drawing.Color vs NPOI.SS.UserModel.IndexedColors)
NPOI.SS.UserModel.IndexedColors 内部其实就是 HSSFColor。
System.Drawing.Color 和 NPOI.SS.UserModel.IndexedColors 内部都定义了一些具体的颜色(Red,Green,Blue等)。
但是有部分颜色名称相同,RGB值却不同。
如:LightGreen。
System.Drawing.Color 中 LightGreen 的 RGB 值是 (144,238,144)。
而 NPOI.SS.UserModel.IndexedColors 中的 LightGreen 的 RGB 值是 (204,255,204)。
System.Drawing.Color 中的预定义颜色遵循 CSS Color Module Level 3。