Skip to content

Commit c118026

Browse files
authored
Merge pull request #10 from fahadadeel/main
Add worksheet tab color functionality
2 parents 4dfd3bc + 3464836 commit c118026

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed

Excel/WorksheetColorExtensions.cs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
using System;
2+
using DocumentFormat.OpenXml;
3+
using DocumentFormat.OpenXml.Spreadsheet;
4+
5+
namespace Openize.Cells
6+
{
7+
/// <summary>
8+
/// Provides extension methods for managing worksheet tab colors in Excel workbooks.
9+
/// </summary>
10+
public static class WorksheetColorExtensions
11+
{
12+
/// <summary>
13+
/// Sets the tab color for a worksheet using RGB values.
14+
/// </summary>
15+
/// <param name="worksheet">The worksheet to set the tab color for.</param>
16+
/// <param name="red">The red component (0-255).</param>
17+
/// <param name="green">The green component (0-255).</param>
18+
/// <param name="blue">The blue component (0-255).</param>
19+
/// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
20+
/// <exception cref="ArgumentOutOfRangeException">Thrown when color components are outside the valid range.</exception>
21+
public static void SetTabColor(this Worksheet worksheet, byte red, byte green, byte blue)
22+
{
23+
if (worksheet == null)
24+
throw new ArgumentNullException(nameof(worksheet));
25+
26+
string hexColor = $"{red:X2}{green:X2}{blue:X2}";
27+
SetTabColorByHex(worksheet, hexColor);
28+
}
29+
30+
/// <summary>
31+
/// Sets the tab color for a worksheet using an HTML-style hex color code.
32+
/// </summary>
33+
/// <param name="worksheet">The worksheet to set the tab color for.</param>
34+
/// <param name="hexColor">The hex color code (e.g., "FF0000" for red).</param>
35+
/// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
36+
/// <exception cref="ArgumentException">Thrown when hexColor is null, empty, or invalid.</exception>
37+
public static void SetTabColorByHex(this Worksheet worksheet, string hexColor)
38+
{
39+
if (worksheet == null)
40+
throw new ArgumentNullException(nameof(worksheet));
41+
42+
if (string.IsNullOrEmpty(hexColor))
43+
throw new ArgumentException("Hex color cannot be null or empty.", nameof(hexColor));
44+
45+
// Strip # if present
46+
if (hexColor.StartsWith("#"))
47+
hexColor = hexColor.Substring(1);
48+
49+
// Validate hex color format
50+
if (!IsValidHexColor(hexColor))
51+
throw new ArgumentException("Invalid hex color format. Expected format: RRGGBB", nameof(hexColor));
52+
53+
// Get access to the internal OpenXML worksheet
54+
var openXmlWorksheetPart = GetOpenXmlWorksheetPart(worksheet);
55+
if (openXmlWorksheetPart == null)
56+
return;
57+
58+
var openXmlWorksheet = openXmlWorksheetPart.Worksheet;
59+
60+
// Get or create the SheetProperties element
61+
SheetProperties sheetProperties = openXmlWorksheet.GetFirstChild<SheetProperties>();
62+
if (sheetProperties == null)
63+
{
64+
sheetProperties = new SheetProperties();
65+
openXmlWorksheet.InsertAt(sheetProperties, 0);
66+
}
67+
68+
// Get or create the TabColor element
69+
TabColor tabColor = sheetProperties.GetFirstChild<TabColor>();
70+
if (tabColor == null)
71+
{
72+
tabColor = new TabColor();
73+
sheetProperties.AppendChild(tabColor);
74+
}
75+
76+
// Set the RGB value
77+
tabColor.Rgb = hexColor;
78+
79+
// Save the changes
80+
openXmlWorksheet.Save();
81+
}
82+
83+
/// <summary>
84+
/// Gets the tab color of a worksheet as RGB values.
85+
/// </summary>
86+
/// <param name="worksheet">The worksheet to get the tab color from.</param>
87+
/// <param name="red">Output parameter to receive the red component.</param>
88+
/// <param name="green">Output parameter to receive the green component.</param>
89+
/// <param name="blue">Output parameter to receive the blue component.</param>
90+
/// <returns>True if a tab color is set; otherwise, false.</returns>
91+
/// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
92+
public static bool GetTabColor(this Worksheet worksheet, out byte red, out byte green, out byte blue)
93+
{
94+
red = 0;
95+
green = 0;
96+
blue = 0;
97+
98+
if (worksheet == null)
99+
throw new ArgumentNullException(nameof(worksheet));
100+
101+
string hexColor = GetTabColorAsHex(worksheet);
102+
if (string.IsNullOrEmpty(hexColor))
103+
return false;
104+
105+
// Parse the hex color
106+
red = Convert.ToByte(hexColor.Substring(0, 2), 16);
107+
green = Convert.ToByte(hexColor.Substring(2, 2), 16);
108+
blue = Convert.ToByte(hexColor.Substring(4, 2), 16);
109+
110+
return true;
111+
}
112+
113+
/// <summary>
114+
/// Gets the tab color of a worksheet as a hex color code.
115+
/// </summary>
116+
/// <param name="worksheet">The worksheet to get the tab color from.</param>
117+
/// <returns>The tab color as a hex color code, or null if no tab color is set.</returns>
118+
/// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
119+
public static string GetTabColorAsHex(this Worksheet worksheet)
120+
{
121+
if (worksheet == null)
122+
throw new ArgumentNullException(nameof(worksheet));
123+
124+
// Get access to the internal OpenXML worksheet
125+
var openXmlWorksheetPart = GetOpenXmlWorksheetPart(worksheet);
126+
if (openXmlWorksheetPart == null)
127+
return null;
128+
129+
var openXmlWorksheet = openXmlWorksheetPart.Worksheet;
130+
131+
// Check if tab color is set
132+
SheetProperties sheetProperties = openXmlWorksheet.GetFirstChild<SheetProperties>();
133+
if (sheetProperties == null)
134+
return null;
135+
136+
TabColor tabColor = sheetProperties.GetFirstChild<TabColor>();
137+
if (tabColor == null || string.IsNullOrEmpty(tabColor.Rgb))
138+
return null;
139+
140+
return tabColor.Rgb;
141+
}
142+
143+
/// <summary>
144+
/// Removes the tab color from a worksheet.
145+
/// </summary>
146+
/// <param name="worksheet">The worksheet to remove the tab color from.</param>
147+
/// <exception cref="ArgumentNullException">Thrown when worksheet is null.</exception>
148+
public static void RemoveTabColor(this Worksheet worksheet)
149+
{
150+
if (worksheet == null)
151+
throw new ArgumentNullException(nameof(worksheet));
152+
153+
// Get access to the internal OpenXML worksheet
154+
var openXmlWorksheetPart = GetOpenXmlWorksheetPart(worksheet);
155+
if (openXmlWorksheetPart == null)
156+
return;
157+
158+
var openXmlWorksheet = openXmlWorksheetPart.Worksheet;
159+
160+
// Check if tab color is set
161+
SheetProperties sheetProperties = openXmlWorksheet.GetFirstChild<SheetProperties>();
162+
if (sheetProperties == null)
163+
return;
164+
165+
TabColor tabColor = sheetProperties.GetFirstChild<TabColor>();
166+
if (tabColor != null)
167+
{
168+
tabColor.Remove();
169+
openXmlWorksheet.Save();
170+
}
171+
}
172+
173+
/// <summary>
174+
/// Validates a hex color code.
175+
/// </summary>
176+
/// <param name="hexColor">The hex color code to validate.</param>
177+
/// <returns>True if the hex color code is valid; otherwise, false.</returns>
178+
private static bool IsValidHexColor(string hexColor)
179+
{
180+
if (string.IsNullOrEmpty(hexColor))
181+
return false;
182+
183+
// Standard hex color format is either RRGGBB or AARRGGBB
184+
return System.Text.RegularExpressions.Regex.IsMatch(hexColor, "^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$");
185+
}
186+
187+
/// <summary>
188+
/// Gets the OpenXML worksheet part from a Worksheet object.
189+
/// </summary>
190+
/// <param name="worksheet">The worksheet to get the OpenXML part from.</param>
191+
/// <returns>The OpenXML worksheet part, or null if not available.</returns>
192+
private static DocumentFormat.OpenXml.Packaging.WorksheetPart GetOpenXmlWorksheetPart(Worksheet worksheet)
193+
{
194+
// Use reflection to access the _worksheetPart field from the Worksheet class
195+
var fieldInfo = worksheet.GetType().GetField("_worksheetPart", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
196+
if (fieldInfo == null)
197+
return null;
198+
199+
return fieldInfo.GetValue(worksheet) as DocumentFormat.OpenXml.Packaging.WorksheetPart;
200+
}
201+
}
202+
}

0 commit comments

Comments
 (0)