“无法将主题颜色转换为颜色”

问题描述 投票:0回答:4

我正在尝试使用 ClosedXml 读取 Excel 中单元格的填充背景颜色。我正在使用此示例代码,并且能够毫无问题地读取 Excel 文档的内容,但无法将单元格的 Fill BackgroundColor 读取为十六进制值。我可以看到在 BackgroundColor 下定义的 ThemeColorThemeTint 属性,但尚未找到将它们转换为 System.Color 或十六进制值的方法。这是我的代码:

// Get all categories
while (!categoryRow.Cell(coCategoryId).IsEmpty())
{
    IXLCell categoryName = categoryRow.Cell(coCategoryName);
    categories.Add(categoryName.GetString() + " " + XLColor.FromTheme(categoryName.Style.Fill.BackgroundColor.ThemeColor, categoryName.Style.Fill.BackgroundColor.ThemeTint).Color.ToHex());
    categoryRow = categoryRow.RowBelow();
}

似乎方法XLColor.FromTheme总是抛出异常“无法将主题颜色转换为颜色”。有谁知道从 ThemeColorThemeTint 值获取 System.Color 的另一种方法吗?

更新:

我没有提到我已经尝试使用 BackgroundColorColor 属性,不幸的是,这没有正确填充,如果您在调试器中查看它,那么您将看到该属性抛出与我得到的相同的异常使用方法 XLColor.FromTheme。所以这看起来绝对像是 ClosedXml 中的一个错误。有谁知道解决方法吗?

c# .net excel closedxml
4个回答
3
投票

我认为您需要评估

ColorType
属性和工作簿的主题(如果需要)。例如。像这样:

Private Function CellColor(ByVal cell As IXLCell, ByVal wb As XLWorkbook) As Drawing.Color

    Select Case cell.Style.Fill.BackgroundColor.ColorType
        Case XLColorType.Color
            Return cell.Style.Fill.BackgroundColor.Color

        Case XLColorType.Theme
            Select Case cell.Style.Fill.BackgroundColor.ThemeColor
                Case XLThemeColor.Accent1
                    Return wb.Theme.Accent1.Color
                Case XLThemeColor.Accent2
                    Return wb.Theme.Accent2.Color
                ...
            End Select
    End Select

正如 BruceHill 指出的,这忽略了着色/阴影。 ClosedXML似乎不支持这一点,因此必须手动计算。 Office 使用的算法可以在这里找到:http://social.msdn.microsoft.com/Forums/en-HK/oxmlsdk/thread/f6d26f2c-114f-4a0d-8bca-a27442aec4d0


0
投票

主题颜色只是枚举值(如

Background1
Text1
等),要获取需要从主题中获取的实际值。因此,在工作簿中查找一些“主题”属性,实际的主题颜色很可能是在其中定义的。


0
投票

我发现这篇文章非常有用,而且运行良好。:

刚刚在“RgbToHls”函数中发现了一个小错误,即在最小值和最大值相等的情况下未设置 alpha 值:

if (max == min)
        {

            hlsColor.H = 0;

            hlsColor.S = 0;

            hlsColor.L = max;

           --> **hlsColor.L = a;**
            return hlsColor;

        }

0
投票

我遇到了同样的问题,并想出了这个助手通过反射创建字典。由于主题是内部的,因此获取信息有点棘手:

public static Dictionary<XLThemeColor, XLColor> GetThemeColorMappingsViaReflection(XLWorkbook workbook)
{
    var themeColorMapping = new Dictionary<XLThemeColor, XLColor>();

    // Access the XLWorkbook's Theme property via reflection
    var themeProperty = typeof(XLWorkbook).GetProperty("Theme", BindingFlags.Public | BindingFlags.Instance);
    if (themeProperty == null) throw new InvalidOperationException("Theme property not found.");

    var theme = themeProperty.GetValue(workbook);
    if (theme == null) throw new InvalidOperationException("Theme is null.");

    // Access the Theme's color properties
    var colorProperties = theme.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var prop in colorProperties)
    {
        if (prop.PropertyType == typeof(XLColor))
        {
            XLThemeColor themeColor;
            if (Enum.TryParse<XLThemeColor>(prop.Name, out themeColor))
            {
                var color = (XLColor)prop.GetValue(theme);
                themeColorMapping.Add(themeColor, color);
            }
        }
    }

    return themeColorMapping;
}
© www.soinside.com 2019 - 2024. All rights reserved.