[.NET Core 6] NPOI 的 Cell 使用自訂前景色與背景色

POI 是產生 xlsx 檔是很方便的工具,網路上已經有很多範例和分享,最近練習想從前端傳送 Cell 的顏色到後端,來產生對應顏色格的檔案,搜集整理如下,以 .NET Core 6 實作,只筆記 model 中的邏輯。


最基本的前景色

下面示範藍色字,就是新增一個 font ,設定 font 的 color 為藍色。

  
  XSSFWorkbook wkBook = new XSSFWorkbook();
  ISheet sheet = wkBook.CreateSheet("測試");
  IRow row = sheet.CreateRow(0);
  row.CreateCell(0).SetCellValue("style0");
  row = sheet.CreateRow(1);

  ICellStyle style0 = wkBook.CreateCellStyle();
  IFont font0 = wkBook.CreateFont();            // 新增 IFont
  font0.Color = HSSFColor.Blue.Index;           // 設定 font 的 color 即前景色
  style0.SetFont(font0);                        // 使用 HSSFColor 的 Index 設定
  ICell cell0 = row.CreateCell(0);
  cell0.CellStyle = style0;
  cell0.SetCellValue("測試藍字");
  


有前景色和背景色

背景色的做法有點特別,雖然 ICellStyle 物件有 FillBackgroundColor 屬性,但是背景色其實是用 FillForegroundColor 搭配 FillPattern.SolidForeground 來填滿的。

  
  XSSFWorkbook wkBook = new XSSFWorkbook();
  ISheet sheet = wkBook.CreateSheet("測試");
  IRow row = sheet.CreateRow(0);
  row.CreateCell(1).SetCellValue("style1");
  row = sheet.CreateRow(1);
  
  ICellStyle style1 = wkBook.CreateCellStyle();
  IFont font1 = wkBook.CreateFont();                   // 新增 IFont
  font1.Color = HSSFColor.White.Index;                 // 設定 font 的 color 為白色
  style1.FillForegroundColor = HSSFColor.Violet.Index; // 設定紫色為前景
  style1.FillPattern = FillPattern.SolidForeground;    // 使用前景來填滿
  ICell cell1 = row.CreateCell(1);
  cell1.CellStyle = style1;
  cell1.SetCellValue("測試紫色背景");
  


使用 RGB 做前景與背景

以上兩個範例是使用 HSSFColor 取 Index,雖然顏色眾多,但難免有自己想自訂顏色的時候,這時要使用 byte[] 來設定給 XSSFColor 物件

  
  XSSFWorkbook wkBook = new XSSFWorkbook();
  ISheet sheet = wkBook.CreateSheet("測試");
  IRow row = sheet.CreateRow(0);
  row.CreateCell(2).SetCellValue("style2");
  row = sheet.CreateRow(1);

  XSSFCellStyle style2 = (XSSFCellStyle)wkBook.CreateCellStyle();  // 須使用 XSSFCellStyle 物件
  XSSFFont font2 = (XSSFFont)wkBook.CreateFont();
  font2.SetColor(new XSSFColor(new byte[] { 255, 255, 0 }));       // 使用 .SetColor 方法與 new XSSFColor 物件
  style2.SetFont(font2);
  style2.FillPattern = FillPattern.SolidForeground;                // 背景也一樣是設定 Foreground 來填滿
  style2.SetFillForegroundColor(new XSSFColor(new byte[] { 255, 0, 0 }));
  ICell cell2 = row.CreateCell(2);
  cell2.CellStyle = style2;
  cell2.SetCellValue("測試自訂RGB");
  


使用十六進位字串做前景背景

