项目需求
用户定时需要收到指定的PDF 到邮箱 其中 PDF里必须是用户上次在前台选择过的图表类型
需求分析
- 首先需要去拿到用户自定义想要最近几天的数据(查询ES 这里需要去自己请求自己的接口拿到指定的数据)
- 去把数据渲染到echarts 只能纯后端生成 (echarts 需要跟前端选择的一样 所以这里需要跟前端调取一样的库)
- 把生成的echarts 的图片 通过流的形式添加到 PDF 文件中
- 在PDF 中加上指定的 文字以及 页脚
- 开始发送 email
- 修改JAVA 定时器 实现从数据库查的 cron 替换Springboot 本身自带的。
代码实现
模拟浏览器自己执行自己的接口
package com.ms.ssa.util.Post;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
public class HttpClientUtil {
@SuppressWarnings("resource")
public static String doPost(String url, String jsonstr, String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = new SSLClient();
httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json");
StringEntity se = new StringEntity(jsonstr);
se.setContentType("text/json");
se.setContentEncoding(new BasicHeader("Content-Type", "application/json"));
httpPost.setEntity(se);
HttpResponse response = httpClient.execute(httpPost);
if(response != null){
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result=EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
}
从ES 中查询数据
// 这里这个类是我封装的 请求数据的类
public void HttpGetData() throws Exception {
List<xxxxx> SendEmailList = ssaSendEmailService.GetAll();
SendEmailList.stream().forEach(s1 -> {
String name = s1.getName();
// 获取到你要发送给谁邮件
String to = s1.getTo();
// 邮件消息
String message = s1.getMessage();
// 邮件主题
String subject = s1.getSubject();
// 获取用户选择的 要几天内的数据
String time = s1.getTime();
String timeurl = "http://localhost:80/****/" + Integer.valueOf(time);
String httpOrgCreateTestRtn1 = HttpClientUtil.doPost(timeurl, "", "utf-8");
JSONObject parse = (JSONObject) JSONObject.parse(httpOrgCreateTestRtn1);
Object data = parse.get("data");
List<xxxx> SsaCountryReportList = ssaCustomReportService.GetAll1(name);
// url
SsaCountryReportList.stream().forEach(s -> {
// 获取图表类型
String Type = s.getName();
// 获取到用户 url
String url = s.getInterfaceName();
// 报表的 前 top
Integer top = s.getTop();
// ???????? count...
String explain = s.getExplain();
// searchWords 获取到用户 条件
String searchWords = s.getSearchWords();
// tle
String title = s.getTitle();
HashMap<String, Object> map = new HashMap<>();
map.put("top", top);
map.put("filterParam", searchWords + "&" + data);
// 根据条件去查询后端ES 的接口
String Dataurl = "http://localhost:80/api/api" + url;
String jsonStr = null;
try {
jsonStr = new ObjectMapper().writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
String httpOrgCreateTestRtn = HttpClientUtil.doPost(Dataurl, jsonStr, "utf-8");
//System.out.println(httpOrgCreateTestRtn);
JSONObject parse1 = (JSONObject) JSONObject.parse(httpOrgCreateTestRtn);
if (!ObjectUtil.isEmpty((JSONObject) ((JSONObject) parse1.get("retData")).get("xxx"))) {
JSONObject infolists = (JSONObject) ((JSONObject) parse1.get("retData")).get("xxxx");
JSONArray jsonArray = infolists.getJSONArray(explain);
if (Type.equals(LINEONE)) {
SendEmail.HandleKVAndNV(Echart.lineOne(title), jsonArray, LINEONE);
} else if (Type.equals(LINETOW)) {
SendEmail.HandleKVAndNV(Echart.lineTwo(title), jsonArray, LINETOW);
} else if (Type.equals(BARONE)) {
SendEmail.HandleKVAndNV(Echart.BarOne(title), jsonArray, BARONE);
} else if (Type.equals(BARTWO)) {
SendEmail.HandleKVAndNV(Echart.BarTwo(title), jsonArray, BARTWO);
} else if (Type.equals(PIEONE)) {
SendEmail.HandleKVAndNV(Echart.PieOne(title), jsonArray, PIEONE);
} else if (Type.equals(PIETWI)) {
SendEmail.HandleKVAndNV(Echart.PieTwo(title), jsonArray, PIETWI);
}
}
});
// 拿到数据后去调用生成 PDF 的 方法
imagesToPdf("pdf 名称", System.getProperties().getProperty("user.dir") + "/src/main/resources/phg/");
try {
// 调用发送 EMAIL 的方法
sendemail(to,subject,message);
} catch (Exception e) {
e.printStackTrace();
} finally {
String dataPath = System.getProperties().getProperty("user.dir") + "/src/main/resources/phg/";
File file=new File(dataPath);
// 调用 删除 存放图片 方法 没次发完邮件清空图片的文件夹避免重复 发送
deleteFile(file);
}
});
}
生成 echarts 的代码
**这里需要自己安装phantomjs **
以及下面的js
package com.learn.echats;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.learn.echats.Mapper.SSa;
import com.learn.echats.echartutil.Echart;
import com.learn.echats.pojo.SsaCountryReport;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.ObjectUtils;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
@SpringBootTest
class EchatsApplicationTests {
private static final String JSpath = "C:\\Users\\86152\\Desktop\\echarts-master\\echarts-master\\src\\main\\resources\\static\\echarts-convert.js";
// 定义常量
public static final String LINEONE = "lineOne";
public static final String LINETOW = "lineTwo";
public static final String BARONE = "BarOne";
public static final String BARTWO = "BarTwo";
public static final String PIEONE = "PieOne";
public static final String PIETWI = "PieTwo";
/**
* 这个是判断返回值类型是 kv name value
* Type :这个是图表的类型 就是 JSON option
* data 这个是数据库 查出来的数据
* name 这个是图表的name
*/
public static JSONObject HandleKVAndNV(String Type, String data, String name) {
// 第一种情况 是 line One
JSONObject optionsJson = (JSONObject) JSONObject.parse(Type);
// 定义 X 坐标
JSONArray xDataArray = new JSONArray();
// 这个是定义 Y 坐标
JSONArray yDataArray = new JSONArray();
// 饼图的
if (!ObjectUtils.isEmpty(data)) {
// 这里去判断 array 的数据到底是 k v 形式还是 name value 这里是我们数据格式 也可能不是这样
for (int i = 0; i < array.size(); ++i) {
JSONObject jsonObject = array.getJSONObject(i);
Object k = jsonObject.get("k");
if (!ObjectUtils.isEmpty(k)) {
xDataArray.add(jsonObject.get("k"));
yDataArray.add(jsonObject.get("v"));
} else {
xDataArray.add(jsonObject.get("name"));
yDataArray.add(jsonObject.get("value"));
}
}
}
if (name.equals(LINEONE)) {
JSONObject series = new JSONObject();
series.put("data", yDataArray);
series.put("type", "line");
optionsJson.getJSONObject("xAxis").put("data", xDataArray);
optionsJson.getJSONArray("series").add(series);
// 调用生成 图表的方法
generateEChart(optionsJson.toJSONString());
return optionsJson;
} else if (name.equals(LINETOW)) {
// JSONObject series = new JSONObject();
//series.put("data", yDataArray);
//series.put("type", "line");
optionsJson.getJSONObject("xAxis").put("data", xDataArray);
optionsJson.getJSONArray("series").getJSONObject(0).put("data", yDataArray);
optionsJson.getJSONArray("series").getJSONObject(0).put("type", "line");
// 调用生成 图表的方法
generateEChart(optionsJson.toJSONString());
return optionsJson;
} else if (name.equals(BARONE)) {
optionsJson.getJSONArray("xAxis").getJSONObject(0).put("data", xDataArray);
optionsJson.getJSONArray("series").getJSONObject(0).put("data", yDataArray);
optionsJson.getJSONArray("series").getJSONObject(0).put("type", "bar");
generateEChart(optionsJson.toJSONString()