在项目中使用Echarts来生成报表,效果不错,之后有个需求要设置定时时间给指定的邮箱发送报表邮件。后台使用JFreeChart生成的话样式不协调,而Echarts需要浏览器内核来执行js,后来尝试过htmlunit,对echarts支持的不是很好,遂放弃了。后来搜索中在一篇博客看到PhantomJs的介绍可以实现上述需求。
PhantomJs是一个无头浏览器,对前端页面支持不错,对于一些需要爬取异步加载的页面很有用。
安装方法网上很多,
#进入/opt目录
cd /opt #下载phantomjs wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 #解压软件压缩包 tar xvf phantomjs-2.1.1-linux-x86_64.tar.bz2# 编辑配置文件.
vim /etc/profile # 将PhantomJS的bin目录加入到PATH环境变量中. export PATH=${PATH}:/opt/phantomjs-2.1.1-linux-x86_64/bin# 退出vi编辑器,使用source命令让刚才的配置即时生效.
source /etc/profile# 测试PhantomJS是否安装成功,如果打出了版本信息,即安装成功.
phantomjs -v#请phantom.js放到/opt目录下
安装完成需要编辑phantomjs脚本,可参考以下脚本:
var system = require('system'); var page = require('webpage').create();
// 如果是windows,设置编码为gbk,防止中文乱码,Linux本身是UTF-8 var osName = system.os.name; if ('windows' === osName.toLowerCase()) { phantom.outputEncoding="gbk"; }
// 获取第二个参数(即请求地址url). var url = system.args[1];
// 显示控制台日志. page.onConsoleMessage = function(msg) { console.log('[' + msg + ']'); };
//打开给定url的页面. page.open(url, function(status) { if (status == 'success') { //console.log('echarts页面加载完成,加载耗时:' + (new Date().getTime() - start) + ' ms'); // 由于echarts动画效果,延迟500毫秒确保图片渲染完毕再调用下载图片方法. console.log("页面加载成功!"); } else { console.log("页面加载失败 Page failed to load!"); } // 10秒后再关闭浏览器. setTimeout(function() { phantom.exit(); }, 10000); });
在刚开始使用时发现没有执行页面JS,将page.content打印才发现访问页面被登陆拦截了。
上传服务器时报错2018-09-21 15:41:29[DEBUG]-[Thread: TP-exec-1]-[org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues()]: Failed to resolve argument 0 of type 'java.lang.String' org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'doc' is not present
后来发现是web容器做了上传限制导致,在tomcat配置中加入maxPostSize="-1"即可
Phantomjs+echarts后台生成报表遇到一个问题生成报表文件的base64编码的URL的图片,体积会100倍,内容里会多出很多个A,在GitHub搜索到类似情况并给出解决方案
https://github.com/ariya/phantomjs/issues/10455
大致因为phantomjs对canvas和png格式不兼容导致,需要明确质量参数
解决方法是修改Echarts源码将echarts中用canvas生成图片的方法指定质量参数0即可解决,类似以下:
varo="svg"===this._zr.painter.getType()?this.getSvgDataUrl():this.getRenderedCanvas(t).toDataURL("image/"+(t&&t.type||"png",0.5));
使用jepg格式可以规避这种问题
myChart.getDataURL({
type:'jpeg',
pixelRatio: 1,
backgroundColor: '#fff'
});
又双叒叕有问题了,线上和仿真渲染出的图片文字模糊一直存在,一直在找phantomjs的问题,想找个替代的方案.今天想到模糊的文字都是没有中文的,然后就想到是系统字体的原因
操作步骤如下:
1.将附件中字体复制到 /usr/share/fonts/zh_CN 目录下
2.对目录授权 #chmod 777 /usr/share/fonts/zh_CN
3.#mkfontscale // 如果提示 mkfontscale: command not found,需自行安装 #yum install mkfontscale
4.#mkfontdir
5.#fc-cache –fv // 刷新内存中的字体缓存
6.#source /etc/profile // 执行以下命令让字体生效