php 导出excel 进度条显示

下载大量数据到Excel表格时,无法查看下载的实时进度。

效果展示:

1、统计数据数量:


2、显示数量:


3、下载进度条展示:



代码:

1、前端显示代码

[html]  view plain  copy
  1. <link rel="stylesheet" href="__PUBLIC__/javascripts/admin/artdialog/skins/default.css" type="text/css"/>  
  2. <script type="text/javascript" src="__PUBLIC__/javascripts/admin/jquery-1.7.2.min.js"></script>  
  3. <script rel="stylesheet" src="__PUBLIC__/javascripts/admin/artdialog/jquery.artDialog.js"></script>  
  4. <script rel="stylesheet" src="__PUBLIC__/javascripts/admin/artdialog/plugins/iframeTools.source.js"></script>  
  5.   
  6. <div class="content-search">  
  7.     <form action="{:U('/Sale/ImportB2bHistory/downloadOrders')}" method="get" class="form-inline" id="downloadOrders" target="_blank">  
  8.         <div class="control-group">  
  9.             <label class="control-label">发货日期  
  10.                 <input type="datetime" placeholder="起始日期" name="begin_time" value="{$condition.begin_time}" id="begin_time"  
  11.                        onClick="WdatePicker({dateFmt:'yyyy-MM-dd'})"  
  12.                        class="Wdate"/>  
  13.             </label>  
  14.             <label class="control-label">发货日期  
  15.                 <input type="datetime" placeholder="结束日期" name="end_time" value="{$condition.end_time}" id="end_time"  
  16.                        onClick="WdatePicker({dateFmt:'yyyy-MM-dd'})"  
  17.                        class="Wdate"/>  
  18.             </label>  
  19.         </div>  
  20.         <div>  
  21.             <button style="margin-right: 10%" class="btn btn-primary" type="button" onclick="processBar()">  
  22.                 <i class="icon-download icon-white"></i> 导出  
  23.             </button>  
  24.         </div>  
  25.     </form>  
  26. </div>  
  27. <script type="text/javascript" language="javascript">  
  28.     var search_uri  = "{:U('downloadOrders')}";// 请求地址  
  29.     var process_uri     = "{:U('getProcess')}";// 请求地址  
  30.     var win = window.top;    // 顶层页面window对象  
  31.     var processBar2 ;  
  32.   
  33.     // processBar函数如下  
  34.     function processBar() {  
  35.         tip();// 弹出统计总数对话框  
  36.         doRequest();  
  37.     }  
  38.   
  39.     function doRequest() {  
  40.         var begin_time = $("#begin_time").val();  
  41.         var end_time = $("#end_time").val();  
  42.   
  43.         //ajax请求总数  
  44.         $.post(search_uri, {begin_time: begin_time, end_time: end_time}, function (json) {  
  45.             var return_arr = jQuery.parseJSON(json);  
  46.             var num = return_arr.total;// 任务总数  
  47.             var processnum = return_arr.processnum;// 当前数  
  48.   
  49.             if (num == 0) {  
  50.                 poptip.title('系统消息');  
  51.                 poptip.content('查询结果为空,不能进行数据导出');  
  52.             } else {  
  53.                 poptip.close();// 关闭提示框  
  54.                 doConfirm(num, processnum);// 弹出确认下载交互界面  
  55.             }  
  56.         });  
  57.     }  
  58.   
  59.     // 弹出确认下载  
  60.     function doConfirm(num, processnum) {  
  61.         var msg = '总有 <span style="color: red">' + num  
  62.                 + '</span> 行,可能会时间较长。<br />您还需要继续吗?';  
  63.         var content = '<progress max="100" value="0" id="processbar" style="text-align: center;width: 300px;"></progress><br/>' +  
  64.                 '<span id="progress_info"></span>';  
  65.   
  66.         // 提示是否继续  
  67.         art.dialog.confirm(msg, function () {  
  68.             // 弹出进度条  
  69.             showProcess = art.dialog.through({  
  70.                 title: '数据导出进度',  
  71.                 content: content,  
  72.                 lock: true,  
  73.                 width: 350,  
  74.                 opacity: '.1',  
  75.                 button: [  
  76.                     {  
  77.                         name: '取消',  
  78.                         callback: function () {  
  79.                             window.location.reload();  
  80.                         }  
  81.                     }  
  82.                 ]  
  83.             });  
  84.             showProcess.show();  
  85.   
  86.             win.$('#processbar').val(processnum * 100 / num);  
  87.             win.$('#progress_info').show().text('正在导出,请等待,请勿关闭窗口...');//当继续的时候  
  88.   
  89.             $.ajax({  
  90.                 url:"{:U('doDownloadOrders')}",  
  91.                 type:"post",  
  92.                 async:true,  
  93.                 error:function (data) {  
  94.                     alert("下载失败!");  
  95.                 },  
  96.                 success:function (data) {  
  97.                     clearInterval(processBar2);// 关闭自动定时执行  
  98.                     showProcess.close();  
  99.                     window.location.href = data;  
  100.                 }  
  101.             });  
  102.   
  103.             processBar2 = setInterval(sync_process, 1000);// 每隔1秒执行一次  
  104.         });  
  105.     }  
  106.   
  107.     // 获取进度  
  108.     function sync_process() {  
  109.         $.ajax({  
  110.             url:process_uri,  
  111.             type:"post",  
  112.             async:true,  
  113.             success:function (json) {  
  114.                 var return_arr = jQuery.parseJSON(json);  
  115.                 var num = return_arr.total;// 任务总数  
  116.                 var processnum = return_arr.processnum;// 当前数  
  117.                 update_process(num, processnum);  
  118.             }  
  119.         });  
  120.     }  
  121.   
  122.     /* 更新进度条 */  
  123.     function update_process(num, processnum) {  
  124.         win.$('#processbar').val(processnum * 100 / num);  
  125.     }  
  126. </script>  


