SptingBoot基于Echarts生成折线图,柱状图
前言
近期产品团伙给了一个生成PDF数据报的需求,PDF中需要生成折线图,梯状折现图,柱状图等需求以及一些表格信息的东西,我这边就去找到前端开发工程师,但是前端工程师并没有好的方案给出,于是乎就由后台开发来生成图片,并写入PDF中。
下面我把我生成统计图的方法(大部分参考+整合)写成文章,需要的兄弟姐妹们可以参考和纠正我。
用到的技术与开源代码
1.PhantomJS
PhantomJS是一个不需要浏览器的富客户端。
官方介绍:PhantomJS是一个基于 WebKit 的服务器端JavaScript API。它全面支持web而不需浏览器支持,支持各种Web标准:DOM处理,CSS选择器, JSON,Canvas,和SVG。
PhantomJS常用于页面自动化,网络监测,网页截屏,以及无界面测试等。
我们可以这么理解:PhantomJS是一个无界面、可运行脚本的谷歌浏览器
下面我们来进行下载与操作:
- PhantomJS(官方下载),我们进入官网下载对应的最新版本,后解压就可以使用了
- 解压后我们需要配置环境变量
右键我的电脑->属性->高级系统设置->高级系统设置->环境变量->Path内新增C:\Users\litianqi\Desktop\phantomjs-2.1.1-windows\bin(这是我的安装解压文件bin地址)
下面我们就可以进行测试使用执行DOME - 执行DOME JS
Hello, world
1.进入安装路径下examples文件夹
2.打开CMD黑窗口
3.输入 phantomjs hello.js
4.控制台输出Hello, world!
JS截屏
我自己这么叫他,下面看dome
1.创建pageload.js文件
2.写入内容:
"use strict";
var page = require('webpage').create();
page.open('https://www.baidu.com/', function () {
page.render('baidu.png');
phantom.exit();
});
3.打开CMD黑窗口,输入 <phantomjs phantomjs pageload.js> 运行文件
4.即可在同级目录下得到一张baidu.png的图片
这样就相当于,你拿谷歌浏览器打开了百度这个页面,然后截了一张图,并保存到你想保存的位置了~
大概的使用流程就是如此,这里简述案列,就不多赘述(文档里都有)~
2.Echartsconvert 开源项目
上面讲述了PhantomJS如何使用,下面我们就从Echarts官网使用JS截图的方式来获取我们想要的图片
- Echartsconvert (Gitee)copy下来代码
注意:因为该源码长期没有更新,script目率下echarts.min.js太过于老旧,无法支持目前Echarts的图形,请大家copy下代码后,更新替换其文件 。最新echarts.min.js下载传送门
其中echarts-convert.js就是我们要使用到的主C,这个Js就相当于帮我们去Echarts官方运行Dome->生成折线图/柱状图->保存到指定文件夹下
看看这些代码 有没有觉得很眼熟的感觉??
下面我们来使用PhantomJS运行这个echarts-convert.js
1.copy的项目下打开cmd黑窗口
2.执行 <phantomjs echarts-convert.js -s -p 6666>
3.黑窗口打印【echarts-convert server start success. [pid]=10364】表明启动成功
-s或–server:开启服务监听,如果开启服务端,则-o不生效,这也就意味不能使用脚本命令生成图片;
-p或–port:端口号,只有-s启用时生效,改变监听端口号;
2.SpringBoot实现统计图生成
1.pom.xml重要依赖
<!--①-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
【依赖①】freemarker是什么?FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。其原理如下图所示:
FreeMarker详细手册传送门
2.图片数据模板
在这里,我就用生成单折线图来做示例。
模板格式均可在 Echarts(官方示例地址)搜索。
{
animation:false ,
xAxis: {
type: 'category',
data: ${x}
},
yAxis: {
type: 'value'
},
series: [
{
data: ${y0},
type: 'line',
color:'blue',
},
{
data: ${y1},
type: 'line',
color:'green',
}
]
}
将模板放入项目资源目录中比较舒服~~
3.JAVA代码
DTO
@Data
public class ImageDataDto {
/**
*标题
**/
private String title;
/**
*X轴
**/
private List<String> x;
/**
*y轴(多)
**/
private List<List<Double>> y = new ArrayList();
}
逻辑代码
public String linecreateImage(ImageDataDto dto) throws IOException, TemplateException {
//新建Map装载数据
HashMap<String, Object> data = new HashMap<>();
data.put("x", JSON.toJSONString(dto.getX()));
data.put("y0", JSON.toJSONString(dto.getY().get(0)));
data.put("y1", JSON.toJSONString(ddto.getY().get(1)));
//模板引擎
String options = FreemarkerUtil.generateString("optionline.ftl", "/teplate", data);
//文件夹路径
String filePath = "";
String name = filePath + UUID.randomUUID().toString() + ".png";
// 文件输出到指定路径方法
generateImage(EchartsUtil.generateEchartsBase64(options), name);
return name;
}
private static void generateImage(String base64, String s) {
//文件
BASE64Decoder decoder = new BASE64Decoder();
try (OutputStream out = new FileOutputStream(s)) {
// 解密
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();
} catch (IOException e) {
e.printStackTrace();
}
}
FreemarkerUtil工具类
public class FreemarkerUtil {
private static final String path = FreemarkerUtil.class.getClassLoader().getResource("").getPath();
public static String generateString(String templateFileName, String templateDirectory, Map<String, Object> datas)
throws IOException, TemplateException {
Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
// 设置默认编码
configuration.setDefaultEncoding("UTF-8");
// 设置模板所在文件夹
configuration.setDirectoryForTemplateLoading(new File(path + templateDirectory));
// 生成模板对象
Template template = configuration.getTemplate(templateFileName);
// 将datas写入模板并返回
try (StringWriter stringWriter = new StringWriter()) {
template.process(datas, stringWriter);
stringWriter.flush();
return stringWriter.getBuffer().toString();
}
}
}
是的~到这里就已经完事了,不出意外你指定的文件夹下已经有生成的图片。
结尾
图片生成到文件夹中,就可以为我所用,比如我需要写入pdf中生成报告。。。。这里的demo只是简单的折线图,不过就可以满足很多人的需求,如果需要更复杂的去Echarts官网查找。
其实java后台生成这种统计图的需求是很少的~~
本人曾使用过jfreechart等其他统计图生成方案均不本文所介绍的理想,如果大家有什么更好用的,欢迎分享。