經常在NPOI群里聊天時發現有人在問NPOI設置單元格背景顏色的問題,而Tony Qu大神的博客里沒有相關教程,剛好最近在做項目時研究了一下這一塊,在這里總結一下。
在NPOI中默認的顏色類是HSSFColor,如果要使用NPOI中的顏色就必須想辦法轉化為HSSFColor。分析了一下原代碼,HSSFColor內置了幾十種顏色,都是用內部類繼承HSSFColor這個類來定義的。那么除非去修改源代碼,否則是不能以這種方式來使用自定義顏色的。
除了繼承的方式外,還有另外一種方式使用HSSFColor。答案就是從調色板中獲取顏色。從調色板中獲取顏色的主要步驟是:1、將顏色的RGB值添加進調色板HSSFPalette中。2、調用HSSFPalette中FindColor方法獲取HSSFColor實例。3、在需要使用顏色的地方使用HSSFColor的GetIndex方法獲取index值。以下是實現相關源代碼:
int StartColIndex = 0;
int rowIndex = 0;
int colIndex = StartColIndex;
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
ISheet sheet = hssfWorkbook.CreateSheet("Sheet1");
IRow row;
ICell cell;
HSSFPalette palette = hssfWorkbook.GetCustomPalette();
List<Color> colorList = new List<Color>();
Random random = new Random(Guid.NewGuid().GetHashCode());
for (int i = 0; i < random.Next(100, 200); i++)
{
colorList.Add(Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)));
}
short FIRST_COLOR_INDEX = (short)0x8;
for (int i = 0; i < colorList.Count; i++)
{
if ((short)(FIRST_COLOR_INDEX + i) > (short)0x40)
{
break;
}
//index的取值范圍 0x8 - 0x40
palette.SetColorAtIndex((short)(FIRST_COLOR_INDEX + i), colorList[i].R, colorList[i].G, colorList[i].B);
}
for (int i = 0; i < colorList.Count; i++)
{
if (i >= (short)(0x40 - 0x8))
{
break;
}
colIndex = StartColIndex;
row = sheet.CreateRow(rowIndex);
cell = row.CreateCell(colIndex);
ICellStyle colorStyle = hssfWorkbook.CreateCellStyle();
colorStyle.FillPattern = FillPatternType.SOLID_FOREGROUND;
var v1 = palette.FindColor(colorList[i].R, colorList[i].G, colorList[i].B);
if (v1 == null)
{
throw new Exception("Color is not in Palette");
}
colorStyle.FillForegroundColor = v1.GetIndex();
cell.CellStyle = colorStyle;
colIndex++;
rowIndex++;
}
string fileName = @"test.xls";
using (FileStream file = new FileStream(fileName, FileMode.Create))
{
hssfWorkbook.Write(file);
file.Close();
}
int rowIndex = 0;
int colIndex = StartColIndex;
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
ISheet sheet = hssfWorkbook.CreateSheet("Sheet1");
IRow row;
ICell cell;
HSSFPalette palette = hssfWorkbook.GetCustomPalette();
List<Color> colorList = new List<Color>();
Random random = new Random(Guid.NewGuid().GetHashCode());
for (int i = 0; i < random.Next(100, 200); i++)
{
colorList.Add(Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)));
}
short FIRST_COLOR_INDEX = (short)0x8;
for (int i = 0; i < colorList.Count; i++)
{
if ((short)(FIRST_COLOR_INDEX + i) > (short)0x40)
{
break;
}
//index的取值范圍 0x8 - 0x40
palette.SetColorAtIndex((short)(FIRST_COLOR_INDEX + i), colorList[i].R, colorList[i].G, colorList[i].B);
}
for (int i = 0; i < colorList.Count; i++)
{
if (i >= (short)(0x40 - 0x8))
{
break;
}
colIndex = StartColIndex;
row = sheet.CreateRow(rowIndex);
cell = row.CreateCell(colIndex);
ICellStyle colorStyle = hssfWorkbook.CreateCellStyle();
colorStyle.FillPattern = FillPatternType.SOLID_FOREGROUND;
var v1 = palette.FindColor(colorList[i].R, colorList[i].G, colorList[i].B);
if (v1 == null)
{
throw new Exception("Color is not in Palette");
}
colorStyle.FillForegroundColor = v1.GetIndex();
cell.CellStyle = colorStyle;
colIndex++;
rowIndex++;
}
string fileName = @"test.xls";
using (FileStream file = new FileStream(fileName, FileMode.Create))
{
hssfWorkbook.Write(file);
file.Close();
}
需要注意的是,調色板的取值范圍是0x8 - 0x40,即8-64,也就是說只支持56種顏色,56種顏色在項目中也差不多夠用了。還有就是所調用的顏色一定要存在於調色板中否則在調用FindColor后會返回null,再調用HSSFColor的GetIndex方法時會報錯。
最后發一張完整示例項目生成結果的截圖, 各位同學如果感興趣可以將示例下載下來看一下 :-)