以前の記事「セルの書式設定 - その2」を踏まえて、セルの背景色を操作します。
C:\Users\Public\Documents\openxmlsdk15.xlsx
セルA1からJ1にかけて、背景色をべた塗り(Solid)するコードを以下に示します。
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace OpenXMLSDK_Sample8 {
class Program {
static void Main(string[] args) {
const string FILE = @"C:\Users\Public\Documents\openxmlsdk15.xlsx";
const string SHEET_NAME = "Sheet1";
using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(FILE, true)) {
WorkbookPart bookPart = excelDoc.WorkbookPart;
Dictionary<string, string> colors = new Dictionary<string, string>();
colors.Add("A1", "FFC00000");
colors.Add("B1", "FFFF0000");
colors.Add("C1", "FFFFC000");
colors.Add("D1", "FFFFFF00");
colors.Add("E1", "FF92D050");
colors.Add("F1", "FF00B050");
colors.Add("G1", "FF00B0F0");
colors.Add("H1", "FF0070C0");
colors.Add("I1", "FF002060");
colors.Add("J1", "FF7030A0");
foreach (KeyValuePair<string, string> cell_color in colors) {
SetCellBackgroundColor(bookPart, SHEET_NAME, cell_color.Key, new ForegroundColor() { Rgb = cell_color.Value });
}
}
//ファイルを開く
System.Diagnostics.Process.Start(FILE);
}
private static void SetCellBackgroundColor(WorkbookPart bookPart, string sheet_name, string cell_address, ForegroundColor bg_color) {
int sheet_index = GetWorksheetIndex(bookPart, sheet_name);
WorksheetPart sheet_part = GetWorksheetPart(bookPart, sheet_index);
Cell target_cell = GetCell(sheet_part, cell_address);
//指定された色と同じパターンのFillを探す
Fill same_bg_fill = bookPart.WorkbookStylesPart.Stylesheet.Fills.Elements<Fill>()
.FirstOrDefault(f =>
f.PatternFill != null && f.PatternFill.ForegroundColor != null &&
f.PatternFill.ForegroundColor.Rgb != null &&
f.PatternFill.PatternType.Value == PatternValues.Solid &&
f.PatternFill.ForegroundColor.Rgb.Value == bg_color.Rgb.Value);
int same_bg_index; //FillのID
//見つからない場合は新たに作成
if (same_bg_fill == null) {
same_bg_fill = new Fill() { PatternFill = new PatternFill() { ForegroundColor = bg_color } };
same_bg_fill.PatternFill.PatternType = new EnumValue<PatternValues>(PatternValues.Solid);
bookPart.WorkbookStylesPart.Stylesheet.Fills.AppendChild<Fill>(same_bg_fill);
same_bg_index = bookPart.WorkbookStylesPart.Stylesheet.Fills.Count() - 1;
//Count属性の更新
bookPart.WorkbookStylesPart.Stylesheet.Fills.Count++;
}else {
same_bg_index = bookPart.WorkbookStylesPart.Stylesheet.Fills.ToList().IndexOf(same_bg_fill);
}
var cell_format_enumerable = bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Elements<CellFormat>();
CellFormat target_cell_format = null;
if(target_cell.StyleIndex != null) {
//背景色をセットするセルに現在セットされているCellFormatを取得
target_cell_format = cell_format_enumerable.ElementAt(Convert.ToInt32(target_cell.StyleIndex.Value));
} else {
target_cell_format = new CellFormat();
target_cell_format.FillId = new UInt32Value((uint)same_bg_index);
target_cell_format.ApplyFill = true;
}
//同じ属性・ChildNodeをもち、かつ指定されたFillIDと同じ設定をもつCellFormatを探す
CellFormat format_to = cell_format_enumerable.FirstOrDefault(
r => r.GetAttributes().Where(f => f.LocalName != "fillId").SequenceEqual(target_cell_format.GetAttributes()
.Where(f => f.LocalName != "fillId")) && r.FillId != null && r.FillId.Value == (uint)same_bg_index && r.InnerXml == target_cell_format.InnerXml);
if (format_to != null) {
target_cell.StyleIndex = new UInt32Value((uint)(cell_format_enumerable.ToList().IndexOf(format_to)));
} else {
if (target_cell.StyleIndex != null) {
format_to = target_cell_format.CloneNode(true) as CellFormat;
if (format_to.FillId == null) {
format_to.FillId = new UInt32Value((uint)same_bg_index);
} else {
format_to.FillId.Value = (uint)same_bg_index;
}
} else {
format_to = target_cell_format;
}
bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Append(format_to);
target_cell.StyleIndex = new UInt32Value((uint)bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Count() - 1);
//Count属性を更新
bookPart.WorkbookStylesPart.Stylesheet.CellFormats.Count++;
}
}
// 以下省略...
}
}
「以下省略」とした部分に定義されているメソッドについては「セルの書式設定 - 表示形式」など、以前の記事をご覧ください。
31行目のSetCellBackgroundColorによってセルそれぞれの背景色をセットします。
SetCellBackgroundColorでは、41行目で指定されたセルを取得します。
45行目から50行目で、指定された背景色を持つFill要素を検索し、52行目から64行目で、そのindexを取得します。
71行目で指定されたセルのStyleIndexを手掛かりに現在セットされているCellFormatを取得して、
79行目から81行目で「FillID以外の属性がこのCellFormatと同じであり、かつFillIDに指定された背景色を持つFill要素のindexがセットされているようなCellFormat」を探します。
もしもそのようなCellFormatが見つかれば指定されたセルのStyleIndexを、見つかったCellFormatを指し示すように変更します(84行目)。
もしも見つからなかったら指定されたセルのCellFormatの複製を作成し、FillIDを指定された背景色を持つFill要素のindexに変更したうえでCellFormatsに追加して、
指定されたセルのStyleIndexがこのCellFormatを指すように変更します(96、97行目)。
このコードを実行すると、セルA1からJ1の背景色が以下のように変わります。
次回はセルの罫線を設定するコードについて紹介します。