Неверный цвет легенды в диаграмме Excel, созданной с помощью EPPlus

Мне интересно, есть ли способ вручную установить цвета ввода легенды.

Я изменил цвета серии на собственный цвет, но цвет легенды не обновляется. Смотрите изображение:

Неверный цвет легенды

1 ответ

Решение

Вот улучшенная версия кода, на который ссылается ОП в комментариях. Эту версию вы передаете в цвет, который вы хотите (вместо того, чтобы просто использовать случайные), чтобы SetChartPointsColor и он установит одинаковые цвета всех точек, а также создаст и введет для легенды:

public static void SetChartPointsColor(this ExcelChart chart, int serieNumber, Color color)
{
    var chartXml = chart.ChartXml;

    var nsa = chart.WorkSheet.Drawings.NameSpaceManager.LookupNamespace("a");
    var nsuri = chartXml.DocumentElement.NamespaceURI;

    var nsm = new XmlNamespaceManager(chartXml.NameTable);
    nsm.AddNamespace("a", nsa);
    nsm.AddNamespace("c", nsuri);

    var serieNode = chart.ChartXml.SelectSingleNode(@"c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser[c:idx[@val='" + serieNumber + "']]", nsm);
    var serie = chart.Series[serieNumber];
    var points = serie.Series.Length;

    //Add reference to the color for the legend and data points
    var srgbClr = chartXml.CreateNode(XmlNodeType.Element, "srgbClr", nsa);
    var att = chartXml.CreateAttribute("val");
    att.Value = $"{color.R:X2}{color.G:X2}{color.B:X2}";
    srgbClr.Attributes.Append(att);

    var solidFill = chartXml.CreateNode(XmlNodeType.Element, "solidFill", nsa);
    solidFill.AppendChild(srgbClr);

    var spPr = chartXml.CreateNode(XmlNodeType.Element, "spPr", nsuri);
    spPr.AppendChild(solidFill);

    serieNode.AppendChild(spPr);
}

Используйте это так:

using (var pck = new ExcelPackage(fileInfo))
{
    var workbook = pck.Workbook;
    var worksheet = workbook.Worksheets.Add("Sheet1");
    worksheet.Cells.LoadFromDataTable(datatable, true);

    var chart = worksheet.Drawings.AddChart("chart test", eChartType.ColumnStacked);
    chart.Series.Add(worksheet.Cells["B2:B11"], worksheet.Cells["A2:A11"]);
    chart.Series.Add(worksheet.Cells["C2:C11"], worksheet.Cells["A2:A11"]);

    var rand = new Random();
    var color = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));

    chart.SetChartPointsColor(0, color);
    color = Color.FromArgb(rand.Next(256), rand.Next(256), rand.Next(256));
    chart.SetChartPointsColor(1, color);

    pck.Save();
}

Дает это в выводе:

Пример вывода

ОТВЕТ НА КОММЕНТАРИИ

Для ряда линий это было бы немного по-другому:

public static void SetLineChartColor(this ExcelChart chart, int serieNumber, Color color)
{
    var chartXml = chart.ChartXml;

    var nsa = chart.WorkSheet.Drawings.NameSpaceManager.LookupNamespace("a");
    var nsuri = chartXml.DocumentElement.NamespaceURI;

    var nsm = new XmlNamespaceManager(chartXml.NameTable);
    nsm.AddNamespace("a", nsa);
    nsm.AddNamespace("c", nsuri);

    var serieNode = chart.ChartXml.SelectSingleNode($@"c:chartSpace/c:chart/c:plotArea/c:lineChart/c:ser[c:idx[@val='{serieNumber}']]", nsm);
    var serie = chart.Series[serieNumber];
    var points = serie.Series.Length;

    //Add reference to the color for the legend
    var srgbClr = chartXml.CreateNode(XmlNodeType.Element, "srgbClr", nsa);
    var att = chartXml.CreateAttribute("val");
    att.Value = $"{color.R:X2}{color.G:X2}{color.B:X2}";
    srgbClr.Attributes.Append(att);

    var solidFill = chartXml.CreateNode(XmlNodeType.Element, "solidFill", nsa);
    solidFill.AppendChild(srgbClr);

    var ln = chartXml.CreateNode(XmlNodeType.Element, "ln", nsa);
    ln.AppendChild(solidFill);

    var spPr = chartXml.CreateNode(XmlNodeType.Element, "spPr", nsuri);
    spPr.AppendChild(ln);

    serieNode.AppendChild(spPr);
}
Другие вопросы по тегам