注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭州 QA Team

务实 专注 分享 做有态度的QA

 
 
 
 
 

日志

 
 

如何在邮件中显示HighCharts渲染的图片  

来自陈亮   2015-02-11 17:31:34|  分类: 质量保障平台 |举报 |字号 订阅

  下载LOFTER 我的照片书  |
【问题背景】
测试人员提出QMS平台支持质量报告的web页面以邮件形式发送的功能。但存在一个问题:在web页面中的所有饼图和柱状图等都是用HighCharts来实现的,但在邮件环境中是不支持HighCharts图片的显示。那么,这个问题该如何破解?

【解决思路】
首先想到的是能找到一个HighCharts的接口,可以将highcharts对象直接转为图片后,直接在邮件视图中引进即可。但受挫,HighCharts没有提供类似接口。于是掉头考虑将highcharts绘制的svg图片转为png图片,终于在无尽的黑夜之中发现了点点繁星,发现可以在浏览器端将svg和canvas结合起来转成以base64编码的png文件,再将该文件转为(解码)blob对象(本质是二进制数据流); 最后将该blob对象通过ajax技术回传给服务器,在服务器侧将blob对象转为png图片即可。发送邮件时只需将该图片以附件形式发送即可(当然你也可以将图片保存在自己的文件系统中,邮件中直接引入超链接就可以)。

这里有一个核心问题:如何将svg转成png?
解决方案:经过调研发现了一个叫canvg的库有如此功能,如获至宝!
该js库文档有一句:Allows for SVG -> Canvas -> png transition all on the client side(through toDataUrl)
它让svg转png的需求得以实现。
用法:

//需要引入以下三个js库:
<script type="text/javascript" src="http://gabelerner.github.io/canvg/rgbcolor.js"></script>
<script type="text/javascript" src="http://gabelerner.github.io/canvg/StackBlur.js"></script>
<script type="text/javascript" src="http://gabelerner.github.io/canvg/canvg.js"></script>

//调用canvg函数将svg渲染到canvas上:
window.canvg(canvas, svg); //render the svg on the canvas


实现原理
如何在邮件中显示web页面的HighCharts图片 - 网易杭州QA - 网易杭州 QA Team

实现浏览器侧获取blob对象的代码:

//get the highcharts id
$(".chart_object_div").each(function(){
chart = $(this).html();
});

chart_object = $(chart).highcharts(); //get highcharts object
svg = chart_object.getSVG(); //get svg string
canvas = document.createElement('canvas'); //create a empty canvas
window.canvg(canvas, svg); //render the svg on the canvas
dataURL = canvas.toDataURL('image/png'); //convert canvas to base64 data

//dataURLtoBlob is for Convert dataURL to Blob object
var image_blob= dataURLtoBlob(dataURL);

// Create new form data
var fd = new FormData();

// Append our Canvas image file to the form data
fd.append(chart_id, image_blob)

//send blob object to /versions/save_image
$.ajax({
url: "/versions/save_image",
type: "POST",
data: fd,
processData: false,
contentType: false,
});

实现服务器侧邮件中图片显示的代码:

// convert blob object to png file in Controller
png_file = "#{Rails.root}/public/email_images/#{params[key]}" + ".png"
File.open(png_file, 'wb') do |f|
f.write(params[key].read)
end

//attach the png file in Mailer
attachments.inline[filename] = File.read(file)

//add image link in mail view
<% inline_image = filename%>
<%= image_tag( attachments.inline[inline_image].url ) %>


【Tips】
rails项目中邮件功能的3个要点:
1. 不要企图复用针对网页浏览的视图,不同的邮件客户端对html的支持是不同的,否则会导致样式显示错误;
2. 不要企图在邮件视图中调用含cookies或session的helper, Mailer环境是没有cookies和session的,建议所有值都从外边的controller传到mailer中;
3. 如果需要使用ActiveMailer功能,强烈建议先将Rails升级到4.1以上。否则,呵.....呵....,闭上眼睛调试代码会是什么感觉?只能"享受"没有错误log靠直觉来定位问题所在了。

【参考文档】
http://www.highcharts.com/docs/export-module/export-module-overview
https://github.com/gabelerner/canvg
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/exporting/offline-download/
http://www.hcharts.cn/api/index.php#Chart.getSVG
http://rohitrox.github.io/2013/07/19/canvas-images-and-rails/
  评论这张
 
阅读(1460)| 评论(3)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016