Java根據word模板生成word文檔之後臺解析和實現及部分代碼(一)

        後臺主要工作是解析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就完畢。

未完待續





發佈了36 篇原創文章 · 獲贊 18 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章