I have code to Generate Excel File using Npoi package where my data on excel sheet creates Line Chart. In that I have 4 lines in my line chart where all line colors appear by default. I want to set custom colors for each Line in Line chart that is I want to set 4 different colors for 4 Lines on my own. How to achieve this using NPOI Package?
using NPOI.OpenXmlFormats.Dml.Chart;
using NPOI.SS.UserModel.Charts;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System.Drawing;
using SixLabors.ImageSharp.PixelFormats;
namespace LineChart
{
class Program
{
const int NUM_OF_ROWS = 3;
const int NUM_OF_COLUMNS = 10;
static void CreateChart(IDrawing drawing, ISheet sheet, IClientAnchor anchor, string[] series1, bool enableMajorGridline = false)
{
XSSFChart chart = (XSSFChart)drawing.CreateChart(anchor);
chart.SetTitle("Test 1");
IChartLegend legend = chart.GetOrCreateLegend();
legend.Position = LegendPosition.TopRight;
ILineChartData<double, double> data = chart.ChartDataFactory.CreateLineChartData<double, double>();
// Use a category axis for the bottom axis.
IChartAxis bottomAxis = chart.ChartAxisFactory.CreateCategoryAxis(AxisPosition.Bottom);
IValueAxis leftAxis = chart.ChartAxisFactory.CreateValueAxis(AxisPosition.Left);
leftAxis.Crosses = AxisCrosses.AutoZero;
// Iterate over the series names and add corresponding series to the chart data
for (int i = 0; i < 4; i++)
{
IChartDataSource<double> xs = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, NUM_OF_COLUMNS - 1));
IChartDataSource<double> ys = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(i + 1, i + 1, 0, NUM_OF_COLUMNS - 1));
var series = data.AddSeries(xs, ys);
series.SetTitle(series1[i]);
// Set custom color for the series
SetSeriesColor(chart, i);
}
chart.Plot(data, bottomAxis, leftAxis);
// Add major gridline, available since NPOI 2.5.5
var plotArea = chart.GetCTChart().plotArea;
plotArea.lineChart[0].ser[0].dPt = new List<NPOI.OpenXmlFormats.Dml.Chart.CT_DPt>();
//plotArea.catAx[0].AddNewMajorGridlines();
//plotArea.valAx[0].AddNewMajorGridlines();
}
static void SetSeriesColor(XSSFChart chart, int seriesIndex)
{
var ctChart = chart.GetCTChart();
var dpt = new NPOI.OpenXmlFormats.Dml.Chart.CT_DPt();
dpt.idx = new NPOI.OpenXmlFormats.Dml.Chart.CT_UnsignedInt();
dpt.idx.val = (uint)seriesIndex;
dpt.spPr = new NPOI.OpenXmlFormats.Dml.Chart.CT_ShapeProperties();
var solidFill = dpt.spPr.AddNewSolidFill();
var color1 = solidFill.AddNewSrgbClr();
// Define colors based on index
switch (seriesIndex % 4)
{
case 0: // Orange
color1.val = new byte[] { Color.Orange.R, Color.Orange.G, Color.Orange.B };
break;
case 1: // Green
color1.val = new byte[] { Color.Green.R, Color.Green.G, Color.Green.B };
break;
case 2: // Red
color1.val = new byte[] { Color.Red.R, Color.Red.G, Color.Red.B };
break;
case 3: // Black
color1.val = new byte[] { Color.Black.R, Color.Black.G, Color.Black.B };
break;
}
var ser = ctChart.plotArea.lineChart[0].ser[seriesIndex];
ser.dPt.Add(dpt);
//plotArea.lineChart[0].ser[0].dPt.Add(dpt);
}
static void Main(string[] args)
{
using (IWorkbook wb = new XSSFWorkbook())
{
ISheet sheet = wb.CreateSheet("linechart");
// Create a row and put some cells in it. Rows are 0 based.
IRow row;
ICell cell;
for (int rowIndex = 0; rowIndex < NUM_OF_ROWS; rowIndex++)
{
row = sheet.CreateRow((short)rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++)
{
cell = row.CreateCell((short)colIndex);
cell.SetCellValue(colIndex * (rowIndex + 1));
}
}
IDrawing drawing = sheet.CreateDrawingPatriarch();
IClientAnchor anchor2 = drawing.CreateAnchor(0, 0, 0, 0, 0, 20, 10, 35);
CreateChart(drawing, sheet, anchor2, new string[] { "s1", "s2", "s3", "s4" }, true);
using (FileStream fs = File.Create("C:\\Users\\lenovo\\Downloads\\linechart.xlsx"))
{
wb.Write(fs, false);
}
}
}
}
}
Sample of Line Chart Generated

Sample of Line Chart Generated

I was able to set custom colors for Pie chart, Bar chart and Column chart. But I wasn't able to set custom color for Line Chart alone. I was facing Null Exception Error in
var ser = ctChart.plotArea.lineChart[0].ser[seriesIndex];
Error: System.NullReferenceException: 'Object reference not set to an instance of an object.' NPOI.OpenXmlFormats.Dml.Chart.CT_PlotArea.lineChart.get returned null.