关于Easy UI中文件上传处理进度条的实现

   主要思路是用线程池池去处理上传任务,并计算上传进度,将进度保存到session中。前端通过一个定时器按固定时间调用获取进度条的百分比,更新进度条进度。


前端相关代码:

[javascript]  view plain  copy
  1. "text/javascript" src="${pageContext.request.contextPath }/static/scripts/easyui/jquery.min.js">  
  2. "text/javascript" src="${pageContext.request.contextPath }/static/scripts/easyui/jquery.easyui.min.js">  
  3. "text/javascript" src="${pageContext.request.contextPath }/static/scripts/easyui/easyui-lang-zh_CN.js">  

[javascript]  view plain  copy
  1. "stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/scripts/easyui/themes/default/easyui.css">  
  2. "stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/scripts/easyui/themes/icon.css">  
  3. "stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/styles/common.css">  
  4. "stylesheet" type="text/css" href="${pageContext.request.contextPath }/static/scripts/easyui/themes/demo.css">  

[javascript]  view plain  copy
  1. "progressDlg" class="easyui-dialog" title="执行进度" style="width: 600px;hight:400px;" data-options="iconCls:'icon-save',closed:true,resizable:true,modal:true,collapsible:true, buttons: '#progressDlgBtns'">  
  2.         "padding: 10px 60px 20px 60px">  
  3.           "p" class="easyui-progressbar" style="width:400px;">
  
  •         
  •   
  •     
  •   
  •     "progressDlgBtns" style="width: 600px;">  
  •         "javascript:void(0)" class="easyui-linkbutton" style="padding: 4px;" οnclick="javascript:$('#progressDlg').dialog('close')">关闭  
  •     
  •   


    相关的js代码:
    [javascript]  view plain  copy
    1. //展示进度条  
    2.   var timerId;  
    3.   function showCheckProgress(){  
    4.     $('#progressDlg').dialog('open');  
    5.     //想要修改进度条的颜色去css文件中去修改    
    6.       $('#p').progressbar({    
    7.           value : 0,          //设置进度条值 默认0    
    8.           text : '{value}%'  //设置进度条百分比模板 默认 {value}%    
    9.           //在value改变的时候触发    
    10.           /*onChange : function (newValue, oldValue) {   
    11.               console.log('新:' + newValue + ',旧:' + oldValue);   
    12.           },  */  
    13.       });   
    14.      timerId = window.setInterval(getCheckProgress,1000);  
    15.   }  
    16.     
    17.     
    18.   //通过post请求得到进度  
    19.   function getCheckProgress(){  
    20.     var progressUrl = $('#getProgressUrl').val();  
    21.            //使用JQuery从后台获取JSON格式的数据  
    22.            $.ajax({  
    23.             type:"post",//请求方式  
    24.             url:progressUrl,//发送请求地址  
    25.             timeout:3000,//超时时间:30秒  
    26.             dataType:"json",//设置返回数据的格式  
    27.             //请求成功后的回调函数 data为json格式  
    28.             success:function(data){  
    29.              if(data.progressValue>=100){  
    30.                  window.clearInterval(timerId);  
    31.                  $('#dg').datagrid('load');  
    32.                  $('#importBtn').css('display','inline-block');  
    33.                  $('#showProgress').css('display','none');  
    34.              }  
    35.              $('#p').progressbar('setValue',data.progressValue);  
    36.             },  
    37.             //请求出错的处理  
    38.             error:function(){  
    39.              window.clearInterval(timerId);  
    40.              //alert("请求出错");  
    41.             }  
    42.            });  
    43.   }  


    文件上传界面:enctype="multipart/form-data"

    [javascript]  view plain  copy
    1. "importDlg" class="easyui-dialog" title="批量导入" style="width:400px;padding:30px 70px 50px 70px">  
    2.          "importForm" method="post"  enctype="multipart/form-data">  
    3.              "margin-bottom:20px">  
    4.                 "uploadFile" class="easyui-filebox" name="uploadFile" data-options="prompt:'请选择要导入的文件……'" style="width:100%">  
    5.             
      
  •             
      
  •                 "#" id="doImportBtn"  class="easyui-linkbutton" style="width:100%">上传  
  •                 "#" id="cancelImportBtn"  class="easyui-linkbutton" style="width:100%">取消  
  •             
  •   
  •              
  •     
  •   


    springmvc中对上传文件的通用属性配置:

    [html]  view plain  copy
    1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">     
    2.           <property name="maxUploadSize"><value>2097152value>property>  
    3.           <property name="defaultEncoding"><value>UTF-8value>property>   
    4.     bean>   



    后台java代码:

    [java]  view plain  copy
    1. /** 
    2.      * 批量导入贷中记录 
    3.      */  
    4.     @RequestMapping(value = "/action/import")  
    5.     @ResponseBody  
    6.     public Result importList(HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile uploadFile) {  
    7.         HttpSession session = request.getSession();  
    8.         session.setAttribute("progressValue"0.0);  
    9.         Result result = new Result();  
    10.         try {  
    11.             String fileName = uploadFile.getOriginalFilename();  
    12.             long size = uploadFile.getSize();//文件大小,字节  
    13.             long maxSize =  2048000;//2M  
    14.             String fileType = StringUtils.split(fileName,".")[1];  
    15.             if(!StringUtils.equals(fileType, "xlsx") && !StringUtils.equals(fileType, "xls")){  
    16.                 result.setCode(0);  
    17.                 result.setMsg("请选择xlsx或xls格式的文件");  
    18.                 return result;  
    19.             }  
    20.             if(size > maxSize){  
    21.                 result.setCode(0);  
    22.                 result.setMsg("批量导入的文件大小不能超过2M");  
    23.                 return result;  
    24.             }  
    25.             String batchNo = "DZ" + DateUtil.getCurrentDateTime();  
    26.             List jobList = parseExcel( uploadFile.getInputStream(),session,batchNo);  
    27.               
    28.             if(jobList!=null && jobList.size()>3000){  
    29.                 result.setCode(0);  
    30.                 result.setMsg("单次校验记录数不能超过3000");  
    31.                 return result;  
    32.             }  
    33.               
    34.             //先全部批量插入数据库  
    35.             rcsCreditManageJobServiceImpl.batchAdd(jobList);  
    36.             result = rcsCreditManageJobServiceImpl.batchCheckCreditIn(session,jobList,batchNo);  
    37.         } catch (Exception e) {  
    38.             result.setCode(0);  
    39.             result.setMsg("批量校验操作失败!");  
    40.             log.error("【批量校验操作异常】:"+ e.getMessage(),e);  
    41.         }  
    42.         return result;  
    43.     }  
    44.       



    这里使用了多个线程,共同消费jobList中任务,每个Runnable中都传入了相同的对象progress来保存共同的信息,如批次号,总任务数,完成的任务数等。
    [java]  view plain  copy
    1. /** 
    2.      * 批量校验 
    3.      */  
    4.     @Override  
    5.     public Result batchCheckCreditIn(HttpSession session,List jobList,String batchNo) {  
    6.         Result result = new Result();  
    7.         try {  
    8.             int totalSize = jobList.size();  
    9.             TaskProgress progress = new TaskProgress(totalSize,batchNo);  
    10.             for (RcsCreditManageJob job : jobList) {  
    11.                 taskExecutor.execute(new dzCheckTask(progress,job,session));  
    12.             }  
    13.             result.setCode(1);  
    14.             result.setMsg("批量校验申请提交完毕!");  
    15.         } catch (Exception e) {  
    16.             e.printStackTrace();  
    17.             result.setCode(0);  
    18.             result.setMsg("批量校验申请提交失败!");  
    19.         }  
    20.         return result;  
    21.     }  



    [java]  view plain  copy
    1. /** 
    2.  * 执行校验的任务 
    3.  */  
    4. private class dzCheckTask implements Runnable {  
    5.     private RcsCreditManageJob job;  
    6.     private TaskProgress progress;  
    7.     private HttpSession session;  
    8.       
    9.     public dzCheckTask(TaskProgress progress,RcsCreditManageJob job,HttpSession session) {  
    10.         this.job = job;  
    11.         this.progress = progress;  
    12.         this.session=session;  
    13.     }  
    14.   
    15.     public void run() {  
    16.         try {  
    17.             EngineCreditInDto ec = new EngineCreditInDto();  
    18.             ec.setName(job.getUserName());//用户名称  
    19.             ec.setMobile(job.getMobile());//手机号  
    20.             ec.setIdCard(job.getCertid());//身份证号  
    21.             ec.setCurrTime(DateUtil.getCurrentPrettyDateTime());//当前时间    
    22.             ec.setCallType(job.getCallType());  
    23.               
    24.             riskServiceFacade.evaluateCreditInCheck(ec);  
    25.             //根据表数据  
    26.             Map paramMap = new HashMap();  
    27.             paramMap.put("execTime", DateUtil.getCurrentDateTime());  
    28.             paramMap.put("certid", ec.getIdCard());  
    29.             paramMap.put("batchNo", progress.getTaskNo());  
    30.             rcsCreditManageJobMapper.updateExcuTimeByMap(paramMap);  
    31.             //更新进度  
    32.             session.setAttribute("progressValue", progress.computeProgress());  
    33.               
    34.             Thread.sleep(200);  
    35.         } catch (InterruptedException e) {  
    36.             e.printStackTrace();  
    37.         }  
    38.     }  
    39. }  


    [java]  view plain  copy
    1. /** 
    2.  * 任务进度实体 
    3.  */  
    4. public class TaskProgress {  
    5.       private int totalSize;//任务总数  
    6.       private int completeSize;//任务完成数  
    7.       private String taskNo;//任务批次  
    8.       public double taskProgress;//任务进度  
    9.               
    10.     public TaskProgress(int totalSize, String taskNo) {  
    11.         this.totalSize = totalSize;  
    12.         this.taskNo = taskNo;  
    13.     }  
    14.       
    15.       
    16.   
    17.     /** 
    18.      * 用同步代码块实现 
    19.      *  
    20.      * @param money 
    21.      */  
    22.     public double computeProgress() {  
    23.         synchronized (this) {  
    24.             BigDecimal   b1   =   new   BigDecimal(Double.toString(this.getTotalSize()));   
    25.             //没调用一次,完成一笔  
    26.             int newCompleteSize = this.getCompleteSize() + 1;  
    27.             this.setCompleteSize(newCompleteSize);  
    28.               
    29.             BigDecimal   b2   =   new   BigDecimal(Double.toString(newCompleteSize));    
    30.             double taskProgress = b2.divide(b1,2,RoundingMode.HALF_UP).multiply(new BigDecimal("100")).doubleValue();  
    31.             this.setTaskProgress(taskProgress);  
    32.             return taskProgress;  
    33.         }  
    34.     }  
    35.       
    36.       
    37.       
    38.     public int getTotalSize() {  
    39.         return totalSize;  
    40.     }  
    41.     public void setTotalSize(int totalSize) {  
    42.         this.totalSize = totalSize;  
    43.     }  
    44.     public int getCompleteSize() {  
    45.         return completeSize;  
    46.     }  
    47.     public void setCompleteSize(int completeSize) {  
    48.         this.completeSize = completeSize;  
    49.     }  
    50.   
    51.     public String getTaskNo() {  
    52.         return taskNo;  
    53.     }  
    54.   
    55.     public void setTaskNo(String taskNo) {  
    56.         this.taskNo = taskNo;  
    57.     }  
    58.   
    59.     public double getTaskProgress() {  
    60.         return taskProgress;  
    61.     }  
    62.     public void setTaskProgress(double taskProgress) {  
    63.         this.taskProgress = taskProgress;  
    64.     }  
    65.   
    66. }  

    spring mvc中配置线程池的bean

    [html]  view plain  copy
    1.     
    2. lt;bean id="taskExecutor"    
    3.    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">    
    4.        
    5.    <property name="corePoolSize" value="10" />    
    6.        
    7.    <property name="maxPoolSize" value="30" />    
    8.        
    9.    <property name="queueCapacity" value="3000" />    
    10.        
    11.    <property name="keepAliveSeconds" value="300" />    
    12.        
    13.    <property name="rejectedExecutionHandler">    
    14.        <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />    
    15.    property>    
    16. lt;/bean>   


    最后是相应获取进度的请求,从session中获取最新的进度:

    [java]  view plain  copy
    1. /** 
    2.      * 得到处理进度 
    3.      */  
    4.     @RequestMapping(value = "/action/getProgressValue")  
    5.     @ResponseBody  
    6.     public Map getProgressValue( HttpSession session) {  
    7.         double progress = (double) session.getAttribute("progressValue");  
    8.         Map map = new HashMap();  
    9.         map.put("progressValue", progress);  
    10.         return map;  
    11.     }  


    比较粗糙的实现,但是能跑能跳,本博客只是自己的工作记录之用,实现方式未必优雅。

    如你有更好的方法,欢迎指教。

    你可能感兴趣的:(easyUI)