.Net 使用HighCharts 導入圖片到Excel

来源:https://www.cnblogs.com/Richet/archive/2018/07/26/9371295.html
-Advertisement-
Play Games

優化HighCharts 利用svg導出圖片到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 

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前的文章記述了 "從ASP.NET Core Module到KestrelServer" 的請求處理過程。現在該聊聊如何生成ASP.NET中我們所熟悉的HttpContext。 當KestrelServer啟動時,會綁定相應的IP地址,同時在綁定時將加入HttpConnectionMiddlewa ...
  • 1,2選取目標站點,然後3的高級設置,4啟用32位的應用程式的屬性變為true就可以了。當然,網路上還有其他的版本,你也可以嘗試下。 原文地址:http://weblogs.asp.net/kencox/archive/2010/05/20/asp-net-iis-fix-the-microsoft ...
  • 我想也許要寫些東西,記錄我做程式員的日子吧 要講到C#源碼的執行過程 首先要提下程式集,因為Clr並不是和托管摸塊打交道的,而是和程式集(dll,exe) 1、從哪裡來 程式集是由一個或者多個托管模塊以及 資源文件等共同組成的,C#編譯器(csc.exe)再把源碼編程成IL代碼和元數據的時候,會進一 ...
  • 大家好,今天又想到需要寫一下博客了,畢竟感覺應該在新人入公司的時候可能需要將你電腦上的開發環境進行修改。 下麵講的主要是將VS2012卸載後,重新安裝VS2010,。 我遇到了這種情況:在我將VS2012卸載完後。發現在網上下載VS2010的安裝包下載完成後,進行安裝,發現在安裝完成之後,自己沒有的 ...
  • 從入職到準備離開兩年多了,兩年的時間不長也不斷,各種原因,決定離開了。 挺捨不得這群小伙伴,帶了一個項目組兩年了,不得不走了,感情的牌就不打了。 記得從入職時,公司研發的源碼管理工具使用的SVN,其實SVN也是非常不錯的中心式源碼管理工具,不過一個項目的解決方案,達到了2G到30G,個人感覺比較混亂 ...
  • 控制器代碼: public string ValidateCarID(string carid) { string result; Car car = db.Car.Find(carid); if(car==null) { result = "false"; //沒有找到 } else { resu ...
  • 客戶機上基於Oracle 9i的ODBC數據源,無法連接oracle 11G資料庫,提示錯誤為:error ORA-01017, Invalid Username / Password。奇怪的是:sqlplus能連接成功;且基於Oracle 10G的ODBC數據源也能連接成功。 解決方法:以DBA進 ...
  • unity中播放視頻步驟如下: 1.將要播放的視頻拖入projec。(註意:unity一般支持的視頻格式有mov, .mpg, .mpeg, .mp4,.avi, .asf格式 ) 2.在場景中添加RawImage。(因為Image使用sprite渲染,rawImage是用texture渲染) 3. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...