php 后台导出数据用户,我所经历的大文件数据导出(后台执行,自动生成),数据导出自动生成_PHP教程...

这篇博客介绍了如何优化后台大文件,如Excel,的导出功能,避免用户长时间等待。通过后台执行生成任务,用户可以继续其他操作,同时通过进度文件实时显示文件生成进度。文章详细阐述了使用HTML表格格式,命令行执行PHP脚本,以及文件进度的检查和下载文件的实现方法。此外,还提到了线上环境遇到的问题及解决方案,以及后续的文件清理优化。
摘要由CSDN通过智能技术生成

我所经历的大文件数据导出(后台执行,自动生成),数据导出自动生成

一、前言

记录一下以前做的后台excel格式导出统计信息的功能,也是最近同事问到了相关东西,一时之间竟忘了具体的细节,因此记录一下;

大家知道,excel导出数据的功能,后台几乎是必须功能,一般都是点击后,生成文件然后自动下载,

如果是数据量小的话,一下子便可请求完成,从而下载到本地;

但是,如果数据量特别大的时候,页面就必须一直在等待,直到写入excel成功,

这样便影响了后台使用者无法操作其他页面,为此,对excel导出做了以下功能优化:

二、生成excel文件

生成excel文件的方法有很多,暂不一一记录,只是记录本次的方法;

这里用到了table的html格式,以及相应的excel的声明

(隐约记得其他的方法用office07打开的时候好像是乱码,后面尝试用csv格式文件,可还是乱码,所以用了table的形式)

文件的开头:

1Z3112235-0.gif

php-weizijiaocheng-289143.html1 $struserdata = <<

4 xmlns="http://www.w3.org/TR/REC-html40">

5

6 span>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

15

16 17 Eof;

View Code

文件的结尾:

1Z3112235-0.gif

php-weizijiaocheng-289143.html1 $struserdata = <<

3

4

5

6 Eof;

View Code

当然,文件中间就是一些tr td 标签了。

三、让程序在后台执行

场景:

用户点击 生成excel后,跳转到下载页面,程序在后台执行,用户可不必等待生成完成,可执行其他操作;

下载页面可看到文件生成的进度以及是否可下载状态

思路:

点击 生成excel,显示下载页面 ---> show_download方法

生成excel ---> create_excel 方法

show_download方法中调用 create_excel方法,而show_download 方法中,自己用了一下命令行执行程序的方式,

利用php命令行的方式,把参数传递给 create_excel方法

1 //$cmd = "/usr/bin/php /home/xxx/xxx.php " . $strjoin . " >/dev/null & ";2 // $a=exec($cmd, $out, $returndata);

3

4

5 $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);8 proc_close($process);9 $pid = intval($var['pid'])+1;

而在create_excel方法中:

需填写以下代码:

1 set_time_limit(0); //取消脚本运行时间的超时上限

2

3 ignore_user_abort(TRUE); //后台运行,不受用户关闭浏览器的影响

调用相关的api得到数据:

1 $statistic = call_user_func(array('shellscript','get_result'),$url,$params);2 if(!is_object($statistic) || !isset($statistic->data->items)){3 usleep(400000);//停止400毫秒

4 $statistic = call_user_func(array('shellscript','get_result'),$url,$params);5 }

四、显示文件生成进度

但是怎么显示相应的文件生成进度呢,怎么知道文件到底生成好了没有呢?

这里,我用到的方法是,在写入数据文件的时候data.xsl,每个数据文件都生成一个对应的文件进度文件,暂且称为flag_data.xsl;

思路:

查看文件的进度方法:

1Z3112235-0.gif

php-weizijiaocheng-289143.html1 public functionexecscript_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 .'/';//@todo

10 if(!is_dir($url_dir)){11 @mkdir($url_dir,0777);12 }13 $files = scandir($url_dir);14

