Панели EPPlus Barchart не отображают цвета для отрицательного значения в Excel 2013, но отлично работают в Excel 2007

Я использую диаграмму BarClustered с использованием пакета EPPlus для Excel на С#. Я могу создать гистограмму по мере необходимости. Единственная проблема, с которой я сталкиваюсь, заключается в том, что когда у меня отрицательное значение, полоса не показывает никакого цвета. Это будет как бы прозрачная полоса только с границей.

Я столкнулся с этой проблемой в Excel 2013. Однако это отлично работает в Excel 2007.

ExcelWorksheet wsDataSource = xlPackage.Workbook.Worksheets.Add("DataSource");
wsDataSource.Hidden = eWorkSheetHidden.VeryHidden;
var namedStyle = xlPackage.Workbook.Styles.CreateNamedStyle("HyperLink");   
namedStyle.Style.Font.UnderLine = true;
namedStyle.Style.Font.Color.SetColor(Color.Blue);

//Here I iterate through an array and populate the wsDataSource values as below starting from 3rd row:
Feb     2000    5000
March   -2000   2770
April   4000    4643

var chart = worksheet.Drawings.AddChart("Chart", OfficeOpenXml.Drawing.Chart.eChartType.BarClustered);
//row is the offset int variable
chart.SetPosition(row + 2, 0, 0, 10);
chart.SetSize(750, 30);
chart.Title.Text = "Data Graph";
chart.Legend.Position = eLegendPosition.Top;
var barChart = chart as ExcelBarChart;
barChart.DataLabel.ShowValue = true;

var mySeries = chart.Series.Add(wsDataSource.Cells[3, 2, intDataRow - 1, 2], wsDataSource.Cells[3, 1, intDataRow - 1, 1]);
mySeries.Header = "Current Year";

//isPreviousYearDataAvailable is a boolean which indicates if previous year data for the user is available.
if (isPreviousYearDataAvailable)
{
    var mySeries2 = chart.Series.Add(wsDataSource.Cells[3, 3, intDataRow, 3], wsDataSource.Cells[3, 1, intDataRow - 1, 1]);
    mySeries2.Header = "Previous Year"
}

Ниже приведено изображение, которое я получаю для отрицательных значений при открытии с помощью Excel 2013.

График Excel 2013 (это не график для предоставленного мной примера данных)


person Sumesh Kuttan    schedule 01.07.2013    source источник


Ответы (3)


Похоже, что EPPlus не поддерживает тег «invertIfNegative» для рядов данных. Возможно, вам придется обратиться к авторам за помощью или добавить эту функцию самостоятельно. В спецификациях Open XML указано, что:

Этот элемент указывает, что родительский элемент должен инвертировать свои цвета, если значение отрицательное.

Также:

Значение on, 1 или true указывает, что свойство применяется. Это значение по умолчанию для этого атрибута, и оно подразумевается, когда присутствует родительский элемент, но этот атрибут опущен.

Поскольку EPPlus не отображает этот тег, используется значение по умолчанию, то есть «true». «Родительский элемент» в данном случае — это XML-элемент ряда данных. Таким образом, это означает, что цвета будут инвертированы, если значение ячейки отрицательное. Отсюда прозрачный цвет, который вы видите.

Я обнаружил, что разные версии Excel немного по-разному подчиняются спецификациям Open XML. Excel 2013 более строго соответствует спецификациям Open XML, поэтому вы получаете прозрачный цвет. Excel 2007, вероятно, проигнорировал отсутствующий тег «invertIfNegative» (это означает, что если он отсутствует, вы не хотите иметь ничего общего с инвертированием цветов и т. Д., И поэтому Excel просто отобразит цвет). В этом смысле Excel 2007 более снисходителен к ошибкам, что может быть и хорошо, и плохо.

person Vincent Tan    schedule 04.07.2013
comment
Спасибо Винсент. Думаю, мне придется согласиться с вашим объяснением. - person Sumesh Kuttan; 15.07.2013

Добавление <c:invertIfNegative val="0"/> в XML вручную, похоже, сработало для меня:

System.Xml.XmlNode invertIfNegativeNode = chart.ChartXml.CreateElement(
    "c", "invertIfNegative", "http://schemas.openxmlformats.org/drawingml/2006/chart");
System.Xml.XmlAttribute invertIfNegativeAttribute = chart.ChartXml.CreateAttribute("val");
invertIfNegativeAttribute.Value = "0";
invertIfNegativeNode.Attributes.Append(invertIfNegativeAttribute);
chart.ChartXml.DocumentElement["c:chart"]["c:plotArea"]["c:barChart"]["ser"].AppendChild(invertIfNegativeNode);
person Saxon Druce    schedule 30.05.2014

Добавляя к этому старому сообщению, я столкнулся с той же проблемой в Excel 2016, но не смог решить ее с помощью прямого ответа @Saxon Druce. Когда я просматриваю chart1.xml за Excel, только ser содержит invertIfNegative, и установка его атрибута val на 0 не применяется ни к одному бару (по-прежнему остается инвертированным/прозрачным). Когда я открываю файл в Excel и снимаю флажок Опция серии/Инвертировать, если отрицательное значение и снова открываю файл chart1.xml, я обнаружил, что каждый бар dPt содержит invertIfNegative узел.

Поэтому я немного изменил ответ @Saxon Druce, создав и добавив узел invertIfNegative к dPt каждого столбца (2-я стрелка) вместо добавления к родительскому узлу ser (1-я стрелка). Затем ExcelBarChart оказывается в порядке со всеми полосами, окрашенными (не инвертированными).

Я часами ломал голову, так что, надеюсь, это поможет кому-то с Excel 2016.

ExcelXml

var nsuri = chartXml.DocumentElement.NamespaceURI;
var dPt = chartXml.CreateNode(XmlNodeType.Element, "dPt", nsuri);
var invertIfNegative = chartXml.CreateNode(XmlNodeType.Element, "invertIfNegative", nsuri);
var att = chartXml.CreateAttribute("val", nsuri);
att.Value = "0";
invertIfNegative.Attributes.Append(att);
dPt.AppendChild(invertIfNegative);

// Other xml changes
var idx = chartXml.CreateNode(XmlNodeType.Element, "idx", nsuri);
att = chartXml.CreateAttribute("val", nsuri);
att.Value = i.ToString();
idx.Attributes.Append(att);
dPt.AppendChild(idx);

ExcelBarChartSample

person KMC    schedule 15.08.2018