highcharts 导出图片 .net Demo

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了highcharts 导出图片 .net Demo相关的知识,希望对你有一定的参考价值。

highcharts 的Net导出服务  GitHub上整理的https://github.com/imclem/Highcharts-export-module-asp.net

引用两个程序集 sharpPDF.dll,Svg.dll (实际上就是将svg转化成其他格式的图片)

两种导出情况:  

1、只需要图片,修改自带导出按钮的请求路径路径就行
2、需要插入到word等二次处理再导出时

 

页面:

技术分享
@{
    ViewBag.Title = "Index";
}

@section css{

}


@section scripts{

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="/Scripts/Highcharts-4.0.4/js/highcharts.js"></script>
<script src="/Scripts/Highcharts-4.0.4/js/highcharts-more.js"></script>
<script src="/Scripts/Highcharts-4.0.4/js/modules/exporting.js"></script>

<script type="text/javascript">
    var chart;
    $(function () {

    var datas = {
        chart: {
            zoomType: xy
        }, 
        title: {
            text: Temperature vs Rainfall
        },
        xAxis: [{
            categories: [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
        }],
        yAxis: [{ // Primary yAxis
            labels: {
                format: {value} °C,
                style: {
                    color: Highcharts.getOptions().colors[1]
                }
            },
            title: {
                text: Temperature,
                style: {
                    color: Highcharts.getOptions().colors[1]
                }
            }
        }, { // Secondary yAxis
            title: {
                text: Rainfall,
                style: {
                    color: Highcharts.getOptions().colors[0]
                }
            },
            labels: {
                format: {value} mm,
                style: {
                    color: Highcharts.getOptions().colors[0]
                }
            },
            opposite: true
        }],

        tooltip: {
            shared: true
        },

        exporting: {
            url: /HighCharts/Export,  //1、自带导出按钮的请求路径
            filename: MyChart,
            width: 1200
        },
        series: [ 
        {
            name: Temperature,
            type: spline,
            data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6],
            tooltip: {
                pointFormat: <span style="font-weight: bold; color: {series.color}">{series.name}</span>: <b>{point.y:.1f}°C</b> 
            }
        }, {
            name: Temperature error,
            type: errorbar,
            data: [[6, 8], [5.9, 7.6], [9.4, 10.4], [14.1, 15.9], [18.0, 20.1], [21.0, 24.0], [23.2, 25.3], [26.1, 27.8], [23.2, 23.9], [18.0, 21.1], [12.9, 14.0], [7.6, 10.0]],
            tooltip: {
                pointFormat: (error range: {point.low}-{point.high}°C)<br/>
            }
        }

        , {
            name: t2===========,
            type: spline,
            data: [118.3, 13.9, 7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 9.6],
            tooltip: {
                pointFormat: <span style="font-weight: bold; color: {series.color}">{series.name}</span>: <b>{point.y:.1f}°C</b> 
            }
        }, {
            name: t2============ error,
            type: errorbar,
            data: [[118.0, 121.1], [12.9, 14.0], [6, 8], [5.9, 7.6], [9.4, 10.4], [14.1, 15.9], [18.0, 20.1], [21.0, 24.0], [23.2, 25.3], [26.1, 27.8], [23.2, 23.9], [7.6, 10.0]],
            tooltip: {
                pointFormat: (error range: {point.low}-{point.high}°C)<br/>
            }
        }

         


        ]
    };
    $(#container-Test).highcharts(datas);
    $(#container-Test2).highcharts(datas);
});
         
    // 2、插入到word等二次处理时导出
    //点击一个按钮导出图片
    function exportClick() {

        var chartTest = $(#container-Test).highcharts();
        var svgData = chartTest.getSVG();

        $.post(/HighCharts/ManualExport, { filename: "手动导出的图片", type: "image/png", width: 1200, svg: svgData }, function (r) {
            if (!r.state) return;

            window.location.href = r.downloadpath;
        },json);


    }

</script>

}


<h2>Index</h2>

<div>

    <input type="button" value="点击一个按钮导出图片" onclick="exportClick()"/>
</div>


<div id="container-Test" style="height: 400px; margin: auto; min-width: 310px; max-width: 600px"></div>
<hr />
<div id="container-Test2" style="height: 400px; margin: auto; min-width: 310px; max-width: 600px"></div>
xxoo Code

 

控制器: 

技术分享
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Timers;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using xxoo.Common.HighChart;

namespace ToolsSite.Controllers
{
    public class HighChartsController : Controller
    {
        //
        // GET: /HighCharts/

        public ActionResult Index()
        {
            

            return View();
        }


        #region1、 自带的导出按钮
        //修改 HighChart 导出服务器路径
        //exporting: { url: ‘/HighCharts/Export‘,   filename: ‘MyChart‘,     width: 1200  },
        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Export(string filename, string type, int width,string svg)
        {
            
            Exporter export = new Exporter(filename, type, width, svg);

            //// 1、文件名输出
            //FileStream fileWrite = new FileStream(@"d:\HighCharts导出图片.png", FileMode.Create, FileAccess.Write);
            //ExportFileInfo fi = export.WriteToStream(fileWrite);
            //string fileName = "导出的图片." + fi.Extension;
            //fileWrite.Close();
            //fileWrite.Dispose();
            //return File(@"d:\HighCharts导出图片.png", fi.ContentType, fileName);

            // 2、 字节输出
            ExportFileInfo fi;
            byte[] buffer = export.WriteToBuffer(out fi);
            string fileName = "导出的图片." + fi.Extension;
            return File(buffer, fi.ContentType, fileName);
        }
       #endregion

        #region 2、 点击一个按钮导出图片 (插入到word中导出是用到)

        [ValidateInput(false)]
        [HttpPost]
        public ActionResult ManualExport(string filename, string type, int width, string svg)
        {
            Exporter export = new Exporter(filename, type, width, svg);
            string fileId = Guid.NewGuid().ToString();
            string tempFilePath = Request.MapPath("~/DownFile/") + fileId;


            // 1、文件名输出 
            FileStream fileWrite = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write);
            ExportFileInfo fi = export.WriteToStream(fileWrite);
            filename += "." + fi.Extension;
            fileWrite.Close();
            fileWrite.Dispose();

            Timer tr = new Timer(1000 * 60 * 1); // 1分钟后删除
            tr.Elapsed += (s, e) =>
            {
                if (System.IO.File.Exists(tempFilePath))
                {
                    System.IO.File.Delete(tempFilePath);
                }
            };
            tr.Start();

            string downloadPath = string.Format( "/HighCharts/ManualDownload?fileId={0}&ContentType={1}&fileName={2}"
                    , fileId,fi.ContentType, filename);

            var o = new { state = true, downloadpath = downloadPath };
            string result = JsonConvert.SerializeObject(o);

            return Content(result);
        }

        // 手动下载导出文件
        [HttpGet]
        public ActionResult ManualDownload(string fileId, string ContentType,string fileName)
        {
            string tempFilePath = Request.MapPath("~/DownFile/") + fileId;
            if (!System.IO.File.Exists(tempFilePath))
            {
                return Redirect("/HighCharts/Index?msg=文件已失效");
            }

            byte[] buffer = System.IO.File.ReadAllBytes(tempFilePath);
            System.IO.File.Delete(tempFilePath);
            return File(buffer, ContentType, fileName);
        }

        #endregion

    }
}
xxoo Code

 

工具类:  

技术分享
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using sharpPDF;
using Svg;
using Svg.Transforms;

namespace xxoo.Common.HighChart
{
    /// <summary>
    /// Processes web requests to export Highcharts JS JavaScript charts.
    /// </summary>
    internal static class ExportChart
    {
        /// <summary>
        /// Processes HTTP Web requests to export SVG.
        /// </summary>
        /// <param name="context">An HttpContext object that provides references 
        /// to the intrinsic server objects (for example, Request, Response, 
        /// Session, and Server) used to service HTTP requests.</param>
        internal static void ProcessExportRequest(HttpContext context)
        {
            if (context != null &&
              context.Request != null &&
              context.Response != null &&
              context.Request.HttpMethod == "POST")
            {
                HttpRequest request = context.Request;

                // Get HTTP POST form variables, ensuring they are not null.
                string filename = request.Form["filename"];
                string type = request.Form["type"];
                int width = 0;
                string svg = request.Form["svg"];

                if (filename != null &&
                  type != null &&
                  Int32.TryParse(request.Form["width"], out width) &&
                  svg != null)
                {
                    // Create a new chart export object using form variables.
                    Exporter export = new Exporter(filename, type, width, svg);

                    // Write the exported chart to the HTTP Response object.
                    export.WriteToHttpResponse(context.Response);

                    // Short-circuit this ASP.NET request and end. Short-circuiting
                    // prevents other modules from adding/interfering with the output.
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    context.Response.End();
                }
            }
        }

        internal static void ProcessExportRequest(string filename, string type, string svg,string widthStr,Stream stream)
        {
            // Get HTTP POST form variables, ensuring they are not null. 
            int width = 0; 

            if (filename != null &&
                type != null &&
                Int32.TryParse(widthStr, out width) &&
                svg != null)
            {
                // Create a new chart export object using form variables.
                Exporter export = new Exporter(filename, type, width, svg); 

                // Write the exported chart to the HTTP Response object.
                export.WriteToStream(stream);

                // Short-circuit this ASP.NET request and end. Short-circuiting
                // prevents other modules from adding/interfering with the output.
                HttpContext.Current.ApplicationInstance.CompleteRequest();
                HttpContext.Current.Response.End();
            } 
        }
    }

    /// <summary>
    /// 导出的文件信息
    /// </summary>
    internal class ExportFileInfo
    {
        /// <summary>
        /// 文件扩展名
        /// </summary>
        public string Extension { get; set; }
        /// <summary>
        /// 响应输出文件类型
        /// </summary>
        public string ContentType { get; set; }
    }

    /// <summary>
    /// .NET chart exporting class for Highcharts JS JavaScript charts.
    /// </summary>
    internal class Exporter
    {
        /// <summary>
        /// Default file name to use for chart exports if not otherwise specified.
        /// </summary>
        private const string DefaultFileName = "Chart";

        /// <summary>
        /// PDF metadata Creator string.
        /// </summary>
        private const string PdfMetaCreator =
          "Tek4(TM) Exporting Module for Highcharts JS from Tek4.com";

        /// <summary>
        /// Gets the HTTP Content-Disposition header to be sent with an HTTP
        /// response that will cause the client‘s browser to open a file save
        /// dialog with the proper file name.
        /// </summary>
        public string ContentDisposition { get; private set; }

        /// <summary>
        /// Gets the MIME type of the exported output.
        /// </summary>
        public string ContentType { get; private set; }

        /// <summary>
        /// Gets the file name with extension to use for the exported chart.
        /// </summary>
        public string FileName { get; private set; }

        /// <summary>
        /// Gets the chart name (same as file name without extension).
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// Gets the SVG chart document (XML text).
        /// </summary>
        public string Svg { get; private set; }

        /// <summary>
        /// Gets the pixel width of the exported chart image.
        /// </summary>
        public int Width { get; private set; }

        /// <summary>
        /// Initializes a new chart Export object using the specified file name, 
        /// output type, chart width and SVG text data.
        /// </summary>
        /// <param name="fileName">The file name (without extension) to be used 
        /// for the exported chart.</param>
        /// <param name="type">The requested MIME type to be generated. Can be
        /// ‘image/jpeg‘, ‘image/png‘, ‘application/pdf‘ or ‘image/svg+xml‘.</param>
        /// <param name="width">The pixel width of the exported chart image.</param>
        /// <param name="svg">An SVG chart document to export (XML text).</param>
        internal Exporter(
          string fileName,
          string type,
          int width,
          string svg)
        {
            string extension;

            this.ContentType = type.ToLower();
            this.Name = fileName;
            this.Svg = svg;
            this.Width = width;

            // Validate requested MIME type.
            switch (ContentType)
            {
                case "image/jpeg":
                    extension = "jpg";
                    break;

                case "image/png":
                    extension = "png";
                    break;

                case "application/pdf":
                    extension = "pdf";
                    break;

                case "image/svg+xml":
                    extension = "svg";
                    break;

                // Unknown type specified. Throw exception.
                default:
                    throw new ArgumentException(
                      string.Format("Invalid type specified: ‘{0}‘.", type));
            }

            // Determine output file name.
            this.FileName = string.Format(
              "{0}.{1}",
              string.IsNullOrEmpty(fileName) ? DefaultFileName : fileName,
              extension);

            // Create HTTP Content-Disposition header.
            this.ContentDisposition =
              string.Format("attachment; filename={0}", this.FileName);
        }

        /// <summary>
        /// Creates an SvgDocument from the SVG text string.
        /// </summary>
        /// <returns>An SvgDocument object.</returns>
        private SvgDocument CreateSvgDocument()
        {
            SvgDocument svgDoc;

            // Create a MemoryStream from SVG string.
            using (MemoryStream streamSvg = new MemoryStream(
              Encoding.UTF8.GetBytes(this.Svg)))
            {
                svgDoc = SvgDocument.Open<SvgDocument>(streamSvg);
            }

            // Scale SVG document to requested width.
            svgDoc.Transforms = new SvgTransformCollection();
            float scalar = (float)this.Width / (float)svgDoc.Width;
            svgDoc.Transforms.Add(new SvgScale(scalar, scalar));
            svgDoc.Width = new SvgUnit(svgDoc.Width.Type, svgDoc.Width * scalar);
            svgDoc.Height = new SvgUnit(svgDoc.Height.Type, svgDoc.Height * scalar);

            return svgDoc;
        }

        /// <summary>
        /// Exports the chart to the specified HttpResponse object. This method
        /// is preferred over WriteToStream() because it handles clearing the
        /// output stream and setting the HTTP reponse headers.
        /// </summary>
        /// <param name="httpResponse"></param>
        internal void WriteToHttpResponse(HttpResponse httpResponse)
        {
            httpResponse.ClearContent();
            httpResponse.ClearHeaders();
            httpResponse.ContentType = this.ContentType;
            httpResponse.AddHeader("Content-Disposition", this.ContentDisposition);
            WriteToStream(httpResponse.OutputStream);
        }

        /// <summary>
        ///  导出
        /// </summary>
        /// <param name="outputStream"></param>
        /// <returns>文件扩展名 和 ContentType</returns>
        internal ExportFileInfo WriteToStream(Stream outputStream)
        {
            ExportFileInfo fi = new ExportFileInfo(); 

            string[] fileExtenContentType = new string[2];
            
            switch (this.ContentType)
            {
                case "image/jpeg":
                    CreateSvgDocument().Draw().Save(
                      outputStream,
                      ImageFormat.Jpeg);
                    fi.Extension    = "jpg";
                    fi.ContentType  = "image/jpeg";
                    break;

                case "image/png":
                    // PNG output requires a seekable stream.
                    using (MemoryStream seekableStream = new MemoryStream())
                    {
                        CreateSvgDocument().Draw().Save(
                            seekableStream,
                            ImageFormat.Png);
                        seekableStream.WriteTo(outputStream);
                    }
                    fi.Extension   = "png";
                    fi.ContentType = "image/png";
                    break;

                case "application/pdf":
                    SvgDocument svgDoc = CreateSvgDocument();
                    Bitmap bmp = svgDoc.Draw();

                    pdfDocument doc = new pdfDocument(this.Name, null);
                    pdfPage page = doc.addPage(bmp.Height, bmp.Width);
                    page.addImage(bmp, 0, 0);
                    doc.createPDF(outputStream);
                    fi.Extension    = "pdf";
                    fi.ContentType  = "application/pdf";
                    break;

                case "image/svg+xml":
                    using (StreamWriter writer = new StreamWriter(outputStream))
                    {
                        writer.Write(this.Svg);
                        writer.Flush();
                    }
                    fi.Extension    = "svg";
                    fi.ContentType  = "image/svg";
                    break;

                default:
                    throw new InvalidOperationException(string.Format(
                      "ContentType ‘{0}‘ is invalid.", this.ContentType));
            } 

            return fi;
        }

        /// <summary>
        ///  导出
        /// </summary>
        /// <param name="ExportFileInfo">文件信息</param>
        /// <returns>图片字节数组</returns>
        internal byte[] WriteToBuffer(out ExportFileInfo fi)
        {
            fi = new ExportFileInfo();
            byte[] buffer = null;
            int length = -1;
            // File(buffer, fileExtenContentType[1], fileName);

            string[] fileExtenContentType = new string[2];

            switch (this.ContentType)
            {
                case "image/jpeg":
                    using (MemoryStream seekableStream = new MemoryStream())
                    {
                        Bitmap bmp = CreateSvgDocument().Draw();
                        bmp.Save(
                           seekableStream,
                           ImageFormat.Jpeg);
                        buffer = seekableStream.GetBuffer();
                    }
                    fi.Extension    = "jpg";
                    fi.ContentType  = "image/jpeg";
                    break;

                case "image/png":
                     
                    // PNG output requires a seekable stream.
                    using (MemoryStream seekableStream = new MemoryStream())
                    {
                        CreateSvgDocument().Draw().Save(
                            seekableStream,
                            ImageFormat.Png);
                        buffer = seekableStream.GetBuffer();
                    }
                    fi.Extension    = "png"

以上是关于highcharts 导出图片 .net Demo的主要内容,如果未能解决你的问题,请参考以下文章

highchart不依赖插件的图表导出

highCharts 转svg 导出excel

Python使用Flask框架,结合Highchart,自定义导出菜单项目及顺序

简易的highcharts公共绘图模块封装--基于.net mvc

在.NET MVC 中使用Highcharts+Ajax+Json生成动态曲线图,柱状图,饼图

highcharts stockchart 怎么设置图例,