We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Export Chart to png and excel

Hi,

I have created a 3D pie chart inside a ejDialog control.  I am trying to add functionality so that the user can do a server side export it to png or excel.  I cannot find documentation on how to do this specifically for ASP.Net Core EJ1.  (All the other types have lots of documentation....)

I tried following this older forum post (to save as png), https://www.syncfusion.com/forums/128915/how-to-render-chart-image-run-time-and-save-it-to-a-file.  However I get an "FormatException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters." error on Convert.FromBase64String(). 

Here is some code from my view:
       // the dialog that contains the pie chart
        List<string> stageAvgButtons = new List<string>() { "close", "print", "save", "excel" };
        <ej-dialog id="StageAveragesDialog" show-on-init="false" title="Stage Averages" width="1000" is-responsive="true" action-buttons="@stageAvgButtons" action-button-click="stageAvgButtonsClick">
            <e-dialog-position x-value="441px" y-value="153.6px" />
            <e-content-template>
                <div id="chartStageAvg"></div>
            </e-content-template>
        </ej-dialog>

// opens the dialog and creates the chart
        function openStageAverages() {
            var popupobj = $("#customWaiting").data("ejWaitingPopup");
            popupobj.show();

            var avgDialog = $("#StageAveragesDialog").ejDialog("instance");

            //avgDialog.width = 1000;
            avgDialog.open();

            $.ajax({
                url: "/Telecom/StageAverageDataSource",
                type: "GET",
                data: { "projId": @ProjId },
                success: function (dataPoints) {
                    if (dataPoints.length > 0) {
                        $("#chartStageAvg").ejChart({
                            commonSeriesOptions:
                                {
                                    labelPosition: 'outside',
                                    tooltip: { visible: true, format: "#point.x# : #point.y# Days" },
                                    marker:
                                        {
                                            dataLabel:
                                                {
                                                    shape: 'none',
                                                    visible: true,
                                                    textPosition: 'top',
                                                    border: { width: 1 },
                                                    connectorLine: { height: 70, stroke: "black" }
                                                }
                                        }
                                },
                            series: [{
                                points: dataPoints,
                                explodeIndex: 0,
                                border: { width: 2, color: 'white' },
                                type: 'pie',
                                labelPosition: 'outside',
                                startAngle: 145
                            }],
                            //Enabling 3D Chart           
                            enable3D: true,
                            enableRotation: true,
                            depth: 30,
                            tilt: -30,
                            rotation: -30,
                            perspectiveAngle: 90,
                            isResponsive: true,
                            load: "onchartload",
                            title: { text: "" },
                            size: { height: "600", width: "970" },
                            legend: { visible: false }                                                  
                        });
                    } else {
                        $("#chartStageAvg").html("There is not enough data to create the pie chart.");
                    }
                    var popupobj = $("#customWaiting").data("ejWaitingPopup");
                    popupobj.hide();
                }
            });
           
        }

       function stageAvgButtonsClick(args) {
            switch (args.currentTarget.toUpperCase()) {
                case "PRINT":
                    try {
                        var chartObj = $("#chartStageAvg").ejChart("instance");
                        chartObj.print("chartStageAvg");
                    } catch {
                        alert("There is not enough data to create the pie chart.");
                    }
                    break;
                case "SAVE":
                    try {
                        var chartObj = $("#chartStageAvg").ejChart("instance");
                        exporting = chartObj.model.exportSettings;
                        exporting.mode = "server";
                        exporting.type = "png";
                        exporting.action = "/Telecom/ExportStageAverages";
                        chartObj.export();

                    } catch {
                        alert("There is not enough data to create the pie chart.");
                    }
                    break;
                case "EXCEL":
                    // will add code here for excel
                default:
                    alert("Action " + args.currentTarget + " not defined.");
                    break;
            }

        }