2、服务器代码

[php]  view plain  copy
  1. /** 
  2.  * 导出客户订单下载 
  3.  */  
  4. public function downloadOrders(){  
  5.     // 查询条件  
  6.     $condition          = I('POST.',null,'trim');  
  7.     $datas              = $this->getDatas($condition);  
  8.   
  9.   
  10.     S('PROCESS_DOWNLOAD_DATA',$datas,60);// 缓存数据  
  11.     S('PROCESS_DOWNLOAD_TOTAL',count($datas),60);  
  12.     S('PROCESS_DOWNLOAD_PROCESSNUM',0);  
  13.   
  14.     $re_arr = array(  
  15.         'total'      => count($datas),  
  16.         'processnum' => 0,  
  17.     );  
  18.     echo json_encode($re_arr);  
  19.     exit;  
  20. }  
  21.   
  22. /** 
  23.  * 获取进度条的执行进度数据 
  24.  */  
  25. public function getProcess(){  
  26.     $re_arr = array(  
  27.         'total'      => S('PROCESS_DOWNLOAD_TOTAL'),  
  28.         'processnum' => S('PROCESS_DOWNLOAD_PROCESSNUM')  
  29.     );  
  30.   
  31.     echo json_encode($re_arr);  
  32.     exit;  
  33. }  
  34.   
  35.   
  36. /** 
  37.  * 生成要下载的文件 
  38.  */  
  39. public function doDownloadOrders(){  
  40.     $path =  'Cache/Runtime/Admin/downloads/';  
  41.     if (!is_dir($path)) {  
  42.         @mkdir($path, 0777, true);  
  43.     }  
  44.   
  45.     set_time_limit(0);  
  46.     session_write_close();// 断开AJAX请求,无需等待响应  
  47.     $datas = S('PROCESS_DOWNLOAD_DATA');  
  48.   
  49.     //  设置表头字段并指定展示顺序  
  50.     $firstLine = array('A','B','C');  
  51.   
  52.     import("Org.Excel.PHPExcel");// 导入扩展类  
  53.     $objPHPExcel = new \PHPExcel();// 实例化类  
  54.   
  55.     $objPHPExcel->getProperties()  
  56.         ->setCreator("123")  
  57.         ->setLastModifiedBy("123")  
  58.         ->setTitle("Office 2003 XLSX Test Document")  
  59.         ->setSubject("Office 2003 XLSX Test Document")  
  60.         ->setDescription("Test document for Office 2003 XLSX, generated using PHP classes.")  
  61.         ->setKeywords("office 2003 openxml php")  
  62.         ->setCategory("Test result file");  
  63.   
  64.     $objActSheet = $objPHPExcel->setActiveSheetIndex(0);// 设置当前的sheet  
  65.   
  66.     // EXCEL表头  
  67.     if($firstLine){  
  68.         $r = 'A';  
  69.         foreach($firstLine as $v){  
  70.             $objActSheet->setCellValue($r.'1',$v);  
  71.             $r ++;  
  72.         }  
  73.     }  
  74.     $i = 2;  
  75.     foreach($datas as $value)  
  76.     {  
  77.         $r = 'A';  
  78.         foreach($value as $value2)  
  79.         {  
  80.             if($r == 'B' || $r == 'P' || $r == 'Q'){  
  81.                 $objActSheet->setCellValueExplicit($r.$i$value2, \PHPExcel_Cell_DataType::TYPE_STRING);  
  82.             }else{  
  83.                 $objActSheet->setCellValue($r.$i$value2);  
  84.             }  
  85.             $r++;  
  86.         }  
  87.         $i++;  
  88.         S('PROCESS_DOWNLOAD_PROCESSNUM',$i-2);// 更新缓存的进度  
  89.     }  
  90.   
  91.     $filename = 'Orders'.date('YmdHis') . '.xls';  
  92.     $objPHPExcel->getActiveSheet()->setTitle('工作表1');// sheet标题  
  93.     $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel'Excel5');  
  94.     $objWriter->save($path.$filename);  
  95.   
  96.     echo '/'.$path.$filename// $_SERVER['HTTP_HOST'].'/'.$path.$filename;  
  97.     exit;  
  98. }  

