现在的位置: 首页 > 综合 > 正文

Java根据word模板生成word文档之后台解析和实现及部分代码(一)

2018年01月27日 ⁄ 综合 ⁄ 共 5696字 ⁄ 字号 评论关闭

        后台主要工作是解析XML定义的标签文件,并获取到数据集,放入到Map中,然后调用Jacob.jar中提供的相关方法来实现替换。首先想多说一句就是jacob会每次生成word报告时都会启动一个office word进程,替换完毕之后 需要关闭掉这个进程,如果有死掉的word进程有可能会影响word的生成。这些具体调试或运行过程中就会发现这个问题的。

        还需要说明一点,解析XML有很多种方式,自己挑选自己熟悉的就行了,我采用jdom,当时想的没有这么负责,所以写代码也没有怎么重构,需要重新整理,主要方法我会贴出来。

       那么我就从头到尾的说一下,调用生成报告时,后台的整个调用过程是怎么样的,是如何运转的?

       首先访问web应用地址:http://192.16.3.22/demo/DocInfo!createDoc.action 这样我提交一个方法 action方法,这个方法首先是在web应用服务器上的,然后进入action中的createDoc方法,同时你需要获取到从方法传过来的相关参数,比如:sql中定义的那个查询条件,报告类型等参数。

 (在去调用生成报告的方法中,可能你还需要加入一些判断,如是否已经生成过报告啊,或者最新报告的版本啊,因为我们都是既保存word报告文档又会在数据库中插入一条记录,方便查询),这样就开始了:

首先是action的createDoc方法:

/**
	 * 通过HttpCient调用报告服务器的方法生成报告 DOC
	 */
	public String createDoc() throws Exception {
                 //定义放回成功与否的判断码
                 String prMsg="";
		 // 获取当前登录的用户
		 UserVo userVo = CommonUtils.getUserMessage();
		 //获取模版类型
		 docType = Struts2Utils.getParameter("docType");
		 //重新创建文档
		 String creatOrnot = Struts2Utils.getParameter("creatOrnot");
		 //获取组组编号参数
		 workgroupId = Struts2Utils.getParameter("workgroupId");
		 //获取评估用例实例ID参数
		 evtcaseInstId = Struts2Utils.getParameter("evtcaseInstId");
		if(CommonUtils.isNotNull(docType)){
			//获取项目Id
			 projectId = Struts2Utils.getParameter("projectId");
			if(!CommonUtils.isNotNull(projectId)){
				if(CommonUtils.isNotNull(this.getIdFromSession("PM_PROJECTID"))){
					projectId = this.getIdFromSession("PM_PROJECTID").toString();
				}else{
					Struts2Utils.getRequest().setAttribute("msg", "请先选择项目!");
				}
			}
			if(CommonUtils.isNotNull(projectId)){
				prMsg = infoSystemDescService.downloadFileByUrl(projectId, userVo.getUserId(), workgroupId, evtcaseInstId, docType, creatOrnot);
			}
		}
		return "docList";
	}

      注:在我贴出来的代码中,能看懂就行了,有些不用管他(可能是其他业务方面的判断),关于最后返回的prMsg---代表各种状态
主要表示成功与否或者是出错的信息。


   接着我贴出service层的方法downloadFileByUrl    


