To set Different Colors For each line in Line Chart Using NPOI excel nuget package in .Net6 Core

12 Views Asked by At

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 image1

Sample of Line Chart Generated image2

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.

0

There are 0 best solutions below