From the controller:

 public void ExportStageAverages(string Data, string ChartModel)
        {
            ChartProperties propObj = ConvertChartObject(ChartModel);
            string type = propObj.ExportSettings.Type.ToString().ToLower();

            if (type == "png")
            {
                //Data = Data.Remove(0, Data.IndexOf(',') + 1);
                //MemoryStream stream = new MemoryStream(Convert.FromBase64String(Data));

                string fullPath = _hostingEnvironment.WebRootPath + @"\XlsIO\Telecom\Download\";

                using (FileStream fs = new FileStream(fullPath + "Averages.png", FileMode.Create))
                {
                    using (BinaryWriter bw = new BinaryWriter(fs))
                    {
                        byte[] data = Convert.FromBase64String(Data);
                        //byte[] data = Convert.
                        bw.Write(data);
                        bw.Dispose();
                    }
                }
            } else
            {
                // code for export to excel will go here
            }
           
        }

        private ChartProperties ConvertChartObject(string ChartModel)
        {
            var settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                MissingMemberHandling = MissingMemberHandling.Ignore
            };
            ChartProperties chartProp = new ChartProperties();
            chartProp = JsonConvert.DeserializeObject<ChartProperties>(ChartModel, settings);
            return chartProp;
        }

Thanks,
Chris

6 Replies

CH Chris November 5, 2018 11:15 PM UTC

I have a couple other questions that wouldn't fit in the original post.

1) How can I change the icon for "print" in the ejdialog? 
2) For exporting the chart to excel is it possible to pass an extra parameter to the controller method?  I need to know the "projectId" so it can get the right data.

Thanks,
Chris


DD Dharanidharan Dharmasivam Syncfusion Team November 7, 2018 11:50 AM UTC

Hi Chris, 
 
Greetings from Syncfusion.  
 
Chart Component: 
We have analyzed our query. We would like to let you know that, as of now we have provided support or 3D chart in SVG mode only, so 3D chart can’t be exported as image. And for 3D chart export to Excel in server side, we have logged feature request for this requirement. While the feature itself important, we are afraid we can’t provide you an accurate timeline on when this feature will be available in our site. So, based on the priority the feature will be available in any of our upcoming release. 
 
Dialog Component: 
By default, svg icons are used for EJ1 dialog action buttons.  If you wish to change this svg print icon, you can remove the svg icon and add your customized icons.  Please find the below css code for your reference.  
 
<style class="cssStyles">  
       .e-icon.e-print:before{   //  Remove default print icon   
         content: "";  
       }  
       .e-icon.e-print{     // Add your customized image  
       }  
       .e-icon.e-print:hover // Add your customized image when you hovering element  
       }  
</style>  
 


 
Please find the below JS playground link.  
 
Thanks, 
Dharani. 



CH Chris November 7, 2018 03:39 PM UTC

Hi,

Thanks for the reply.  In ASP.net Core EJ1 are we able to save a pie chart as image and export to excel if it is NOT 3d?  If so, could I have an example?

Thanks,
Chris


CH Chris November 7, 2018 04:10 PM UTC

Sorry, I thought of another question... 

Can you save a 3d chart as an SVG file?  If so, how would you do that? 

I just realized there is way you could export a 3d chart to excel.  You could do it yourself using XlsIO instead of the built in export to excel functionality in the chart.

Chris


CH Chris November 7, 2018 11:44 PM UTC

Hi,

I figured out how to save the 3d pie chart as SVG and how to export to excel using XlsIO.  I even got the chart in the excel file looking reasonably close to the one created in the view.  Here is my controller method:

