时间:2021-07-01 10:21:17 帮助过:3人阅读
excel导出分成两部分内容:生成excel文件和下载excel文件 excel的文件生成在程序后台执行,前端不必等待,可进行其他后台操作 增加下载文件页面,显示excel文件生成的进度,完成后,方可下载生成的excel文件 文件生成后,点击下载方可下载相应的文件
1$struserdata = <<<Eof 2 3 xmlns:x="urn:schemas-microsoft-com:office:excel" 4 xmlns="http://www.w3.org/TR/REC-html40"> 5 6 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 7 8 9 10 12 13 14 1516 17 Eof;
3 4 5 6 Eof;View Code
文件的结尾: 1$struserdata = <<<Eof 2
场景:
用户点击 生成excel后,跳转到下载页面,程序在后台执行,用户可不必等待生成完成,可执行其他操作;
下载页面可看到文件生成的进度以及是否可下载状态
思路:
点击 生成excel,显示下载页面 ---> show_download方法
生成excel ---> create_excel 方法
1// $cmd = "/usr/bin/php /home/xxx/xxx.php " . $strjoin . " >/dev/null & "; 2 // $a=exec($cmd, $out, $returndata);345$command = "/usr/bin/php ".STATISTIC_EXPORT_SCRIPT_DIR."xxx.php " . "'" .$strjoin ."'". " " . $uid . " ". $action ." & "; 6$process = proc_open($command, array(),$pipes); 7$var = proc_get_status($process); 8proc_close($process); 9$pid = intval($var['pid'])+1;
1set_time_limit(0); //取消脚本运行时间的超时上限23ignore_user_abort(TRUE); //后台运行,不受用户关闭浏览器的影响
1$statistic = call_user_func(array('shellscript','get_result'),$url,$params); 2if(!is_object($statistic) || !isset($statistic->data->items)){ 3usleep(400000);//停止400毫秒4$statistic = call_user_func(array('shellscript','get_result'),$url,$params); 5 }
第一次请求api的时候,根据返回的total总数,以及pagesize,确定要请求的次数count; 这样便可知道要请求api的次数(分页请求api),在写入数据文件的同时,同时写入进度文件flag_data.xsl;
数据格式大约是(以逗号分割)
1,5
2,5
...然后显示文件进度的时候,读取进度文件,这样变可知道数据文件大体的进度 前端js处理时,几秒读取一次相应的方法(如果都100%进度,可停止请求方法),从而实现动态查看文件的生成进度
1publicfunction execscript_process(){ 2$this->load->library('smarty'); 3$file_arr_str = array(); 4$file_arr_process = array(); 5$file_arr_name = array(); 6$file_arr = array(); 7$refresh_flag = 'yes'; 8$uid = $_REQUEST['uid']; 9$url_dir = STATISTIC_EXPORT_FILE_DIR.$uid .'/';//@todo10if(!is_dir($url_dir)){ 11 @mkdir($url_dir,0777); 12 } 13$files = scandir($url_dir); 1415if(!empty($files)){ 16foreach ($filesas$key => $value) { 17if($value!='.' && $value!='..'){ 18if(substr($value, 0 , 5)=="flag_"){ 19$file_size = filesize($url_dir . $value); 20if(!empty($file_size)){ 21$fhandle = fopen($url_dir . $value, 'rb+'); 22fseek($fhandle, -1, SEEK_END); 23$fstr = ''; 24while(($c = fgetc($fhandle)) !== false) { 25if($c == "\n" && $fstr) break; 26$fstr = $c . $fstr; 27fseek($fhandle, -2, SEEK_CUR); 28 } 29fclose($fhandle); 30$fstr = trim($fstr); 31$fstr_arr_str = explode(',', $fstr); 32$file_arr_process[] = 100 * number_format($fstr_arr_str[0]/$fstr_arr_str[1],2).'%'; 33$file_arr_name[] = substr($value,5); 34 } 35 } 36 } 37 } 3839foreach ($file_arr_processas$key => $value) { 40if($value != '100%'){ 41$refresh_flag = 'no'; 42break; 43 } 44 } 45 } 4647$file_arr = array( 48 'process' => $file_arr_process, 49 'name' => $file_arr_name, 50 'refresh_flag' => $refresh_flag51 ); 52$file_arr_json = json_encode($file_arr); 53echo$file_arr_json; 54 }
1publicfunction execscript_download(){ 2$filename = $_REQUEST['filename']; 3$uid = $_REQUEST['uid']; 4$file_dir = STATISTIC_EXPORT_FILE_DIR.$uid.'/'.$filename; 5if (!file_exists($file_dir)){ 6header("Content-type: text/html; charset=utf-8"); 7echo "File not found!"; 8exit; 9 } else { 10ini_set("memory_limit","500M"); 11header('Content-Description: File Transfer'); 12header('Content-Type: application/octet-stream'); 13header('Content-Disposition: attachment; filename='.basename($file_dir)); 14header('Content-Transfer-Encoding: binary'); 15header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT'); 16header('Cache-Control: must-revalidate,post-check=0, pre-check=0'); 17header('Pragma: public'); 18header('Content-Length: ' . filesize($file_dir)); 19readfile($file_dir); 20 } 2122 }
现象描述:
当在后台点击生成文件,跳转到下载页的时候,因为下载页是显示文件进度的页面, 竟然出现有时候有刚刚点击的文件进度,有时候没有,就感觉没有生成相应的文件一样;
解决方法:
因为数据文件和进度文件都是生成在程序的某个文件夹file中,所以读取的时候都是读取的文件夹下的文件,从而判断显示进度;
后面才知道,由于后台程序有两台服务器,导致读取以及下载的时候找不到相应的文件夹,两个服务器相应的文件夹弄个共享目录就可以了
1publicfunction execscript_process_show(){ 2$this->load->library('smarty'); 3$uid = $_REQUEST['uid']; 4$url_dir = STATISTIC_EXPORT_FILE_DIR.$uid .'/';//@todo 5if(!is_dir($url_dir)){ 6 @mkdir($url_dir,0777); 7 } 8$files = scandir($url_dir); 9if(!empty($files)){ 10foreach ($filesas$key => $value) { 11if($value!='.' && $value!='..'){ 12foreach ($filesas$key => $value) { 13if($value!='.' && $value!='..'){ 14if(substr($value, 0 , 5)!="flag_"){ 15$filenamedate = substr($value, 0,10); 16$today = date('Y-m-d',time()); 17$filenamedate = date('Y-m-d',strtotime($filenamedate)+(STATISTIC_FILE_EXPIRE_DAY-1)*24*3600); 18if($today>$filenamedate){//文件过期19 @unlink($url_dir . $value); 20 @unlink($url_dir . 'flag_' . $value); 21 } 22 } 23 } 24 } 25 } 26 } 27 } 2829$this->smarty->assign('uid',$uid); 30$this->smarty->display('interact/statistic/execscript.tpl'); 31 }
http://blog.csdn.net/yysdsyl/article/details/4636457 http://www.codesky.net/article/201202/163385.html http://www.cnblogs.com/zdz8207/p/3765567.html http://blog.163.com/mojian20040228@126/blog/static/4112219320097300922992/ http://php.com/manual/en/features.commandline.php http://blog.csdn.net/yangjun07167/article/details/5603425 http://blog.csdn.net/yunsongice/article/details/5445448 http://www.cppblog.com/amazon/archive/2011/12/01/161281.aspx http://blog.51yip.com/tag/proc_open http://www.justwinit.cn/post/1418/ http://limboy.me/tech/2010/12/05/php-async.html
以上就介绍了我所经历的大文件数据导出(后台执行,自动生成),包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。