Epplus如何获取正确的单元格背景RGB颜色

5

我在使用EPPLUS时遇到了一些问题,无法获取背景颜色的真正RGB值。

我的代码只能用于在Excel上设置为RGB的颜色,不能识别调色板颜色的单元格。

以下是我的代码,希望有人能帮助我解决问题:

ExcelRangeBase c = sheet.Cells[k, j];
var wbs = sheet.Workbook.Styles;
var fill = c.Style.Fill;
string rgb = "";
if (fill.PatternType == OfficeOpenXml.Style.ExcelFillStyle.Solid)
{
  rgb = !String.IsNullOrEmpty(fill.BackgroundColor.Rgb) ? fill.BackgroundColor.Rgb :
  fill.PatternColor.LookupColor(fill.BackgroundColor);
}
else if (fill.PatternType != OfficeOpenXml.Style.ExcelFillStyle.None)
{
  rgb = !String.IsNullOrEmpty(fill.PatternColor.Rgb) ? fill.PatternColor.Rgb :
  fill.PatternColor.LookupColor(fill.PatternColor);
}
if (rgb.StartsWith("#")) rgb.Replace("#", "");
rgb = rgb.Trim();

// Removes ALPHA from ARGB
if (rgb.Length == 8 || rgb.Length == 5) rgb = rgb.Substring(2);
else if (rgb.Length > 8) rgb = rgb.Substring(rgb.Length - 6);

if (!rgb.StartsWith("#")) rgb = "#" + rgb;

string bg = "";
// I got this validation because most times lookupColor returns FF000;
if (rgb != null && rgb != "" && rgb != "#000" && rgb != "#000000")
{
  bg = "background: " + rgb + "; ";
}

2个回答

5
如果您在Excel颜色下拉菜单中选择了“主题颜色”而不是“标准颜色”或者从颜色选择器中选择颜色,则似乎无法按照此问题的答案所述工作:EPPlus Excel Change cell color 看来主题不受支持-EPPlus FAQ

该库不支持什么(这些是最明显的特点)?[...] * 主题


2
谢谢您的回复,Bunker。我明白主题不受支持,而且我认为我没有使用它们,我使用了Excel中的默认颜色。我猜它们在EPPlus中被称为Tinted或Indexed,因为ExcelColor.LookupColor方法说:“返回使用Indexed或Tint属性的颜色对象的RGB值”。我检查了一下,我的代码返回了#FF000颜色,并且某些单元格上有Indexed和Tint属性。 - AleMonteiro

1
原来这是EPPlus中LookupColor的一个怪癖。具体来说,颜色格式在这种情况下返回的是AA {R} {G} {B}, alpha通道使用两个字符,每个R、G和B通道都使用相同长度的序列,指定灰度。然而,如果你看一下代码,你可能会得到一些非常奇怪的颜色(即它可能有bug)。这是因为使用的固定长度可以从1到3个字符不等,上限为0x0200
例如,((int)(decimal.Round(-1M * -512))).ToString("X") 返回 "200",根据推断,将会返回#FF200200200。然而,除非提交一个修补程序来改变处理方式,否则做这件事的方法可能是相信这就是可以返回通道的上限,然后在0->FF之间进行缩放。
以下是一种进行此操作的方法。请注意,如果这在EPPlus本身中得到修复,下面的代码将无法正确缩放(因为实际上的上限将是“FF”,而不是“0x0200”)。

private string EPPLookupColorFixed(ExcelColor sourceColor)
    {
        var lookupColor = sourceColor.LookupColor();
        const int maxLookup = 63;
        bool isFromTable = (0 <= sourceColor.Indexed) && (maxLookup > sourceColor.Indexed);
        bool isFromRGB = (null != sourceColor.Rgb && 0 < sourceColor.Rgb.Length);
        if (isFromTable || isFromRGB)
            return lookupColor;

        // Ok, we know we entered the else block in EPP - the one 
        // that doesn't quite behave as expected.

        string shortString = "0000";
        switch (lookupColor.Length)
        {
            case 6:
                // Of the form #FF000
                shortString = lookupColor.Substring(3, 1).PadLeft(4, '0');
                break;
            case 9:
                // Of the form #FFAAAAAA
                shortString = lookupColor.Substring(3, 2).PadLeft(4, '0');
                break;
            case 12:
                // Of the form #FF200200200
                shortString = lookupColor.Substring(3, 3).PadLeft(4, '0');
                break;
        }
        var actualValue = short.Parse(shortString, System.Globalization.NumberStyles.HexNumber);
        var percent = ((double)actualValue) / 0x200d;
        var byteValue = (byte)Math.Round(percent * 0xFF,0);
        var byteText = byteValue.ToString("X");
        byteText = byteText.Length == 2 ? byteText : byteText.PadLeft(2, '0');
        return $"{lookupColor.Substring(0, 3)}{byteText}{byteText}{byteText}";
    }

是的,但LookupColor对于任何主题颜色都没有帮助 - EPPlus不支持主题,而且如果不知道应用于包含您正在查看的范围的工作表的主题,则无法确定色调对应的颜色。 - Alexander Høst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接