开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
前言
前段时间项目有这样一个需求,需要把统计用户的相关数据以Echarts图表的形式展现在pdf文档中。 有时候后端同学遇到生成图表问题可能会有些苦恼,在实际项目中展示图表数据大多场景下可能使用的是 Echarts ,我们大多时候都是把各种统计的图表数据提供给前端同学,通过页面来渲染展示。 这里咱们先做个投票吧,在实际工作中或者项目中,看看有多少图表的生成是依靠前端来实现的,有多少图表的生成是靠后端实现的。欢迎大家参与。
发起投票:
对于上面的疑问,那么是否有什么工具我们后端同学尤其是Java同学也能独自生成需要的图表呢? 答案是有。
项目介绍
下面介绍两个开源项目,一个是基本Apache ECharts 的 Java库 地址,一个是 使用PhantomJS 在服务端生成ECharts图片 的项目 地址 。 有些同学可能会有疑问 PhantomJS 是啥 ? 用官方的介绍讲的话: PhantomJS是一个基于 WebKit 的服务器端JavaScript API。它全面支持web而不需浏览器支持,支持各种Web标准:DOM处理,CSS选择器, JSON,Canvas,和SVG。 PhantomJS常用于页面自动化,网络监测,网页截屏,以及无界面测试等。其实可以这样理解PhantomJS,可以把它当做一个不需要浏览器的客户端。这个时候大家可能大概猜到这个图表数据图片是如何生成的了。
这篇文章从这两个开源项目说起,第一步:如何把我们的数据处理成 Echarts 格式的数据。第二步:如何把处理后的数据生成图表对应的图片
1、数据处理
1.1 引入jar包
<dependency>
<groupId>org.icepear.echarts</groupId>
<artifactId>echarts-java</artifactId>
<version>1.0.7</version>
</dependency>
1.2 获取Json格式Echarts数据
此demo示例以常见的 柱状图、折线图、饼图 为例,生成所需要的Json 格式数据、以及本地html页面。下面是示例以及示例可生成的html页面。 也可参考 官方文档 【目前官方提供的文档还不够完善,如有同学在使用过程中有疑问,欢迎在下方评论留言】
import org.icepear.echarts.Bar;
import org.icepear.echarts.Line;
import org.icepear.echarts.Option;
import org.icepear.echarts.Pie;
import org.icepear.echarts.charts.line.LineSeries;
import org.icepear.echarts.charts.pie.PieSeries;
import org.icepear.echarts.components.coord.cartesian.CategoryAxis;
import org.icepear.echarts.components.coord.cartesian.ValueAxis;
import org.icepear.echarts.components.legend.Legend;
import org.icepear.echarts.components.title.Title;
import org.icepear.echarts.components.tooltip.Tooltip;
import org.icepear.echarts.origin.util.SeriesOption;
import org.icepear.echarts.render.Engine;
import java.util.ArrayList;
import java.util.List;
/**
* 生成json数据 以及 本地html文件
*
* @author demain_lee
* @since 2022/12/28
*/
public class EchartsData {
public static void main(String[] args) {
getBar();
getLine1();
getLine2();
getPie();
}
/**
* 柱状图
* 使用 {@link Bar} 构建
*/
static void getBar() {
// All methods in ECharts Java supports method chaining
Bar bar = new Bar()
.setLegend()
.setTooltip("item")
.addXAxis(new String[]{"Matcha Latte", "Milk Tea", "Cheese Cocoa", "Walnut Brownie"})
.addYAxis()
.addSeries("2020", new Number[]{43.3, 83.1, 86.4, 72.4})
.addSeries("2021", new Number[]{85.8, 73.4, 65.2, 53.9})
.addSeries("2022", new Number[]{93.7, 55.1, 82.5, 39.1});
Engine engine = new Engine();
// The render method will generate our EChart into a HTML file saved locally in the current directory.
// The name of the HTML can also be set by the first parameter of the function.
engine.render("demo-bar.html", bar);
// json 格式数据
System.out.println(engine.renderJsonOption(bar));
}
/**
* 折线图
* ECharts中,一切图表皆Option,使用 {@link Line} 构建
*/
static void getLine1() {
// All methods in ECharts Java supports method chaining
Line line = new Line()
.setLegend()
.setTooltip("item")
.addXAxis(new String[]{"Matcha Latte", "Milk Tea", "Cheese Cocoa", "Walnut Brownie"})
.addYAxis()
.addSeries("2020", new Number[]{43.3, 83.1, 86.4, 72.4})
.addSeries("2021", new Number[]{85.8, 73.4, 65.2, 53.9})
.addSeries("2022", new Number[]{93.7, 55.1, 82.5, 39.1});
Engine engine = new Engine();
// The render method will generate our EChart into a HTML file saved locally in the current directory.
// The name of the HTML can also be set by the first parameter of the function.
engine.render("demo-line1.html", line);
// json 格式数据
System.out.println(engine.renderJsonOption(line));
}
/**
* 折线图
* ECharts中,一切图表皆Option,使用 {@link Option} 构建
*/
static void getLine2() {
Option option = new Option();
option.setLegend(new Legend().setData(new String[]{"2020", "2021", "2022"}));
option.setTooltip(new Tooltip().setTrigger("item"));
option.setXAxis(new CategoryAxis().setData(new String[]{"Matcha Latte", "Milk Tea", "Cheese Cocoa", "Walnut Brownie"}));
option.setYAxis(new ValueAxis().setType("value"));
LineSeries lineSeries1 = new LineSeries().setName("2020").setData(new Number[]{43.3, 83.1, 86.4, 72.4});
LineSeries lineSeries2 = new LineSeries().setName("2021").setData(new Number[]{85.8, 73.4, 65.2, 53.9});
LineSeries lineSeries3 = new LineSeries().setName("2022").setData(new Number[]{93.7, 55.1, 82.5, 39.1});
option.setSeries(new SeriesOption[]{lineSeries1, lineSeries2, lineSeries3});
Engine engine = new Engine();
System.out.println(engine.renderJsonOption(option));
engine.render("demo-line2.html", option);
}
/**
* 饼图
* 使用 {@link Pie} 构建
* ref <a href="https://echarts.apache.org/examples/zh/editor.html?c=pie-simple">...</a>
*/
static void getPie() {
List<PieData> list = new ArrayList<>();
list.add(new PieData("直接访问", 335));
list.add(new PieData("邮件营销", 310));
list.add(new PieData("联盟广告", 234));
list.add(new PieData("视频广告", 135));
list.add(new PieData("搜索引擎", 1548));
PieSeries pieSeries = new PieSeries()
.setName("访问来源")
.setType("pie")
.setRadius("55%")
.setData(list);
Pie pie = new Pie()
.setTitle(new Title().setText("Referer of a Website").setSubtext("Fake Data").setLeft("center"))
.setLegend(new Legend().setOrient("vertical").setLeft("left"))
.setTooltip("item")
.addSeries(pieSeries);
Engine engine = new Engine();
// The render method will generate our EChart into a HTML file saved locally in the current directory.
// The name of the HTML can also be set by the first parameter of the function.
engine.render("demo-pie.html", pie);
// json 格式数据
System.out.println(engine.renderJsonOption(pie));
}
/**
* 饼图数据
*/
static class PieData {
private String name;
private Integer value;
public PieData(String name, Integer value) {
this.name = name;
this.value = value;
}
}
}
1.2.1 柱状图
1.2.2 折线图
1.2.3 饼图
2、安装PhantomJS
2.1 常规方式安装部署 (不推荐)
2.1.1 下载PhantomJS安装包
官网地址下载最新的安装包,目前最新的版本是 2.1.1 。它支持 windows 、mac os 、linux 等 。
2.1.2 配置环境变量
windows下操作:
path 下添加 C:\Users\ming\Desktop\java-echarts\phantomjs-2.1.1-windows\bin
打开cmd,查看是否配置成功
C:\Users\ming>phantomjs --version
2.1.1
linux 下操作:
export PHANTOMJS=/usr/local/phantomjs/phantomjs-2.1.1-linux-x86_64
export PATH=$PATH:$PHANTOMJS/bin
# or
export PATH=$PATH:/usr/local/phantomjs/phantomjs-2.1.1-linux-x86_64/bin
# 刷新配置
source /etc/profile
2.1.3 运行脚本测试
安装包下 example 文件夹下提供了好多示例,这里以hello.js 为例,在example文件夹下输入 phantomjs hello.js 命令 会输出 Hello, world! 更多用法可参考官方文档。
C:\Users\ming\Desktop\java-echarts\phantomjs-2.1.1-windows\examples>phantomjs hello.js
Hello, world!
2.1.3 下载 echartsconvert 项目
# clone 方式
git clone https://gitee.com/saintlee/echartsconvert.git
# 或者直接点击按钮下载
2.1.4 启动命令
windows下启动命令 端口默认 9090
C:\Users\ming\Desktop\java-echarts\echartsconvert>phantomjs echarts-convert.js -s
linux 下启动命令 端口默认 9090
nohup phantomjs /usr/local/phantomjs/echartsconvert/echarts-convert.js -s &
2.1.5 文件替换
echartsconvert\script 目录下 有 echarts.min.js 、jquery-3.2.1.min.js 文件 ,使用的时候可以自定义替换版本 ,文件配置见 echartsconvert/echarts-convert.js 文件
2.1.6 文件乱码问题
linux 下 phantonjs 没有支持的中文, 需要进行安装对应包。也可安装其它字体库,这里不做更多叙述。
yum -y install bitmap-fonts bitmap-fonts-cjk
2.2 docker 镜像方式部署 (强烈推荐)
由于上面的一些操作有些繁琐,我这里把相关文件配置统一打包成docker镜像,2行代码即可实现安装部署
2.2.1 拉取镜像
docker pull slightlee/phantomjs:0.1
2.2.1 启动容器
docker run -d --name phantomjs -p 9090:9090 slightlee/phantomjs:0.1
3、JSON格式数据生成图表图片
直接上demo
package com.demain.test;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 以 EchartsData 示例中 getBar() 数据为例,将生成的Echarts数据转为base64图片
*
* @author demain_lee
* @since 2022/12/28
*/
public class EchartData2Base64 {
public static void main(String[] args) throws IOException {
// json 格式数据
String jsonData = "{"xAxis":[{"type":"category","data":["Matcha Latte","Milk Tea","Cheese Cocoa","Walnut Brownie"]}],"yAxis":[{"type":"value"}],"tooltip":{"trigger":"item"},"legend":{},"series":[{"type":"bar","name":"2020","data":[43.3,83.1,86.4,72.4]},{"type":"bar","name":"2021","data":[85.8,73.4,65.2,53.9]},{"type":"bar","name":"2022","data":[93.7,55.1,82.5,39.1]}]}";
// PhantomJS 服务器地址
String url = "http://localhost:9090";
Map<String, String> map = new HashMap<>();
jsonData = jsonData.replaceAll("\s+", "").replaceAll(""", "'");
map.put("opt", jsonData);
String resultData = post(url, map, "utf-8");
System.out.println(resultData);
}
public static String post(String url, Map<String, String> map, String encoding) throws IOException {
String body = "";
// 创建httpclient对象
CloseableHttpClient client = HttpClients.createDefault();
// 创建post方式请求对象
HttpPost httpPost = new HttpPost(url);
// 装填参数
List<NameValuePair> nvp = new ArrayList<>();
if (map != null) {
for (Map.Entry<String, String> entry : map.entrySet()) {
nvp.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
// 设置参数到请求对象中
httpPost.setEntity(new UrlEncodedFormEntity(nvp, encoding));
// 执行请求操作,并拿到结果(同步阻塞)
CloseableHttpResponse response = client.execute(httpPost);
// 获取结果实体
HttpEntity entity = response.getEntity();
if (entity != null) {
// 按指定编码转换结果实体为String类型
body = EntityUtils.toString(entity, encoding);
}
EntityUtils.consume(entity);
// naps
response.close();
return body;
}
}
3.1 base64格式数据
resultData 返回的数据包含base64格式数据
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
4、结束语
本篇文章到这里就结束了,本文介绍了如何通过Java 第三方库去处理对应的图表数据,以及通过基于PhantomJS的第三方开源项目echartsconvert进行数据转换,获取最后需要的Base64格式的图片数据。有了这个数据可以把它运用到自己需要的地方。 如下图所示,写到PDF文档中。至于操作PDF文档的工具可以用 spire、itext 等。如果大家有需要,可以评论留言,到时再单独写篇文章。 spire 示例 、itext 示例 。 本篇文章代码示例 , 也可查看其它更多demo 示例 。