EPPlus Excel Change cell color - c#

I am trying to set the color of a given cell with the color of another cell (that is already colored in the template.
But worksheet.Cells[row, col].Style.Fill.BackgroundColor doesn't seem to have a getproperty.
Is it possible to do that or do I have to find the exact hexdecimal code of the color on the internet ?
EDIT
using the code in the answer, I get that error (it is written in French but it translate with what I wrote in my first comment)

How about something like this?
//get color from this cell
var rgb = ws.Cells[1, 2].Style.Fill.BackgroundColor.Rgb;
//Convert to system.drawing.color
var color = System.Drawing.ColorTranslator.FromHtml("#" + rgb);
//set color in this cell
ws.Cells[1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells[1, 1].Style.Fill.BackgroundColor.SetColor(color);
Update:
Seems that if you select a color from system colors or the palette as your fill color it works fine. If you select one of the 'Theme colors' in the fill drop down .Rgb returns an empty string
//get style
var style = ws.Cells[400, 1].Style;
//If color from System colors or palette
if (!string.IsNullOrEmpty(style.Fill.BackgroundColor.Rgb))
{
//Convert to system.drawing.colow
var color = System.Drawing.ColorTranslator.FromHtml("#" + style.Fill.BackgroundColor.Rgb);
//set color in this cell
ws.Cells[1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells[1, 1].Style.Fill.BackgroundColor.SetColor(color);
}
else if (!string.IsNullOrEmpty(style.Fill.BackgroundColor.Theme))
{
//No idea how to get color from Theme
}
I'm not sure it's supported... according to EPPlus Faqs :
What is NOT supported by the library (these are the most obvious features)?
[...]
* Themes

For anyone getting here, since I had my round of fun with EPPlus and I wasn't satisfied with the answers above:
cell.Style.Fill.BackgroundColor.LookupColor()
returns #AARRGGBB color (I.E. red is #FFFF0000). The part you're interesdted in is probably the last 6 digits.

Related

How to Get the font color of an Excel Cell in c#

okay, so I'm trying to get the cell's font color as the program needs to do different things biased on the font color in the cell so I made a test file
and I tried to access it like so:
Range thrange = ws.UsedRange.Columns["A:A", Type.Missing].Rows;
foreach (Range r in thrange)
{
Style sy = r.Style;
Font font = sy.Font;
ColorFormat color = (ColorFormat)font.Color;
Console.WriteLine(" "+r.Value+" " + color.RGB);
}
I get
Can not convert type 'double' to 'Microsoft.Office.Interop.Excel.ColorFormat'
I saw people saying you set the color with a drawing object so I tried changing the last two lines to:
Color color =(System.Drawing.Color)font.Color;
Console.WriteLine(" "+r.Value+" " + color.ToArgb());
but that didn't work either
Can not convert type 'double' to 'System.Drawing.Color'
so I thought I'd see what this double is, then set the font to a known rgb value and work out how to convert the number I get back into that. but that didn't work either.
as while
Console.WriteLine(" "+r.Value+" "+r.style.font.color);
didn't throw an error it still didn't give me anything useful:
cyan 0
pink 0
blue 0
red 0
orange 0
purple 0
I thought maybe r.style.font.colorindex but that just gave me a 1 for everything instead of a 0
I was hopping for something like
blue 0000ff
red ff0000
I can't use a 3rd party libraries due to the rules set out by the project owner.
So how do I get the actual color value out?
Use the Font property of the Range not that of its Style. Then use the ColorTranslator class to convert the double value from Office to a .net Color.
foreach (Microsoft.Office.Interop.Excel.Range r in thrange)
{
// Get Color from Font from Range directly
int oleColor = Convert.ToInt32(r.Font.Color);
// Convert to C# Color type
System.Drawing.Color c = System.Drawing.ColorTranslator.FromOle(oleColor);
// Output
Console.WriteLine(r.Value + " " + c.ToString());
}

Cell.Style.Fill.BackgroundColor doesn't fill the proper color

I need to mark error cells in my output excel file in red. If in the original document those cells have no fill, all is fine, the color is red. But if the cell was already filled with Blue (or some kind of), in the output it become filled with pink, but not with red!
Here is my code:
var cell = worksheet.Cells[row, column];
cell.Reset();
cell.Value = string.Format("{0} Error:{1}", cell.Value, errortext);
cell.Style.Fill.BackgroundColor.SetColor(Color.Empty);
cell.Style.Fill.PatternType = ExcelFillStyle.Solid;
cell.Style.Fill.BackgroundColor.SetColor(Color.Red);
cell.Style.Fill.BackgroundColor.SetColor(Color.FromArgb(255, 0, 0));
This is how it should look:
This is how it is if the original fill was blue:
Will be very appreciated for any help.
cell.Style.Fill.BackgroundColor.Tint = 0;
that helped.

C# Excel Macro - how to check if cell value is negative and change its font colour?

I need to check if cells value is negative or positive, if negative - change its font colour to red. This is how I tried to do it, it doesn't work...
oRange2 = oWorksheet.get_Range("L14");
int value = oRange2.Value;
if(value < 0)
{
oRange2.Font.ColorIndex = 3;
}
Any suggestions?
A custom number format like [Red][<0]General;General will do this for you. If you don't like that particular shade of red then [color9][<0]General;General provides a darker palette.
oWorksheet.get_Range("L14").NumberFormat = "[Red][<0]General;General";
//... or for the whole column
oWorksheet.get_Range("L14").EntireColumn.NumberFormat = "[color9][<0]General;General";
// red with brackets
oWorksheet.get_Range("L14").EntireColumn.NumberFormat = "[Red][<0](General);General_)"
// red with minus sign
oWorksheet.get_Range("L14").EntireColumn.NumberFormat = "[Red][<0]-General;General"
I've used General as you did not supply any example data but you could easily substitute some sort of fixed or floating decimal number mask.

Excel Interop get width in pixels of text inside cell

I have a wide merged cell showing the title of the sheet. I also have a colored Textbox that I would like to position immediately to the right of the text in the merged cell.
The width of the title is variable so I have used a very wide merged cell.
sheet.Range["A2"].Value = title;
//Red Square
sheet.Shapes.Item("redSquare").Left += 0; // Position sheet.Range["A2"].TextWidth ???
Is there a property I can access on Range that will give me the actual text width in pixels of the text in merged cell?
As far as I know, there isn't anything in Interop that will tell you the width of text in pixels, but you can do it with the following. It seems to return a value reasonably similar to the column widths that Excel sets based on the same fonts.
Excel.Range xlRange = sheet.get_Range("A2");
Excel.Font xlFont = xlRange.Font;
string fontName = xlFont.Name;
double fontSize = xlFont.Size;
Font font = new Font(fontName, (float)fontSize);
float width = Graphics.FromImage(new Bitmap(1, 1)).MeasureString(title, font).Width;
You might need to add a few pixels here and there to make sure your textbox clears the end of the text, but I think it's about as accurate as you're going to get.

How to fill the color in cells A1:A5 and B1:B5 and C1:C5 with the same color using C#?

I am currently using the following code to fill cells in the range A1 to A5, and B1 to B5, with yellow:
chartRange1 = xlWorkSheet.get_Range("A1", "A5");
chartRange1.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);
Excel.Range chartRange2;
chartRange2 = xlWorkSheet.get_Range("B1", "B5");
chartRange2.Interior.Color= System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow);
But it takes 2 chartRange objects in order to do this. What if I want to set the same color over a wide range of cells?
Is there a way to do this using a single statement that sets the same color for a larger range of cells?
In your case (A1:A5, B1:B5, C1:C5) you can merge the cells into a contiguous range A1:C5:
xlWorkSheet.get_Range("A1:C5");
But a range does not have to be contiguous. You can also use code like the following:
xlWorkSheet.get_Range("A1:A5,C1:C5,F10:F15");
Have you tried
chartRange = xlWorkSheet.get_Range("A1", "B5");
Are you able to just set the chartRange1 object to null, then reinitialize and set the next range?

Categories