15 if(!empty($files)){16 foreach ($files as $key => $value) {17 if($value!='.' && $value!='..'){18 if(substr($value, 0 , 5)=="flag_"){19 $file_size = filesize($url_dir . $value);20 if(!empty($file_size)){21 $fhandle = fopen($url_dir . $value, 'rb+');22 fseek($fhandle, -1,SEEK_END);23 $fstr = '';24 while(($c = fgetc($fhandle)) !== false) {25 if($c == "\n" && $fstr) break;26 $fstr = $c . $fstr;27 fseek($fhandle, -2,SEEK_CUR);28 }29 fclose($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 }38

39 foreach ($file_arr_process as $key => $value) {40 if($value != '100%'){41 $refresh_flag = 'no';42 break;43 }44 }45 }46

47 $file_arr = array(48 'process' => $file_arr_process,

49 'name' => $file_arr_name,

50 'refresh_flag' => $refresh_flag

51 );52 $file_arr_json = json_encode($file_arr);53 echo $file_arr_json;54 }

View Code

五、下载文件

文件的下载就好说了,既然已经都生成成功,下载的方法如下:

1 public functionexecscript_download(){2 $filename = $_REQUEST['filename'];3 $uid = $_REQUEST['uid'];4 $file_dir = STATISTIC_EXPORT_FILE_DIR.$uid.'/'.$filename;5 if (!file_exists($file_dir)){6 header("Content-type: text/html; charset=utf-8");7 echo "File not found!";8 exit;9 } else{10 ini_set("memory_limit","500M");11 header('Content-Description: File Transfer');12 header('Content-Type: application/octet-stream');13 header('Content-Disposition: attachment; filename='.basename($file_dir));14 header('Content-Transfer-Encoding: binary');15 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');16 header('Cache-Control: must-revalidate,post-check=0, pre-check=0');17 header('Pragma: public');18 header('Content-Length: ' . filesize($file_dir));19 readfile($file_dir);20 }21

22 }

六、上线后出现的问题

本地本来已经测试完毕,可上线后,却出现了奇怪的问题;

现象描述:

当在后台点击生成文件,跳转到下载页的时候,因为下载页是显示文件进度的页面,

竟然出现有时候有刚刚点击的文件进度,有时候没有,就感觉没有生成相应的文件一样;

解决方法:

因为数据文件和进度文件都是生成在程序的某个文件夹file中,所以读取的时候都是读取的文件夹下的文件,从而判断显示进度;

后面才知道,由于后台程序有两台服务器,导致读取以及下载的时候找不到相应的文件夹,两个服务器相应的文件夹弄个共享目录就可以了

七、相应的后续优化

由于下载的文件多了,导致文件夹下的文件越来越多,而原来生成的文件是没有价值的,所以加了个定期删除文件的功能,只保留近七天的文件

当然可以用crontab,只不过我比较懒,是在点击生成文件的时候,判断了一下文件夹中的过期文件,从而删除

1 public functionexecscript_process_show(){2 $this->load->library('smarty');3 $uid = $_REQUEST['uid'];4 $url_dir = STATISTIC_EXPORT_FILE_DIR.$uid .'/';//@todo

5 if(!is_dir($url_dir)){6 @mkdir($url_dir,0777);7 }8 $files = scandir($url_dir);9 if(!empty($files)){10 foreach ($files as $key => $value) {11 if($value!='.' && $value!='..'){12 foreach ($files as $key => $value) {13 if($value!='.' && $value!='..'){14 if(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);18 if($today>$filenamedate){//文件过期

19 @unlink($url_dir . $value);20 @unlink($url_dir . 'flag_' . $value);21 }22 }23 }24 }25 }26 }27 }28

29 $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.net/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

http://www.bkjia.com/PHPjc/1048777.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1048777.htmlTechArticle我所经历的大文件数据导出(后台执行,自动生成),数据导出自动生成 一、前言 记录一下以前做的后台excel格式导出统计信息的功能,也...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值