赞
踩
下载地址:Download PhantomJS
下载完成后解压
tar -xjvf phantomjs-2.1.1-linux-x86_64.tar.bz2
将可执行文件放入系统路径,并进行连接(必须是全路径)
sudo ln -s home/software/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs
授权
chmod 777 phantomjs
测试Phantomjs
1. echarts.min.js
下载地址:https://echarts.baidu.com/download.html
下载最新的 release 版本,解压出来的文件夹里的 dist 目录里可以找到最新版本的 echarts 库。
2. jquery-3.2.1.min.js
我用了3.2.1这个版本,具体版本没有限制。
3. echarts-convert.js
- (function () {
- var system = require('system');
- var fs = require('fs');
- var config = {
- // define the location of js files
- JQUERY: 'jquery-3.2.1.min.js',
- //ESL: 'esl.js',
- ECHARTS: 'echarts.min.js',
- // default container width and height
- DEFAULT_WIDTH: '600',
- DEFAULT_HEIGHT: '700'
- }, parseParams, render, pick, usage;
-
- usage = function () {
- console.log("\nUsage: phantomjs echarts-convert.js -options options -outfile filename -width width -height height"
- + "OR"
- + "Usage: phantomjs echarts-convert.js -infile URL -outfile filename -width width -height height\n");
- };
-
- pick = function () {
- var args = arguments, i, arg, length = args.length;
- for (i = 0; i < length; i += 1) {
- arg = args[i];
- if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') {
- return arg;
- }
- }
- };
-
- parseParams = function () {
- var map = {}, i, key;
- if (system.args.length < 2) {
- usage();
- phantom.exit();
- }
- for (i = 0; i < system.args.length; i += 1) {
- if (system.args[i].charAt(0) === '-') {
- key = system.args[i].substr(1, i.length);
- if (key === 'infile') {
- // get string from file
- // force translate the key from infile to options.
- key = 'options';
- try {
- map[key] = fs.read(system.args[i + 1]).replace(/^\s+/, '');
- } catch (e) {
- console.log('Error: cannot find file, ' + system.args[i + 1]);
- phantom.exit();
- }
- } else {
- map[key] = system.args[i + 1].replace(/^\s+/, '');
- }
- }
- }
- return map;
- };
-
- render = function (params) {
- var page = require('webpage').create(), createChart;
-
- var bodyMale = config.SVG_MALE;
- page.onConsoleMessage = function (msg) {
- console.log(msg);
- };
-
- page.onAlert = function (msg) {
- console.log(msg);
- };
-
- createChart = function (inputOption, width, height,config) {
- var counter = 0;
- function decrementImgCounter() {
- counter -= 1;
- if (counter < 1) {
- console.log(messages.imagesLoaded);
- }
- }
-
- function loadScript(varStr, codeStr) {
- var script = $('<script>').attr('type', 'text/javascript');
- script.html('var ' + varStr + ' = ' + codeStr);
- document.getElementsByTagName("head")[0].appendChild(script[0]);
- if (window[varStr] !== undefined) {
- console.log('Echarts.' + varStr + ' has been parsed');
- }
- }
-
- function loadImages() {
- var images = $('image'), i, img;
- if (images.length > 0) {
- counter = images.length;
- for (i = 0; i < images.length; i += 1) {
- img = new Image();
- img.onload = img.onerror = decrementImgCounter;
- img.src = images[i].getAttribute('href');
- }
- } else {
- console.log('The images have been loaded');
- }
- }
- // load opitons
- if (inputOption != 'undefined') {
- // parse the options
- loadScript('options', inputOption);
- // disable the animation
- options.animation = false;
- }
-
- // we render the image, so we need set background to white.
- $(document.body).css('backgroundColor', 'white');
- var container = $("<div>").appendTo(document.body);
- container.attr('id', 'container');
- container.css({
- width: width,
- height: height
- });
- // render the chart
- var myChart = echarts.init(container[0]);
- myChart.setOption(options);
- // load images
- loadImages();
- return myChart.getDataURL();
- };
-
- // parse the params
- page.open("about:blank", function (status) {
- // inject the dependency js
- page.injectJs(config.ESL);
- page.injectJs(config.JQUERY);
- page.injectJs(config.ECHARTS);
-
-
- var width = pick(params.width, config.DEFAULT_WIDTH);
- var height = pick(params.height, config.DEFAULT_HEIGHT);
-
- // create the chart
- var base64 = page.evaluate(createChart, params.options, width, height,config);
- fs.write("base64.txt",base64);
- // define the clip-rectangle
- page.clipRect = {
- top: 0,
- left: 0,
- width: width,
-
- height: height
- };
- // render the image
- page.render(params.outfile);
- console.log('render complete:' + params.outfile);
- // exit
- phantom.exit();
- });
- };
- // get the args
- var params = parseParams();
-
- // validate the params
- if (params.options === undefined || params.options.length === 0) {
- console.log("ERROR: No options or infile found.");
- usage();
- phantom.exit();
- }
- // set the default out file
- if (params.outfile === undefined) {
- var tmpDir = fs.workingDirectory + '/tmp';
- // exists tmpDir and is it writable?
- if (!fs.exists(tmpDir)) {
- try {
- fs.makeDirectory(tmpDir);
- } catch (e) {
- console.log('ERROR: Cannot make tmp directory');
- }
- }
- params.outfile = tmpDir + "/" + new Date().getTime() + ".png";
- }
-
- // render the image
- render(params);
- }());
注意:三个脚本放一起
1.安装EChart 依赖
- <dependency>
- <groupId>com.github.abel533</groupId>
- <artifactId>ECharts</artifactId>
- <version>2.2.7</version>
- </dependency>
2.用echarts提供的sdk拼接生成options,并保存json文件到服务器,然后使用Java传cmd命令调用 PhantomJS + EchartsConvert 命令读取json,生成 echarts 图片
- private InputStream createChart() {
- //choList 为List<choList>
- //生成饼图图片
- InputStream pieInputStream = this.createChart(choList,"pie");
- //生成柱状图
- InputStream histogramInputStream = this.createChart(choList,"histogram");
-
- // 发邮件
- String title = "测试邮件" + DateUtils.getDate();
- String from= "ceshifajianren@163.com";
- String user= "ceshifajianren@163.com";
- String emailPassword= "******";
- String fromCNname = "测试管理系统";
- String content = "测试邮件!"
- String[] addrs = {"ceshi@163.com"};
- try {
- SendMail.sendMailImage(from, fromCNname, user, emailPassword, content, title, addrs, "", pieInputStream, histogramInputStream);
- } catch (Exception e) {
- log.error("发送邮件失败--->" + e.getMessage());
- }
- }
- //生成图片
- private InputStream createChart(List<choList> choList,String fileType) {
- String phantomjs = "/home/phantomjs/phantomjs/bin/phantomjs";
- String JSpath = "/home/phantomjs/echartsconvert/convert.js";
- String path = "/home/echartspath/";
- String dateTime = DateUtils.dateTime();
- String jsonfile = dateTime + fileType + ".json";
- String imagefile = dateTime + fileType + ".png";
- String option = "";
- InputStream fileInputStream = null;
- try {
- //生成option
- if("pie".equals(fileType)) {
- option = createPieChartOption(choList);
- }else {
- option = createHistogramOption(choList);
- }
- FtpUtil ftpshell = new FtpUtil("121.1.1.1",22,"ccc","ccc***");
- // option上传
- ftpshell.connect();
- ftpshell.writeContent(option, echartsPath, jsonfile);
- System.out.println("创建option");
- // 生成图片
- ftpshell.sshconnect();
- String cmd = phantomjsPath + " " + echartsconvertPath + " -infile " + echartsPath + jsonfile + " -outfile " + echartsPath + imagefile;
- System.out.println(cmd);
- ftpshell.execShell(cmd);
- //读取图片
- fileInputStream = ftpshell.getsftp(echartsPath + imagefile);
- ftpshell.disConnect();
- } catch (Exception e) {
- log.error("生成图片,读取图片失败--->" + e.getMessage());
- }
- return fileInputStream;
- }
- //生成饼图
- private String createPieChartOption(List<choList> choList) {
- List<Map<String, Object>> list = new ArrayList<>();
- for (choListch : choList) {
- Map<String, Object> map = new HashMap<>();
- map.put("name", ch.getProcorr());
- map.put("value", ch.getStatis());
- list.add(map);
- }
- //创建Option
- Option option = new GsonOption();
- option.title(new Title().text("占比").x("middle"));
- option.tooltip(Trigger.item);
- option.legend(new Legend().orient(Orient.vertical).left("left"));
- //饼图数据
- Pie pie = new Pie("占比");
- //循环数据
- for (Map<String, Object> objectMap : list) {
- //饼图数据
- pie.data(new PieData(objectMap.get("name").toString() + " " + objectMap.get("value"), objectMap.get("value")));
- }
- //设置数据
- option.series(pie);
- String optionStr = option.toString().replace(" ", "");
- return optionStr;
- }
- //生成柱状图
- private String createHistogramOption(List<choList> choList) {
- String[] colors = { "#546fc6", "#91cb74",
- "#fac859", "#ee6666", "#73c0de",
- "#3ba372", "#fb8351", "#9a60b4"};
- List<Map<String, Object>> list = new ArrayList<>();
- for (choListch : choList) {
- Map<String, Object> map = new HashMap<>();
- map.put("name", ch.getProcorr()); //人名
- map.put("value", ch.getStatis()); //数量
- map.put("itemStyle",
- new ItemStyle().normal(new Normal().color(colors[new Random().nextInt(8)])));
- list.add(map);
- }
- //创建Option
- Option option = new GsonOption();
- option.title(new Title().text("统计").x("middle"));
- option.tooltip(Trigger.item);
- option.legend(new Legend().orient(Orient.vertical).left("left"));//设置布局方式
-
- //设置x轴数据
- CategoryAxis categoryAxis = new CategoryAxis();
- for (Changeorder ch : choList) {
- categoryAxis.data(ch.getProcorr());
- }
- option.xAxis(categoryAxis);
-
- //设置y轴 这里不给指定数据 自动调整
- ValueAxis valueAxis = new ValueAxis();
- option.yAxis(valueAxis);
-
- //填充柱状图数据
- Bar bar = new Bar("统计");
- //循环数据
- for (Map<String, Object> objectMap : list) {
- bar.data(objectMap);
- }
- //设置顶端显示数值
- bar.setLabel(new ItemStyle().normal(new Normal().show(true).position(Position.top)));
- //设置数据
- option.series(bar);
- String optionStr = option.toString().replace(" ", "");
- return optionStr;
- }
3. 发送邮件
- public static boolean sendMailImage(String from, String fromCNname,String user, String password, String text, String title, String[] addrs, String recipient, InputStream pieImageInputStream, InputStream histogramImageInputStream) throws Exception {
- // 1.创建参数配置, 用于连接邮件服务器的参数配置
- Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
- final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
- Properties props = System.getProperties();
- props.setProperty("mail.smtp.host", mailHost);
- props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
- props.setProperty("mail.smtp.socketFactory.fallback", "false");
- props.setProperty("mail.smtp.port", "465");
- props.setProperty("mail.smtp.socketFactory.port", "465");
- props.put("mail.smtp.auth", "true");
- // 2. 根据配置创建会话对象, 用于和邮件服务器交互,不要用defaultInstance!!!!!!
- Session session = Session.getInstance(props, new Authenticator() {
- @Override
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(user, password);
- }
- });
- session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log
- // -- Create a new message -- 1. 创建一封邮件
- Message msg = new MimeMessage(session);
- // -- Set the FROM and TO fields --
- String nick = javax.mail.internet.MimeUtility.encodeText(fromCNname); //设置发件人中文名称 ***<213321@163.com>
- msg.setFrom(new InternetAddress(nick+" <"+from+">"));
- // msg.setFrom(new InternetAddress(from));
- InternetAddress[] toAddrs = new InternetAddress[addrs.length];
- if (StringUtils.isNotBlank(recipient)) {
- InternetAddress reciAddr = new InternetAddress(recipient); //抄送
- msg.setRecipient(Message.RecipientType.CC, reciAddr);
- }
- for (int i = 0; i < toAddrs.length; i++) {
- toAddrs[i] = new InternetAddress(addrs[i]);
- }
- msg.setRecipients(Message.RecipientType.TO, toAddrs);
- msg.setSubject(title);
-
- //创建富文本对象
- BodyPart mdp = new MimeBodyPart();//新建一个存放信件内容的BodyPart对象
- mdp.setContent(text, "text/html;charset=utf-8");//给BodyPart对象设置内容和格式/编码方式
-
- MimeMultipart mm = new MimeMultipart();//新建一个多功能邮件块对象用来存放BodyPart对象
- mm.addBodyPart(mdp);//将BodyPart加入到MimeMultipart对象中(可以加入多个BodyPart)
- mm.addBodyPart(createImageMimeBodyPart(pieImage)); //将图片插入MimeMultipart对象中
- mm.addBodyPart(createImageMimeBodyPart(histogramImage)); //将图片插入MimeMultipart对象中
- /**
- * mixed:混合关系,一般正文和附件组合使用mixed,如果不设置,javamail默认会使用mixed
- * related:关联关系,一般html引用了图片这类内嵌资源,正文和图片组合使用related
- * alternative:同时存在纯文本与超文本,使用boundary分割
- */
- mm.setSubType("related");
-
- //将封装好的数据保存到Message中
- msg.setContent(mm);
- msg.setSentDate(new Date());
-
- // Transport.send(msg);
- System.out.println("Message sent.");
- return true;
- }
-
- // 封装图片MimeBodyPart
- private static MimeBodyPart createImageMimeBodyPart(InputStream imageInputStream) throws Exception {
- MimeBodyPart image = new MimeBodyPart();
- image.setDataHandler(new DataHandler(new ByteArrayDataSource(imageInputStream, "application/octet-stream"))); //javamail jaf
- image.setContentID(IdUtils.fastSimpleUUID());//设置对应资源文件的唯一标识符,即MIME协议对于邮件得结构组织格式中得content-id头字段
- return image;
- }
(使用-options不能生成图片,只能使用-infile,指定json文件全目录,原因未知)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。