用内置浏览器生成pdf报表

    在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;
	}


你可能感兴趣的:(用内置浏览器生成pdf报表)