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

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

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

        

 
明显可以看出,差别很大,无法达到要求,
实现此所采用的代码:

 var doc = new SvgDocument();
XmlDocument xml = new XmlDocument();
xml.LoadXml(this.chart_Hidden.Value);
doc = SvgDocument.Open(xml);
Bitmap mapImage = doc.Draw();
byte[] buffer = NPOIExportExcelHelp.BitmapToBytes(mapImage);
int pictureIdx = workBook.AddPicture(buffer, PictureType.JPEG);
HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(, , , , , , , );
HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
pict.Resize();

优化方案:

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()方法的优化改造,优化图片的格式,
 /// <summary>
/// Creates an SvgDocument from the SVG text string.
/// </summary>
/// <returns>An SvgDocument object.</returns>
private SvgDocument CreateSvgDocument()
{
SvgDocument svgDoc;
XmlDocument xml = new XmlDocument();
xml.LoadXml(this.Svg);
XmlNodeList nodeListAllg = xml.GetElementsByTagName("g");
Dictionary<int, XmlNode[,]> dic = new Dictionary<int, XmlNode[,]>();
int i = ;
foreach (XmlNode xNod in nodeListAllg)
{
i++;
XmlNode xmlvisibility = xNod.Attributes.GetNamedItem("class");
if (xmlvisibility != null && xmlvisibility.Value == "highcharts-series-group")
{
foreach (XmlNode xNod2 in xNod.ChildNodes)
{
i++;
XmlNode xmlvisibility1 = xNod2.Attributes.GetNamedItem("visibility");
if (xmlvisibility1 != null && xmlvisibility1.Value == "hidden")
{
XmlNode[,] xmln = new XmlNode[, ];
xmln[, ] = xNod;
xmln[, ] = xNod2;
dic.Add(i, xmln);
}
}
}
else if (xmlvisibility != null && xmlvisibility.Value == "highcharts-tooltip")
{
XmlNode[,] xmln = new XmlNode[, ];
xmln[, ] = xml.FirstChild;
xmln[, ] = xNod;
dic.Add(i, xmln);
}
}
foreach (KeyValuePair<int, XmlNode[,]> a in dic)
{
a.Value[, ].RemoveChild(a.Value[, ]);
}
this.Svg = xml.OuterXml;
// Create a MemoryStream from SVG string.
using (MemoryStream streamSvg = new MemoryStream(
Encoding.UTF8.GetBytes(this.Svg)))
{
// Create and return SvgDocument from stream.
svgDoc = SvgDocument.Open(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;
}
 
3 利用第二步的方法,基本可以满足要求,生成的Exce图片效果如下
4 将以上方法整理封装成类库
 public class HightChartExport
{
/// <summary>
/// 获取svg图片buffer,用于excel
/// </summary>
/// <param name="svgHtml"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <returns></returns>
public static byte[] GetSvgDocumentByte(string svgHtml, int width, int height)
{
try
{
if (string.IsNullOrEmpty(svgHtml))
{
return new byte[];
}
if (width == || height == )
{
return new byte[];
}
SvgDocument svgDocument = CreateSvgDocument(svgHtml, width, height);
return BitmapToBytes(svgDocument.Draw());
}
catch
{
throw new Exception();
}
}
private static SvgDocument CreateSvgDocument(string svgHtml, int width, int height)
{
SvgDocument svgDoc;
XmlDocument xml = new XmlDocument();
xml.LoadXml(svgHtml);
XmlNodeList nodeListAllg = xml.GetElementsByTagName("g");
Dictionary<int, XmlNode[,]> dic = new Dictionary<int, XmlNode[,]>();
int i = ;
foreach (XmlNode xNod in nodeListAllg)
{
i++;
XmlNode xmlvisibility = xNod.Attributes.GetNamedItem("class");
if (xmlvisibility != null && xmlvisibility.Value == "highcharts-series-group")
{
foreach (XmlNode xNod2 in xNod.ChildNodes)
{
i++;
XmlNode xmlvisibility1 = xNod2.Attributes.GetNamedItem("visibility");
if (xmlvisibility1 != null && xmlvisibility1.Value == "hidden")
{
XmlNode[,] xmln = new XmlNode[, ];
xmln[, ] = xNod;
xmln[, ] = xNod2;
dic.Add(i, xmln);
}
}
}
else if (xmlvisibility != null && xmlvisibility.Value == "highcharts-tooltip")
{
XmlNode[,] xmln = new XmlNode[, ];
xmln[, ] = xml.FirstChild;
xmln[, ] = xNod;
dic.Add(i, xmln);
}
}
foreach (KeyValuePair<int, XmlNode[,]> a in dic)
{
a.Value[, ].RemoveChild(a.Value[, ]);
}
svgHtml = xml.OuterXml;
// Create a MemoryStream from SVG string.
using (MemoryStream streamSvg = new MemoryStream(
Encoding.UTF8.GetBytes(svgHtml)))
{
// Create and return SvgDocument from stream.
svgDoc = SvgDocument.Open<SvgDocument>(streamSvg);
}
// Scale SVG document to requested width.
svgDoc.Transforms = new SvgTransformCollection();
float scalar = (float)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>
/// 读取图片
/// </summary>
/// <param name="Bitmap"></param>
/// <returns></returns>
private static byte[] BitmapToBytes(Bitmap Bitmap)
{
MemoryStream ms = null;
try
{
ms = new MemoryStream();
Bitmap.Save(ms, ImageFormat.Png);
byte[] byteImage = new Byte[ms.Length];
byteImage = ms.ToArray();
return byteImage;
}
catch (ArgumentNullException ex)
{
throw ex;
}
finally
{
ms.Close();
}
}
}

5 调用方法如下:

 byte[] buffer = HightChartExport.GetSvgDocumentByte(this.chart_Pie.Value, Convert.ToInt32(chart_width.Value), Convert.ToInt32(chart_height.Value));
int pictureIdx = workBook.AddPicture(buffer, PictureType.PNG);
HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(, , , , , rowIndex + , , );
HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
pict.Resize();

参考文章

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

https://jucelin.com/highcharts_esport_net.html

 

.Net 使用HighCharts 导入图片到Excel的更多相关文章

  1. FastStone+ImageReady+Kutools plus导入图片到Excel单元格

    先前打算自己做一个也附带训练下,发现有下面方法也好. 1)做帮助文档时需要一种格式(需要将图片导入到Excel中时,假如是按此法归类汇总) 2)FastStone滚动截图       粘贴到Photo ...

  2. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续2篇-模板导出综合示例)

    自ExcelUtility类推出以来,经过项目中的实际使用与不断完善,现在又做了许多的优化并增加了许多的功能,本篇不再讲述原理,直接贴出示例代码以及相关的模板.结果图,以便大家快速掌握,另外这些示例说 ...

  3. [转]Java中导入、导出Excel

    原文地址:http://blog.csdn.net/jerehedu/article/details/45195359 一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样 ...

  4. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续3篇-导出时动态生成多Sheet EXCEL)

    ExcelUtility 类库经过我(梦在旅途)近期不断的优化与新增功能,现已基本趋向稳定,功能上也基本可以满足绝大部份的EXCEL导出需求,该类库已在我们公司大型ERP系统全面使用,效果不错,今天应 ...

  5. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续篇)

    上周六我发表的文章<分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility>受到了大家的热烈支持与推荐,再此表示感谢,该ExcelUtility ...

  6. 用javascript协助导入图片

    用javascript协助导入图片 需求 先说说需求.春节回家见爸妈,老爸迷上了摄影.他把平时的照片都上传到了 成都图片网, 这个成都图片网专门有一个 "快拍成都" 的版块,用于大 ...

  7. Java的导入与导出Excel

    使用Jakarta POI导入.导出Excel Jakarta POI 是一套用于访问微软格式文档的Java API.Jakarta POI有很多组件组成,其中有用于操作Excel格式文件的HSSF和 ...

  8. (转载)SQL中导入图片

    SQL中导入图片 分类: 论坛精贴 2006-05-10 12:07 398人阅读 评论(0) 收藏 举报 sqlimage服务器insertlogingo 1.建立过程CREATE PROCEDUR ...

  9. 有关ios中images.xcassets的导入图片等命名问题

    最近遇到一个问题,就是在设置启动图片的时候,把启动图片命名设置为了xxx@2x.png, 然后应用死活没有显示启动图片,调试了很久,才发现是因为文件命名的原因. 1. 如果在图片的下方有2x或3x的标 ...

