在java项目内置一个phantomJS浏览器,用echarts生成图表,然后生成pdf报表,为了数据安全,所以内置浏览器的,直接给用户报表,
以下代码主要获取访问路径,主要调用红色
public HashMap dataProcess(@ModelAttribute WeatherHistoryGridReportFrontEditData entity, HttpServletResponse response) {
DataSourceHolder.setCustomerType(ChangeDataSource.ADMIN);
HashMap resultMap = new HashMap();
HttpSession session = getRequest().getSession();
//根据当前登录用户,获取其所有公司logo,并填充至模版中
InfoUser loginUser = getSessionUserInfo();
InfoCompany companyObj = companyService.get(loginUser.getInfoCompanyId());
byte[] companyLogoByte = companyObj.getLogo();
//ByteArrayInputStream companyLogoStream = new ByteArrayInputStream(picLogo);
//服务器访问路径http://localhost:8083/wrmpg/
String path = getRequest().getContextPath();
String basePath = getRequest().getScheme()+"://"+getRequest().getServerName()+":"+getRequest().getServerPort()+path+"/";
//phantomJSPath保存路径 D:\java\apache-tomcat-9.0.0.M9-8083\webapps\wrmpg\phantomJS/
String phantomJSPath = session.getServletContext().getRealPath("/") + "phantomJS/";
//pdf保存路径(不同的登录用户,建立单独的文件夹)
InfoUser user = (InfoUser) session.getAttribute(Constants.SESSION_USER);
String currentLoginUserCode = user.getCode();
//获取tomcat中webapp目录
String tomcatWebApp = getTomcatWebappsPath(session);
String pdfReportFilePath = tomcatWebApp + "wrmpg_pdfFile/" + currentLoginUserCode;
try {
/**
* 根据所选择的要素时行判断,调用对应的action链接,生成图片
* @param checkedElementData 传入前端传来的数据
* @param phantomJSPath 部署的web应用在服务器上的实际路径
* @param basePath 应用web访问路径
* @return
* @throws Exception
*/
weatherHistoryGridPdfCreatorService.callActionForHistoryGridChart(entity,phantomJSPath,basePath);
//判断图片是否生成,如果没有生成则在循环中等待,并添加计时器限定时间
boolean flag = true;
imageFlag = false;
Calendar beginTime = Calendar.getInstance();
while(flag) { //利用无限循环制造线程阻塞,等待后面的操作完成
Calendar currentTime = Calendar.getInstance();
long usedTime = currentTime.getTimeInMillis() - beginTime.getTimeInMillis();
if(imageFlag == true) {
imageFlag = false; //使用完后,重置为false
break;
}
if(usedTime >= 180 * 1000) { //单个要素图片生成时间如果超过20s,终止操作
resultMap.put("status", "timeOut");
break;
}
}
//使用调用phantomJS生成的chart图片创建chart部分的pdf文件
//byte[] chartPdfFileOutPutByte = weatherHistoryGridPdfCreatorService.generateHistoryGridChartPartPdf(chartImageStreamList,session);
JasperPrint chartPdfFileOutPutByte = weatherHistoryGridPdfCreatorService.generateHistoryGridChartPartPdf(chartImageStreamList,session,companyLogoByte);
//整合所有部分的pdf,返回完整的pdf报表
allPdfFileOutPutByte = weatherHistoryGridPdfCreatorService.createHistoryGridPdf(entity,chartPdfFileOutPutByte,session,companyLogoByte);
//将pdf报表写入到文件夹中,当需要下载时,触发下载
String savePdfName = weatherHistoryGridPdfCreatorService.savePdfReportFile(pdfReportFilePath, allPdfFileOutPutByte);
//pdfDownLoadURL
String pdfDownLoadURL = getRequest().getScheme()+"://"+getRequest().getServerName()+":"+getRequest().getServerPort()+"/wrmpg_pdfFile/"+currentLoginUserCode+"/"+savePdfName;
resultMap.put(Contents.OPERATE, Contents.SUCCESS);
resultMap.put("downloadUrl", pdfDownLoadURL);
resultMap.put("fileName",savePdfName);
} catch (Exception e) {
resultMap.put(Contents.OPERATE, Contents.FAILED);
e.printStackTrace();
}
return resultMap;
}
调用callActionForHistoryGridChart()后,将数据处理成需要的访问路径,和数据格式。这里主要是untime.getRuntime().exec()来新的进程去运行调用内置的phantomjs的程序。
public void callActionForHistoryGridChart(WeatherHistoryGridReportFrontEditData checkedElementData,String webPath,String webAppPath) throws Exception{
String phantomJSPath = webPath + "phantomjs-2.1.1-windows/bin/phantomjs.exe ";
//test.js是保存在G盘下面的phantomjs目录
String callChartPageJS = webPath +"callChartPage.js ";
try {
//1、根据前端传来的参数,判断哪些要素被选中,对于选中的要素进行展示
String cmdStr = phantomJSPath + callChartPageJS + " "+webAppPath+"chartsGenerate.do?lon="+lon+"&lat="+lat+"&beginTime="+beginTime+"&endTime="+endTime
+"&heavyRainThreshold="+heavyRainThreshold+"&windMaxThreshold="+windMaxThreshold+"&temMaxThreshold="+temMaxThreshold+"&temMinThreshold="+temMinThreshold
+"&preCheckedValue="+preCheckedValue+"&temCheckedValue="+temCheckedValue+"&windMaxCheckedValue="+windMaxCheckedValue+"&windExtCheckedValue="+windExtCheckedValue
+"&thsCheckedValue="+thsCheckedValue+"&hailCheckedValue="+hailCheckedValue+"&sunCheckedValue="+sunCheckedValue+"&groundTemCheckedValue="+groundTemCheckedValue;
//生成一个新的进程去运行调用的程序。用一个新的进程去调用phantomJS
Runtime rt = Runtime.getRuntime();
rt.exec(cmdStr);
}catch (Exception e) {
e.printStackTrace();
}
}
其中smdStr如下:
//为phantomjs.exe的实际路径,用于开启内置的浏览器
D:\java\apache-tomcat-9.0.0.M9-8083\webapps\wrmpg\phantomJS/phantomjs-2.1.1-windows/bin/phantomjs.exe
//开启phantomjs的界面,用于设置页面信息
D:\java\apache-tomcat-9.0.0.M9-8083\webapps\wrmpg\phantomJS/callChartPage.js
内置浏览器发送的连接
http://localhost:8083/wrmpg/chartsGenerate.do?lon=108.369140625&lat=25.20494115356912&beginTime=2009-01-01&endTime=2009-12-31&heavyRainThreshold=50.0&windMaxThreshold=13.9&temMaxThreshold=35.0&temMinThreshold=5.0&preCheckedValue=isChecked&temCheckedValue=isNotChecked&windMaxCheckedValue=isNotChecked&windExtCheckedValue=null&thsCheckedValue=isNotChecked&hailCheckedValue=isNotChecked&sunCheckedValue=null&groundTemCheckedValue=null
callChartPage.js 代码
var system = require('system');
//创建页面
var page = require('webpage').create();
//设置页面长宽
page.viewportSize = { width: 1280, height: 800 };
// 如果是windows,设置编码为gbk,防止中文乱码,Linux本身是UTF-8
//if ('windows' === osName.toLowerCase()) {
phantom.outputEncoding="gbk";
//}
// 获取第二个参数(即请求地址url),动态取得访问地址
var url = system.args[1];
//var url = "http://localhost:8082/zhtq/showPhantomJSTestPage.do";
//打开给定url的页面.
var start = new Date().getTime();
page.open(url, function(status) {
if (status == 'success') {
var url = page.url;
console.log(url+'---页面加载完成,加载耗时:' + (new Date().getTime() - start) + ' ms');
//由于echarts动画效果,延迟500毫秒确保图片渲染完毕再调用下载图片方法.
setTimeout(function() {
page.render("d:/phantomJSshotScreen.png");
}, 1000);
} else {
console.log("页面加载失败 Page failed to load!");
}
// 10秒后再关闭浏览器.
setTimeout(function() {
phantom.exit();
}, 10000);
});
向服务端发送请求后,打开echarts界面生成相应的echarts图表,调用getDataURL用,进行png格式导出,以
base64 格式编码传入后台,数据用JSON.stringify进行格式化,这里就写主要代码。
insuranceHistoryHalChart2Image = insuranceHistoryHalChart2.getDataURL({
type:"png",
pixelRatio: 1,
backgroundColor: '#565656'
});
imageString = imageString + "&" +insuranceHistoryHalChartImage + "&" + insuranceHistoryHalChart2Image;
}
$.ajax({
async: false,
dataType: 'json',
contentType:'application/json;charset=UTF-8',
cache: true,
type: "POST",
url: $("#urlId").val()+"getPhantomJSChartsImageData.do", //传递所选取位置的经度,纬度以及地名
data: JSON.stringify(imageString),
error: function() {
},
success: function(data) {
//console.log(data);
}
});
后台接收数据,并转化图片输入流
/**
* 将前端传来的base64字符串,转换为图片输入流
* @param imagesBase64Info charts图片base64字符串
* @return
*/
public static List getElementChartImageStream(String imagesBase64Info) {
List chartImageStreamList = new ArrayList();
try {
if(imagesBase64Info!= null && !imagesBase64Info.equals("")) {
imagesBase64Info = imagesBase64Info.replaceAll(" ", "+"); //字符串在传到后台的过程中,"+"被转换成了空格,所以要进行替换
String[] images = imagesBase64Info.split("&"); //整个字符串中包含多张图片,用"&"分隔
for(int i=1;i
然后调用jasper模版,生成JasperPrint对象,最后生成pdf
/**
* 处理jasper模版,并填充必要参数<模版名称,包含数据源bean的list,传入模版的参数map,session>,返回一个jasperPrint对象
*/
public static JasperPrint getJasperPrint(String reportName, List> mapList,Map companyLogo,HttpSession session){//
//获取模版所在文件夹的路径
String path = Contents.jasperPath;
if(session != null){
//获取"jasper"文件夹的绝对路径,jasper模版文件放置在项目根目录jasper文件夹中
path = session.getServletContext().getRealPath("static");
}
JasperPrint jasperPrint = null;
try{
File jasperFile = new File(path+"/jasper/"+reportName+".jasper");
//如果jasper文件不存在,就调用jrxml文件编译生成 .jasper文件
//JasperCompileManager.compileReportToFile(String sourceFileName, String destFileName)
if (!jasperFile.exists()) {
JasperCompileManager.compileReportToFile(path + "/"+ reportName + ".jrxml",path + "/"+ reportName + ".jasper");
}
//加载编译后的模版文件
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperFile);
//接收处理传入的数据
JRDataSource dataSource = new JRBeanCollectionDataSource(mapList);
//将对象列表设为数据源,第二个参数传入参数为模版图片文件,返回的是一个JasperPrint类对象,其中包含所有模版参数和数据
jasperPrint = JasperFillManager.fillReport(jasperReport, companyLogo, dataSource);
}catch(Exception e){
e.printStackTrace();
}
return jasperPrint;
}