ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java通过后台导出Echart图片

2021-06-19 13:33:28  阅读:371  来源: 互联网

标签:Java Echart type base64 导出 String series data option


Java通过后台导出Echart图片

一,工具准备

phantomjs

由于Echart图片是通过浏览器的js生成在页面上,因此若不想通过前端生成Echart图片,需要使用其他工具,例如 phantomjs,俗称为:无界面的浏览器。

PhantomJS是一个基于 WebKit 的服务器端JavaScript API。它全面支持web而不需浏览器支持,支持各种Web标准:DOM处理,CSS选择器, JSON,Canvas,和SVG。
PhantomJS常用于页面自动化,网络监测,网页截屏,以及无界面测试等。

通常我们使用PhantomJS作为爬虫工具。传统的爬虫只能单纯地爬取html的代码,对于js渲染的页面,就无法爬取,如Echarts统计图。而PhantomJS正可以解决此类问题。

官网下载http://phantomjs.org/download.html 国内镜像http://npm.taobao.org/dist/phantomjs/

EChartsConvert

echart-convert.js可以配合phantomjs将图片截图下来

下载地址(个人自定义): https://gitee.com/lmchh/echartsconvert

网上地址:https://gitee.com/saintlee/echartsconvert

安装并运行

D:/Java/Echart/phantomjs-2.1.1-windows/bin/phantomjs.exe D:/Java/Echart/echartsconvert/echarts-convert.js -s -p 6666

命令參數:

  • -s: 指通過服務器的方式
  • -p:指定端口後,一般和 -s 一起使用
  • -o:o即option,格式為 {…}
  • -f:輸出路徑
  • -t:圖片類型,有 file/base64 兩種,默認是base64
  • -w:即width,圖片寬度
  • -h:即height,圖片高度

二,所需依赖

		<!--   Echart     -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.9</version>
        </dependency>
		<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

三,实现代码

package com.lmc.excel.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import freemarker.template.TemplateException;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: EchartsUtil
 * @author: Leemon
 * @Description: TODO
 * @date: 2021/6/14 15:43
 * @version: 1.0
 */
public class EchartsUtil {
    /**
     * 临时文件夹路径
     */
    public static final String TEMP_FILE_PATH = "D:/data/echart/";
    private static final String SUCCESS_CODE = "1";

    private static final String path = EchartsUtil.class.getClassLoader().getResource("json").getPath();


    public static void main(String[] args) throws IOException, TemplateException {

        // 获取option字符串
        String option = getStringByFile(path + "/test.json");
        JSONObject object = JSONObject.parseObject(option);
        option = object.toJSONString();

        // 根据option参数,width和height生成base64编码
        String base64 = EchartsUtil.generateEchartsBase64(option, "1360", "800");

        System.out.println("BASE64:" + base64);
        generateImage(base64, TEMP_FILE_PATH, "test.png");

    }


    public static String generateEchartsBase64(String option, String width, String height) throws IOException {
        String base64 = "";
        if (option == null) {
            return base64;
        }
        option = option.replaceAll("\\s+", "");//.replaceAll("\"", "");
        JSONObject object = JSON.parseObject(option);
        object.getJSONArray("series").getJSONObject(0).put("data", Arrays.asList(120, 200, 150, 80, 70, 110, 130));
        String json = JSONObject.toJSONString(object);
        object = JSON.parseObject(json);
        // 将option字符串作为参数发送给echartsConvert服务器
        if (width == null || "".equals(width)) {
            width = "800";
        }
        if (height == null || "".equals(height)) {
            height = "400";
        }
        Map<String, String> params = new HashMap<>();
        params.put("opt", JSON.toJSONString(object));
        params.put("width", width);
        params.put("height", height);
        String response = HttpUtil.post("http://localhost:6666", params, "utf-8");
        System.err.println(response);
        // 解析echartsConvert响应
        JSONObject responseJson = JSON.parseObject(response);
        String code = responseJson.getString("code");

        // 如果echartsConvert正常返回
        if (SUCCESS_CODE.equals(code)) {
            base64 = responseJson.getString("data");
        }
        // 未正常返回
        else {
            String string = responseJson.getString("msg");
            throw new RuntimeException(string);
        }
        return base64;
    }

