• .Net 使用HighCharts 导入图片到Excel


    需求:数据统计报表使用到HighCharts显示各种图形:柱状图,饼图,点阵图等等,需要将数据表以及对应的图像导入到Excel中,方便打印。

    解决方法: Excel导出采用NPOI,HighChart图像利用svg将图片写入到Excel中。

    遇到的问题:图片模糊,图片清晰度与web页面相比差距很大。

    导出Excel显示图片        web显示图片

     
    明显可以看出,差别很大,无法达到要求,
    实现此所采用的代码:
     1 var doc = new SvgDocument();
     2             XmlDocument xml = new XmlDocument();
     3             xml.LoadXml(this.chart_Hidden.Value);
     4             doc = SvgDocument.Open(xml);
     5             Bitmap mapImage = doc.Draw();
     6             byte[] buffer = NPOIExportExcelHelp.BitmapToBytes(mapImage);
     7             int pictureIdx = workBook.AddPicture(buffer, PictureType.JPEG);
     8             HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
     9             HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, 7, 0, 7,  15);
    10             HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
    11             pict.Resize();
    View Code

     优化方案:

    1 下载开源的.net导出文件: https://github.com/imclem/Highcharts-export-module-asp.net

       利用此项目中的dll文件:itextsharp.dll,sharpPDF.dll,Svg.dll

    2   借鉴文章:https://jucelin.com/highcharts_esport_net.html  中针对于CreateSvgDocument()方法的优化改造,优化图片的格式,
     1 /// <summary>
     2         /// Creates an SvgDocument from the SVG text string.
     3         /// </summary>
     4         /// <returns>An SvgDocument object.</returns>
     5         private SvgDocument CreateSvgDocument()
     6         {
     7             SvgDocument svgDoc;
     8             XmlDocument xml = new XmlDocument();
     9             xml.LoadXml(this.Svg);
    10             XmlNodeList nodeListAllg = xml.GetElementsByTagName("g");
    11             Dictionary<int, XmlNode[,]> dic = new Dictionary<int, XmlNode[,]>();
    12             int i = 0;
    13             foreach (XmlNode xNod in nodeListAllg)
    14             {
    15                 i++;
    16                 XmlNode xmlvisibility = xNod.Attributes.GetNamedItem("class");
    17                 if (xmlvisibility != null && xmlvisibility.Value == "highcharts-series-group")
    18                 {
    19                     foreach (XmlNode xNod2 in xNod.ChildNodes)
    20                     {
    21                         i++;
    22                         XmlNode xmlvisibility1 = xNod2.Attributes.GetNamedItem("visibility");
    23                         if (xmlvisibility1 != null && xmlvisibility1.Value == "hidden")
    24                         {
    25                             XmlNode[,] xmln = new XmlNode[1, 2];
    26                             xmln[0, 0] = xNod;
    27                             xmln[0, 1] = xNod2;
    28                             dic.Add(i, xmln);
    29                         }
    30                     }
    31                 }
    32                 else if (xmlvisibility != null && xmlvisibility.Value == "highcharts-tooltip")
    33                 {
    34                     XmlNode[,] xmln = new XmlNode[1, 2];
    35                     xmln[0, 0] = xml.FirstChild;
    36                     xmln[0, 1] = xNod;
    37                     dic.Add(i, xmln);
    38                 }
    39             }
    40             foreach (KeyValuePair<int, XmlNode[,]> a in dic)
    41             {
    42                 a.Value[0, 0].RemoveChild(a.Value[0, 1]);
    43             }
    44             this.Svg = xml.OuterXml;
    45             // Create a MemoryStream from SVG string.
    46             using (MemoryStream streamSvg = new MemoryStream(
    47               Encoding.UTF8.GetBytes(this.Svg)))
    48             {
    49                 // Create and return SvgDocument from stream.
    50                 svgDoc = SvgDocument.Open(streamSvg);
    51             }
    52             // Scale SVG document to requested width.
    53             svgDoc.Transforms = new SvgTransformCollection();
    54             float scalar = (float)this.Width / (float)svgDoc.Width;
    55             svgDoc.Transforms.Add(new SvgScale(scalar, scalar));
    56             svgDoc.Width = new SvgUnit(svgDoc.Width.Type, svgDoc.Width * scalar);
    57             svgDoc.Height = new SvgUnit(svgDoc.Height.Type, svgDoc.Height * scalar);
    58             return svgDoc;
    59         }
    View Code
     
    3 利用第二步的方法,基本可以满足要求,生成的Exce图片效果如下
    4 将以上方法整理封装成类库
      1 public class HightChartExport
      2     {
      3         /// <summary>
      4         /// 获取svg图片buffer,用于excel
      5         /// </summary>
      6         /// <param name="svgHtml"></param>
      7         /// <param name="width"></param>
      8         /// <param name="height"></param>
      9         /// <returns></returns>
     10         public static byte[] GetSvgDocumentByte(string svgHtml, int width, int height)
     11         {
     12             try
     13             {
     14                 if (string.IsNullOrEmpty(svgHtml))
     15                 {
     16                     return new byte[0];
     17                 }
     18                 if (width == 0 || height == 0)
     19                 {
     20                     return new byte[0];
     21                 }
     22                 SvgDocument svgDocument = CreateSvgDocument(svgHtml, width, height);
     23                 return BitmapToBytes(svgDocument.Draw());
     24             }
     25             catch
     26             {
     27                 throw new Exception();
     28             }
     29         }
     30         private static SvgDocument CreateSvgDocument(string svgHtml, int width, int height)
     31         {
     32             SvgDocument svgDoc;
     33             XmlDocument xml = new XmlDocument();
     34             xml.LoadXml(svgHtml);
     35             XmlNodeList nodeListAllg = xml.GetElementsByTagName("g");
     36             Dictionary<int, XmlNode[,]> dic = new Dictionary<int, XmlNode[,]>();
     37             int i = 0;
     38             foreach (XmlNode xNod in nodeListAllg)
     39             {
     40                 i++;
     41                 XmlNode xmlvisibility = xNod.Attributes.GetNamedItem("class");
     42                 if (xmlvisibility != null && xmlvisibility.Value == "highcharts-series-group")
     43                 {
     44                     foreach (XmlNode xNod2 in xNod.ChildNodes)
     45                     {
     46                         i++;
     47                         XmlNode xmlvisibility1 = xNod2.Attributes.GetNamedItem("visibility");
     48                         if (xmlvisibility1 != null && xmlvisibility1.Value == "hidden")
     49                         {
     50                             XmlNode[,] xmln = new XmlNode[1, 2];
     51                             xmln[0, 0] = xNod;
     52                             xmln[0, 1] = xNod2;
     53                             dic.Add(i, xmln);
     54                         }
     55                     }
     56                 }
     57                 else if (xmlvisibility != null && xmlvisibility.Value == "highcharts-tooltip")
     58                 {
     59                     XmlNode[,] xmln = new XmlNode[1, 2];
     60                     xmln[0, 0] = xml.FirstChild;
     61                     xmln[0, 1] = xNod;
     62                     dic.Add(i, xmln);
     63                 }
     64             }
     65             foreach (KeyValuePair<int, XmlNode[,]> a in dic)
     66             {
     67                 a.Value[0, 0].RemoveChild(a.Value[0, 1]);
     68             }
     69             svgHtml = xml.OuterXml;
     70             // Create a MemoryStream from SVG string.
     71             using (MemoryStream streamSvg = new MemoryStream(
     72               Encoding.UTF8.GetBytes(svgHtml)))
     73             {
     74                 // Create and return SvgDocument from stream.
     75                 svgDoc = SvgDocument.Open<SvgDocument>(streamSvg);
     76             }
     77             // Scale SVG document to requested width.
     78             svgDoc.Transforms = new SvgTransformCollection();
     79             float scalar = (float)width / (float)svgDoc.Width;
     80             svgDoc.Transforms.Add(new SvgScale(scalar, scalar));
     81             svgDoc.Width = new SvgUnit(svgDoc.Width.Type, svgDoc.Width * scalar);
     82             svgDoc.Height = new SvgUnit(svgDoc.Height.Type, svgDoc.Height * scalar);
     83             return svgDoc;
     84         }
     85         /// <summary>
     86         /// 读取图片
     87         /// </summary>
     88         /// <param name="Bitmap"></param>
     89         /// <returns></returns>
     90         private static byte[] BitmapToBytes(Bitmap Bitmap)
     91         {
     92             MemoryStream ms = null;
     93             try
     94             {
     95                 ms = new MemoryStream();
     96                 Bitmap.Save(ms, ImageFormat.Png);
     97                 byte[] byteImage = new Byte[ms.Length];
     98                 byteImage = ms.ToArray();
     99                 return byteImage;
    100             }
    101             catch (ArgumentNullException ex)
    102             {
    103                 throw ex;
    104             }
    105             finally
    106             {
    107                 ms.Close();
    108             }
    109         }
    110     }
    View Code

    5 调用方法如下:

    1 byte[] buffer = HightChartExport.GetSvgDocumentByte(this.chart_Pie.Value, Convert.ToInt32(chart_width.Value), Convert.ToInt32(chart_height.Value));
    2  int pictureIdx = workBook.AddPicture(buffer, PictureType.PNG);
    3  HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
    4  HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, 0, rowIndex + 1, 0, 15);
    5  HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
    6   pict.Resize();
    View Code

    参考文章

    https://github.com/imclem/Highcharts-export-module-asp.net

    https://jucelin.com/highcharts_esport_net.html 

     
       路曼曼其修远兮,吾将上下而求索
  • 相关阅读:
    吴裕雄 python深度学习与实践(1)
    吴裕雄 python 机器学习-Logistic(1)
    吴裕雄 python 熵权法确定特征权重
    【Uva 1252】Twenty Questions
    【玲珑杯 round#18 B】图论你先敲完模板
    【Uva 10817】Headmaster's Headache
    【玲珑杯 round#18 A】计算几何你瞎暴力
    【Uva 12128】Perfect Service
    【UVa 12186】Another Crisis
    【Uva 10003】Cutting Sticks
  • 原文地址:https://www.cnblogs.com/Richet/p/9371295.html
Copyright © 2020-2023  润新知