需求:数据统计报表使用到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. c#静态构造函数与构造函数

    构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧. 静态构造函数是在构造函数方法前面添加了stat ...

  2. JSON格式化工具推荐

    JSON以其独特的简洁方便及与Javscript的无缝集成在WEB2.0时瓦风靡全球.   不过做为开发者,当看到一段很长的未格式化的JSON代码时,你会不会感到头晕? {"meta&quo ...

  3. mybatis“$”和“#”

    摘要:$ 是直接拼接# 会转义,更安全 类比Mybatis的执行流程和JDBC原有的我们使用的方法就是:Mybatis: Sqlsession -> Executor -> Stateme ...

  4. python beautifulsoup爬虫

    爬虫这个听起来很 hack 的名字,是我学习 python 的诱因.当 python 基础学习到一定程度(基本语法,数据类型掌握) 就可以开启自己的小爬虫了.毕竟实践才是提高的最快途径.废话说完了,下 ...

  5. Windows下测量cpu利用率的类

    方法参考网上的一段代码,把它改成了类以方便调用,很简单,但是可以一用,哈哈. cpu_usage.h #include <windows.h> class CpuUsage { publi ...

  6. VsCode中vim插件剪切板等问题

    剪切板共享 这个挺重要的,否则每次右键菜单复制粘贴会奔溃的. 在用户设置中添加: "vim.useSystemClipboard": true, 光标的变化 我觉得这个也重要,毕竟 ...

  7. maven settings.xml 文件

    指定jdk 的版本: <profile> <id>jdk-1.8</id> <activation> <activeByDefault>tr ...

  8. leetcode190

    public class Solution { public uint reverseBits(uint n) { var list = new List<uint>();//逆序的二进制 ...

  9. 基于Spring Boot和Spring Cloud实现微服务架构学习

    转载自:http://blog.csdn.net/enweitech/article/details/52582918 看了几周Spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习感 ...

  10. Spring 3.1 entityManagerFactory java.lang.NoSuchFieldError: NULL Error

    This means there is a version mismatch--most likely with spring classes. So make sure all your sprin ...