public ActionResult ExportStageAverages(string Data, string ChartModel)
        {
            ChartProperties propObj = ConvertChartObject(ChartModel);
            string type = propObj.ExportSettings.Type.ToString().ToLower();

            if (type == "svg")
            {
                // to svg                               
                string data = System.Uri.UnescapeDataString(Data);

                MemoryStream ms = new MemoryStream();
                TextWriter tw = new StreamWriter(ms);

                tw.WriteLine(data);
                tw.Flush();
                ms.Position = 0;

                return File(ms, "application/force-download", "Averages.svg");
            } else
            {
                if (type == "xlsx")
                {
                    ExcelEngine excelEngine = new ExcelEngine();

                    IApplication application = excelEngine.Excel;

                    // create new workbook
                    IWorkbook workbook = application.Workbooks.Create();
                    IWorksheet sheet = workbook.Worksheets[0];

                    sheet.Name = "Averages";
                  
                    string stageText = propObj.Legend.Title.Text;

                    sheet.Range["A1"].ColumnWidth = 14.43;
                    sheet.Range["B1"].ColumnWidth = 14.29;

                    sheet.Range["A1"].Text = stageText + " Averages";
                    sheet.Range["A1"].CellStyle.Font.Bold = true;
                    sheet.Range["A1"].CellStyle.Font.Size = 16;

                    sheet.Range["A3"].Text = stageText;                   
                    sheet.Range["B3"].Text = "Length (Days)";
                    sheet.Range["A3:B3"].CellStyle.Font.Bold = true;
                    sheet.Range["A3:B3"].CellStyle.Font.Underline = ExcelUnderline.Single;

                    // the data points are already in the chart properties, no need to recalculate
                    int curRowIdx = 3;                   
                    foreach (var point in propObj.Series[0].Points)
                    {
                        curRowIdx++;
                        sheet.Range["A" + curRowIdx.ToString()].Text = point.X;
                        sheet.Range["B" + curRowIdx.ToString()].Number = point.Y;                       
                    }

                    IChartShape chart = sheet.Charts.Add();
                    chart.ChartType = ExcelChartType.Pie_Exploded_3D;
                    chart.DataRange = sheet.Range["A3:B" + curRowIdx.ToString()];
                    chart.IsSeriesInRows = false;
                    chart.ChartTitle = "";
                    chart.TopRow = curRowIdx + 1;
                    chart.BottomRow = curRowIdx + 35;
                    chart.RightColumn = 9;
                    chart.HasLegend = false;
                   
                    IChartSerie serie = chart.Series[0];
                    chart.ChartArea.LineProperties.LinePattern = ExcelChartLinePattern.None;
                    // can't use DefaultDataPoint as I want to add a "suffix" to each one
                    //serie.DataPoints.DefaultDataPoint.DataLabels.IsValue = true;
                    //serie.DataPoints.DefaultDataPoint.DataLabels.IsCategoryName = true;
                    //serie.DataPoints.DefaultDataPoint.DataLabels.ShowLeaderLines = true;
                    //serie.DataPoints.DefaultDataPoint.DataLabels.Position = ExcelDataLabelPosition.Outside;
                    //serie.DataPoints.DefaultDataPoint.DataLabels.Delimiter = ": ";                  
                   
                    //serie.DataPoints.DefaultDataPoint.DataLabels.Text = serie.DataPoints.DefaultDataPoint.DataLabels.Text + " Days";

                    int curIdx = 0;
                    foreach (var point in propObj.Series[0].Points) {
                        serie.DataPoints[curIdx].DataFormat.Fill.ForeColor = Syncfusion.Drawing.ColorTranslator.FromHtml(point.Fill);
                        serie.DataPoints[curIdx].DataLabels.Text = point.X + ": " + point.Y.ToString() + " days";
                        serie.DataPoints[curIdx].DataLabels.Position = ExcelDataLabelPosition.Outside;
                        serie.DataPoints[curIdx].DataLabels.ShowLeaderLines = true;
                        curIdx++;
                    }

                    chart.Elevation = 50;
                    chart.Rotation = 90;

                    chart.Series[0].SerieFormat.Percent = 40;
                   
                    string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                    workbook.Version = ExcelVersion.Excel2016;
                    string fileName = "Averages.xlsx";

                    try
                    {
                        MemoryStream ms = new MemoryStream();
                        workbook.SaveAs(ms);
                        ms.Position = 0;

                        workbook.Close();
                        excelEngine.Dispose();

                        return File(ms, contentType, fileName);
                    }
                    catch
                    {
                        return View();
                    }
                }
               
            }
            // should never get here
            return View();
        }


DD Dharanidharan Dharmasivam Syncfusion Team November 8, 2018 07:34 AM UTC

Hi Chris, 
 
Thanks for the information. As stated earlier we will provide support for exporting 3d chart to excel in any of our upcoming release. Kindly revert us, if you need any further assistance. 
 
Thanks, 
Dharani. 


Loader.
Up arrow icon