以上是有十進位數字的 RGB 值來做為 byte[] 給 XSSFColor 建構,如果前端有一個<input type="color" name="colorFg" /> 其值 .value 為 '#794c83',希望以此顏色來做為前景,就要截取字串並轉為 byte。

  
  XSSFWorkbook wkBook = new XSSFWorkbook();
  ISheet sheet = wkBook.CreateSheet("測試");
  IRow row = sheet.CreateRow(0);
  row.CreateCell(3).SetCellValue("style3");
  row = sheet.CreateRow(1);

  string colorFg = "#794c83", colorBg = "#fedfe1";   // 從前端送來的前景色 #794c83 和背景色 #fedfe1
  XSSFCellStyle style3 = (XSSFCellStyle)wkBook.CreateCellStyle();
  XSSFFont font3 = (XSSFFont)wkBook.CreateFont();
  font3.SetColor(new XSSFColor(new byte[] { 
      Convert.ToByte(colorFg.Substring(1, 2), 16),   // 使用 Convert.ToByte() 搭配 16 的 base
      Convert.ToByte(colorFg.Substring(3, 2), 16),   // 分別將字串 "79"、"4c"、"83"
      Convert.ToByte(colorFg.Substring(5, 2), 16)    // 轉為 121、76、131
  }));
  style3.SetFont(font3);
  style3.FillPattern = FillPattern.SolidForeground;
  style3.SetFillForegroundColor(new XSSFColor(new byte[] { 
      Convert.ToByte(colorBg.Substring(1, 2), 16), 
      Convert.ToByte(colorBg.Substring(3, 2), 16), 
      Convert.ToByte(colorBg.Substring(5, 2), 16) 
  }));
  ICell cell3 = row.CreateCell(3);
  cell3.CellStyle = style3;
  cell3.SetCellValue("測試十六進位RGB");
  

以上程式碼合併,請參考以下。


  public void ExportXLSX()
  {
    FileName = "wwwroot/test.xlsx";
    try
    {
      using(FileStream fs = new FileStream(FileName, FileMode.Create, FileAccess.Write))
      {
        XSSFWorkbook wkBook = new XSSFWorkbook();
        ISheet sheet = wkBook.CreateSheet("測試工作表");
        IRow row = sheet.CreateRow(0);
        row.CreateCell(0).SetCellValue("style0");
        row.CreateCell(1).SetCellValue("style1");
        row.CreateCell(2).SetCellValue("style2");
        row.CreateCell(3).SetCellValue("style3");

        row = sheet.CreateRow(1);
        ICellStyle style0 = wkBook.CreateCellStyle();
        IFont font0 = (XSSFFont)wkBook.CreateFont();
        font0.Color = HSSFColor.Blue.Index;
        style0.SetFont(font0);
        ICell cell0 = row.CreateCell(0);
        cell0.CellStyle = style0;
        cell0.SetCellValue("測試藍字");

        ICellStyle style1 = wkBook.CreateCellStyle();
        IFont font1 = wkBook.CreateFont();
        font1.Color = HSSFColor.White.Index;
        style1.FillForegroundColor = HSSFColor.Violet.Index;
        style1.FillPattern = FillPattern.SolidForeground;
        ICell cell1 = row.CreateCell(1);
        cell1.CellStyle = style1;
        cell1.SetCellValue("測試紫色背景");

        XSSFCellStyle style2 = (XSSFCellStyle)wkBook.CreateCellStyle();
        XSSFFont font2 = (XSSFFont)wkBook.CreateFont();
        font2.SetColor(new XSSFColor(new byte[] { 255, 255, 0 }));
        style2.SetFont(font2);
        style2.FillPattern = FillPattern.SolidForeground;
        style2.SetFillForegroundColor(new XSSFColor(new byte[] { 255, 0, 0 }));
        ICell cell2 = row.CreateCell(2);
        cell2.CellStyle = style2;
        cell2.SetCellValue("測試自訂RGB");

        string colorFg = "#794c83", colorBg = "#fedfe1";
        XSSFCellStyle style3 = (XSSFCellStyle)wkBook.CreateCellStyle();
        XSSFFont font3 = (XSSFFont)wkBook.CreateFont();
        font3.SetColor(new XSSFColor(new byte[] { 
          Convert.ToByte(colorFg.Substring(1, 2), 16), 
          Convert.ToByte(colorFg.Substring(3, 2), 16), 
          Convert.ToByte(colorFg.Substring(5, 2), 16) }
        ));
        style3.SetFont(font3);
        style3.FillPattern = FillPattern.SolidForeground;
        style3.SetFillForegroundColor(new XSSFColor(new byte[] { 
          Convert.ToByte(colorBg.Substring(1, 2), 16), 
          Convert.ToByte(colorBg.Substring(3, 2), 16), 
          Convert.ToByte(colorBg.Substring(5, 2), 16) }
        ));
        ICell cell3 = row.CreateCell(3);
        cell3.CellStyle = style3;
        cell3.SetCellValue("測試十六進位RGB");

        wkBook.Write(fs, false);
      }
    }
    catch (Exception)
    {
      throw;
    }
  }
  

留言