    /**
     * 将base64转化为图片
     * @param base64
     * @param path
     * @param fileName
     * @throws IOException
     */
    public static void generateImage(String base64, String path, String fileName) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        try (OutputStream out = new FileOutputStream(path + fileName)){
            // 解密
            byte[] b = decoder.decodeBuffer(base64);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {
                    b[i] += 256;
                }
            }
            out.write(b);
            out.flush();
        }
    }
    
    /**
     * 将文件转化为字符串
     * @param fileName
     * @return
     */
    public static String getStringByFile(String fileName) {
        File file = new File("D:/Java/Echart/test.json");
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        try {
            fis = new FileInputStream(file);
            isr = new InputStreamReader(fis);
            br = new BufferedReader(isr);
            String line = null;
            while (((line = br.readLine()) != null)) {
                sb.append(line);
            }
            br.close();
            isr.close();
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return sb.toString();
        }
    }



}

test.json

{
	"tooltip": {
		"trigger": "axis",
		"axisPointer": {
			"type": "shadow"
		}
	},
	"legend": {
		"data": [
			"直接访问",
			"邮件营销",
			"联盟广告",
			"视频广告",
			"搜索引擎",
			"百度",
			"谷歌",
			"必应",
			"其他"
		]
	},
	"grid": {
		"left": "3%",
		"right": "4%",
		"bottom": "3%",
		"containLabel": true
	},
	"xAxis": [{
		"type": "category",
		"data": [
			"周一",
			"周二",
			"周三",
			"周四",
			"周五",
			"周六",
			"周日"
		]
	}],
	"yAxis": [{
		"type": "value"
	}],
	"series": [{
			"name": "直接访问",
			"type": "bar",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				320,
				332,
				301,
				334,
				390,
				330,
				320
			]
		},
		{
			"name": "邮件营销",
			"type": "bar",
			"stack": "广告",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				120,
				132,
				101,
				134,
				90,
				230,
				210
			]
		},
		{
			"name": "联盟广告",
			"type": "bar",
			"stack": "广告",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				220,
				182,
				191,
				234,
				290,
				330,
				310
			]
		},
		{
			"name": "视频广告",
			"type": "bar",
			"stack": "广告",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				150,
				232,
				201,
				154,
				190,
				330,
				410
			]
		},
		{
			"name": "搜索引擎",
			"type": "bar",
			"data": [
				862,
				1018,
				964,
				1026,
				1679,
				1600,
				1570
			],
			"emphasis": {
				"focus": "series"
			},
			"markLine": {
				"lineStyle": {
					"type": "dashed"
				},
				"data": [
					[{
							"type": "min"
						},
						{
							"type": "max"
						}
					]
				]
			}
		},
		{
			"name": "百度",
			"type": "bar",
			"barWidth": 5,
			"stack": "搜索引擎",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				620,
				732,
				701,
				734,
				1090,
				1130,
				1120
			]
		},
		{
			"name": "谷歌",
			"type": "bar",
			"stack": "搜索引擎",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				120,
				132,
				101,
				134,
				290,
				230,
				220
			]
		},
		{
			"name": "必应",
			"type": "bar",
			"stack": "搜索引擎",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				60,
				72,
				71,
				74,
				190,
				130,
				110
			]
		},
		{
			"name": "其他",
			"type": "bar",
			"stack": "搜索引擎",
			"emphasis": {
				"focus": "series"
			},
			"data": [
				62,
				82,
				91,
				84,
				109,
				110,
				120
			]
		}
	]
}

运行main函数,将会在 D:/data/echart/下生成 test.png 的堆栈柱状图。

在这里插入图片描述

四,传入参数方式

前面这种方式直接把test.json中整一个文件当做一个option,这样的话数据就是写死的方式,如果需要自定义数据的话,可以通过编辑json修改option

		// 获取option字符串
        String option = getStringByFile(path + "/test.json");
        JSONObject object = JSONObject.parseObject(option);
        object.getJSONObject("legend").put("data", Arrays.asList("直接访问","邮件营销","联盟广告","其他"));
        option = object.toJSONString();

以上就是关于只通过后台生成Echart图表的方式。

标签:Java,Echart,type,base64,导出,String,series,data,option
来源: https://blog.csdn.net/lmchhh/article/details/118052539

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有