随机推荐

  1. 20165233 Java第七、十章学习总结

    20165233 2017-2018-2 <Java程序设计>第五周学习总结 教材学习内容总结 ch07 内部类:Java支持在一个类中声明另一个类,这样的类称为内部类,而包含内部类的类称 ...

  2. html链接路径

    html链接的相对路径与绝对路径 绝对路径 完整的一个路径就是绝对路径,即包含schema://host[:port#]/path/.../[?query-string][#anchor] 例:htt ...

  3. 关于常见的协议BSD,APACHE,MIT,GPL的理解

    其实BSD和APACHE和MIT协议类似,基本就是可以为所欲为,但是要尊重原来的作者. GPL协议是一个免费和开源的协议,只要用了GPL协议的类库源码等,也必须适应GPL协议. 意思就是把开源和免费进 ...

  4. TCP/IP知识总结(TCP/IP协议族读书笔记一)

    一.简述TCP/IP协议 Transmission Control Protocol/Internet Protocol的简写,即传输控制协议/互联网互联协议,又名网络通信协议.是Internet最基 ...

  5. JS nodeJs 的日期计算

    目录[-] date-utils Static Methods 静态方法 Instance Methods 接口方法 date-utils 前端引用 <script type="tex ...

  6. confd test

    vi /etc/confd/confd.toml backend = "consul"confdir = "/etc/confd"log-level = &qu ...

  7. binary tree

    一.中序线索化 二叉树节点定义: class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; int isle ...

  8. SpringBoot进行单元测试

    SpringBoot进行单元测试,需要在maven中加入以下依赖 <dependency> <groupId>org.springframework.boot</grou ...

  9. 今天无意中发现的WWW.threadPriority

    WWW.threadPriority     Description Priority of AssetBundle decompression thread. You can control dec ...

  10. springMVC入门程序。使用springmvc实现商品列表的展示。

    1.1 开发环境 本教程使用环境: Jdk:jdk1.7.0_72 Eclipse:mars Tomcat:apache-tomcat-7.0.53 Springmvc:4.1.3 1.2 需求 使用 ...