/**
	 * 功能:
     * 1.(生成报告文档)
     * 2.保存指定URL的源文件到指定路径下  
	 * @param projectId
	 * @param userId
	 * @param workgroupId
	 * @param evtcaseInstId
	 * @param docType
	 * @param creatOrnot
	 * @return
	 * @throws Exception
	 */
    @SuppressWarnings("deprecation")
	public synchronized String downloadFileByUrl(String projectId,String userId,String workgroupId,String evtcaseInstId,String docType,String creatOrnot) throws Exception {   
    	String msg = "1";//"1":默认为创建成功的提示信息 "2":标识创建失败
    	String srcUrl = "";  //报告服务器的执行路径
        HttpResponse response = null;   
        FileOutputStream out = null; 
        HttpClient httpclient = null;
        HttpGet httpget = null;
        long time1 = System.currentTimeMillis();
    	//获取保存后的路径 
		TProjDoc projDoc = projectDocDao.findFileByType(userId, Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId);
		if(projDoc == null || (projDoc != null && CommonUtils.isNotNull(creatOrnot) && creatOrnot.equals("1"))){   //FT_任务编号_[FID]
			 try {    
				 //获取报告服务器的执行路径
				    srcUrl = xmlPathDef.getActionUrl(docType, projectId,userId,workgroupId,evtcaseInstId);
				   
			        HttpParams httpParams = new BasicHttpParams(); 
			        // 设置最大连接数  
			        ConnManagerParams.setMaxTotalConnections(httpParams, 1);  
			        // 设置获取连接的最大等待时间  
			        //ConnManagerParams.setTimeout(httpParams, 6000);
			        // 设置每个路由最大连接数  
			        ConnPerRouteBean connPerRoute = new ConnPerRouteBean(1);  
			        ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute); 
			        // 设置连接超时时间  
			        HttpConnectionParams.setConnectionTimeout(httpParams, 6000);  
			        // 设置读取超时时间  
			        if(docType.toString().equals(XmlPathDef.SPOTTEST_DOC) && docType.toString().equals(XmlPathDef.FTEST_DOC)){
			        	HttpConnectionParams.setSoTimeout(httpParams, 2400000);  
			        }else{
			        	HttpConnectionParams.setSoTimeout(httpParams, 600000);
			        }
			        
			        
			        SchemeRegistry registry = new SchemeRegistry();  
			        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
			        registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
			        
			        ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams, registry); 
			        
				    httpclient = new DefaultHttpClient(connectionManager, httpParams);  
				    
			        httpget = new HttpGet(srcUrl);  
			        //执行返回
		            response = httpclient.execute(httpget);
		            //如果是本机既当服务器,又当报表服务器,那么就只生成一遍
		            String ipvalues = xmlPathDef.getRepUrl();
		            if(CommonUtils.isNotNull(ipvalues)){
		            	if(ipvalues.indexOf(":") != -1){
		            		ipvalues = ipvalues.substring(0,ipvalues.lastIndexOf(":"));
		            	}
		            }
		            HttpEntity entity = response.getEntity();
		                		//获取保存后的路径 
	                		    projDoc = projectDocDao.findFileByType(userId,Integer.parseInt(docType), Long.parseLong(projectId), workgroupId,evtcaseInstId);
	                			String filePath = "";
	                			if(projDoc != null)
	                				filePath = projDoc.getPath();
	                			if(CommonUtils.isNotNull(filePath)){
	                				String basepath = XmlPathDef.getBasePath();
	                				String outFilePath = (basepath + filePath).replaceAll("\\\\", "\\/");
	                				XmlPathDef.isExists(outFilePath);
	                				File wdFile = new File(outFilePath); 
	    	     		            out = new FileOutputStream(wdFile);
		     		                int l;   
		     		                byte[] tmp = new byte[2048];   
		     		                while ((l = instream.read(tmp)) != -1) {  
		     		                    out.write(tmp, 0, l);   
		     		                  }   
		     		                out.flush();
		     		                out.close(); 
		     		               System.out.println("****************************** ");
		     					   System.out.println("");
		     					   System.out.println("*************** 恭喜! 报告创建成功   结束   ***************");
		     					   System.out.println("");
	                			}else{
	                				msg = "8";//说明word创建成功,但是数据没有保存成功
	                				response = null;
	                			}
		                }else{
		                	msg = "2";
		              }
		        } catch (ClientProtocolException e) {   
		        	msg = "7";
		            e.printStackTrace();   
		        } catch (IOException e) {
		        	msg = "7";
		        	logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时" + e.getMessage());  
		            e.printStackTrace();   
		        }finally{   
		            if(out!=null){   
		                try {   
		                    out.close();  
		                } catch (IOException e) {   
		                	msg = "7";
		                	logger.error("数据库报告服务器地址配置错误或网络不通!!2.连接是否超时" + e.getMessage());  
		                    e.printStackTrace();   
		                }   
	                  } 
		            
	        }
		}
		long time2 = System.currentTimeMillis();
		long numTime = time2 - time1;
		if(docType.toString().equals(XmlPathDef.SPOTTEST_DOC) && docType.toString().equals(XmlPathDef.FTEST_DOC)){
			if(numTime >= 2401000){
				msg = "9";
				
			}
        }else{
            if(numTime >= 601000){
            	msg = "9";
			}
        }
		System.out.println(""); 
		String loggerinfo = "********* 报告类型为 :" +  docType + " 执行时间为: " + (time2 - time1) /1000  + " 秒!***************";
		System.out.println(loggerinfo); 
		System.out.println(""); 
		System.out.println("*****************************"); 
		logger.info(loggerinfo);
        return msg;
    } 

这个方法还有待优化和调整,现在我主要说明他的作用:

首先使用了synchronized 关键字 意思说使用同步的方式,让每次只有一个线程运行这个方法(其实如果是大数量的并发,就不能这样写了,自己去摸索吧)。然后在方法体中,使用了一个httpclient技术,这个主要是调用远程的服务返回对象流,在我这里就是调用另外一个服务器的代码,去生成报告,

然后将word报告的流返回来就ok,如果不明白httpclient的用法,请上网学一下,具体我就不说了。(下节我会贴出相应的代码

最后通过httpclient的返回流写成word文档就行了(其实里面还有一些判断什么的,比如:最后返回流是否是word流啊,什么的 都需要判断的,我都去掉了,代码太多),返回一个状态码给action就完毕。

未完待续





抱歉!评论已关闭.