JS发起请求后必须等待服务器返回结果才向下执行,才会解析后面请求的结果,这样导致下载数据到Excel文件中时不能再次发起请求读取下载进度。

在此session_write_close()函数端口AJAX请求,无需等待服务器返回结果,向下执行,该请求会正常执行完毕。

[php]  view plain  copy
  1. session_write_close();// 断开AJAX请求,无需等待响应   
[php]  view plain  copy
  1. <pre code_snippet_id="2173596" snippet_file_name="blog_20170208_4_6547481"></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <link rel="stylesheet" href="http://static.blog.csdn.net/public/res-min/markdown_views.css?v=2.0">  
  6.               
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Java中导出Excel时,可以采用jxl或poi等第三方库进行操作。在导出Excel的过程中,如果Excel文件过大或数据量较多,可能会导致导出时间较长,因此需要添加进度条来提示用户导出进度。 一般情况下,可以使用Swing组件中的JProgressBar(进度条)来实现进度条效果。在导出Excel的过程中,可以通过不断更新进度条的值来展示进度。在更新进度条时,需要注意线程同步问题,避免出现并发问题。 具体实现步骤如下: 1. 创建一个进度条(JProgressBar)并设定进度条的最大值(即导出数据总量); 2. 在导出Excel数据的过程中,根据实际情况更新进度条的值(使用setValue()方法); 3. 为了避免更新进度条与导出Excel数据的线程冲突,可以使用SwingWorker类来进行多线程操作; 4. 在导出完毕后,将进度条设置为完成状态(setValue(maximum))。 同时,为了让用户能够明确了解到导出进度,还可以在进度条下添加文字提示或使用弹窗等方式提醒用户导出进度。通过以上步骤,即可在Java中实现导出Excel进度条功能。 ### 回答2: Java导出Excel进度条在实际开发中很常见,对于数据量较大的导出操作尤其有用。常用的实现方式是利用多线程和Ajax技术配合完成。下面简单介绍一下具体步骤: 1. 在服务器端,将导出Excel的代码封装成一个单独的方法,并把方法放入一个线程中运行。 2. 在前端页面中,使用Ajax向服务器端发送请求,触发Excel导出操作,并异步获取服务器端返回的导出进度信息。 3. 在前端页面中实现进度条功能,即获取服务器端返回的导出进度信息,计算已完成的比例,并将进度条实时反映到页面上。 4. 当导出操作完成后,服务器端将导出结果存储到指定的位置并返回导出完成信息给前端页面,此时前端页面可以提示用户下载导出结果。 实现Java导出Excel进度条需要涉及到多线程,Ajax,进度条等相关技术,需要开发人员熟练掌握。正确使用这些技术可以大大提高导出操作的用户体验,减少用户等待时间,提高系统的可用性。 ### 回答3: 在Java中,我们可以使用Apache POI库来创建和操作Excel文件。但是,当我们从数据库或其他数据源中提取大量数据并写入Excel文件时,这可能需要一些时间。在这种情况下,为了提高用户体验并显示进度,我们可以创建一个进度条。 首先,我们需要创建一个工作表,并确定需要写入Excel的列和行的数量。然后,我们可以创建一个进度条的GUI组件并在主线程中运行。我们可以使用Swing的JProgressBar组件,并将其添加到JFrame的容器中。 接下来,我们需要在程序中安排一个方法来更新进度条。在此方法中,我们要计算导出过程的百分比,并将其传递给进度条。在Apache POI中,我们可以使用Row和Cell类来写入数据。在写入每个单元格之后,我们可以使用更新百分比的方法来调用进度条,以便在GUI上添加进度。 完成导出后,我们可以使用Swing的JOptionPane来提示用户Excel文件已成功生成,并提供打开文件所需的选项。 最后,为了确保在开始导出之前显示进度条GUI,我们可以使用SwingUtilities工具类的invokeLater()方法在事件调度线程上执行GUI初始化任务。这将确保GUI在导出开始之前准备就绪,并且不会与导出线程发生冲突。 总之,Java导出Excel进度条可以通过创建Swing的JProgressBar组件和更新方法来实现。通过在事件调度线程上初始化GUI,并在导出过程中更新进度条,我们可以提高用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值