Heim > Artikel > Backend-Entwicklung > Den Datenexport großer Dateien, den ich erlebt habe (Hintergrundausführung, automatisch generiert)
Der Excel-Export gliedert sich in zwei Teile: Excel-Dateien generieren und Excel-Dateien herunterladen Die Excel-Dateigenerierung wird im Hintergrund des Programms ausgeführt, das Frontend muss nicht warten, andere Hintergrundvorgänge können ausgeführt werden Fügen Sie eine hinzu Seite „Datei herunterladen“, um den Fortschritt der Excel-Dateigenerierung anzuzeigen. Nach Abschluss kann die generierte Excel-Datei heruntergeladen werden Nachdem die Datei generiert wurde, klicken Sie auf „Herunterladen“, um die entsprechende Datei herunterzuladen
<spanmicrosoft yahei><span> 1</span><span>$struserdata</span> = <<<<span>Eof </span><span> 2</span> <html xmlns:o="urn:schemas-microsoft-com:office:office" <span> 3</span> xmlns:x="urn:schemas-microsoft-com:office:excel" <span> 4</span> xmlns="http://www.w3.org/TR/REC-html40"> <span> 5</span><span> 6</span> <!DOCTYPE html <span>PUBLIC</span> "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <span> 7</span> <html> <span> 8</span> <head> <span> 9</span> <meta http-equiv="Content-type" c /> <span>10</span> <style> <span>11</span> </style> <span>12</span> </head> <span>13</span> <body> <span>14</span> <div align=center x:publishsource="Excel"> <span>15</span><span>16</span> <table x:str border=1 cellpadding=0 cellspacing=0 width=100%> <span>17</span> Eof;</spanmicrosoft>
<spanmicrosoft yahei><span>1</span><span>$struserdata</span> = <<<<span>Eof </span><span>2</span> </table> <span>3</span> </div> <span>4</span> </body> <span>5</span> </html> <span>6</span> Eof;</spanmicrosoft>
Szenario:
Der Benutzer klickt nach dem Generieren von Excel auf die Download-Seite. Der Benutzer muss nicht warten, bis die Generierung abgeschlossen ist, und kann andere Vorgänge ausführen Auf der Download-Seite können Sie den Fortschritt der Dateigenerierung und den Download-Status sehen.
Idee:
Klicken Sie hier, um Excel zu generieren und die Download-Seite anzuzeigen - --> show_download-Methode
Excel generieren ---> create_excel-Methode
Die create_excel-Methode wird im show_download aufgerufen Methode, und in der show_download-Methode habe ich die Befehlszeilen-Ausführungsprogrammmethode
Und in der Methode create_excel:
<spanmicrosoft yahei><span>1</span><span>//</span><span> $cmd = "/usr/bin/php /home/xxx/xxx.php " . $strjoin . " >/dev/null & "; </span><span>2</span><span> // $a=exec($cmd, $out, $returndata);</span><span>3</span><span>4</span><span>5</span><span>$command</span> = "/usr/bin/php ".STATISTIC_EXPORT_SCRIPT_DIR."xxx.php " . "'" .<span>$strjoin</span> ."'". " " . <span>$uid</span> . " ". <span>$action</span> ." & "<span>; </span><span>6</span><span>$process</span> = <span>proc_open</span>(<span>$command</span>, <span>array</span>(),<span>$pipes</span><span>); </span><span>7</span><span>$var</span> = <span>proc_get_status</span>(<span>$process</span><span>); </span><span>8</span><span>proc_close</span>(<span>$process</span><span>); </span><span>9</span><span>$pid</span> = <span>intval</span>(<span>$var</span>['pid'])+1;</spanmicrosoft>
Rufen Sie die entsprechende API auf, um die Daten zu erhalten:
<spanmicrosoft yahei><span>1</span><span>set_time_limit</span>(0); <span>//</span><span>取消脚本运行时间的超时上限</span><span>2</span><span>3</span><span>ignore_user_abort</span>(<span>TRUE</span>); <span>//</span><span>后台运行,不受用户关闭浏览器的影响</span></spanmicrosoft>
4. Zeigen Sie den Fortschritt der Dateigenerierung an
<spanmicrosoft yahei><span>1</span><span>$statistic</span> = <span>call_user_func</span>(<span>array</span>('shellscript','get_result'),<span>$url</span>,<span>$params</span><span>); </span><span>2</span><span>if</span>(!<span>is_object</span>(<span>$statistic</span>) || !<span>isset</span>(<span>$statistic</span>->data-><span>items)){ </span><span>3</span><span>usleep</span>(400000);<span>//</span><span>停止400毫秒</span><span>4</span><span>$statistic</span> = <span>call_user_func</span>(<span>array</span>('shellscript','get_result'),<span>$url</span>,<span>$params</span><span>); </span><span>5</span> }</spanmicrosoft>
第一次请求api的时候,根据返回的total总数,以及pagesize,确定要请求的次数count; 这样便可知道要请求api的次数(分页请求api),在写入数据文件的同时,同时写入进度文件flag_data.xsl;
数据格式大约是(以逗号分割)
1,5
2,5
...然后显示文件进度的时候,读取进度文件,这样变可知道数据文件大体的进度 前端js处理时,几秒读取一次相应的方法(如果都100%进度,可停止请求方法),从而实现动态查看文件的生成进度
<spanmicrosoft yahei><span> 1</span><span>public</span><span>function</span><span> execscript_process(){ </span><span> 2</span><span>$this</span>->load->library('smarty'<span>); </span><span> 3</span><span>$file_arr_str</span> = <span>array</span><span>(); </span><span> 4</span><span>$file_arr_process</span> = <span>array</span><span>(); </span><span> 5</span><span>$file_arr_name</span> = <span>array</span><span>(); </span><span> 6</span><span>$file_arr</span> = <span>array</span><span>(); </span><span> 7</span><span>$refresh_flag</span> = 'yes'<span>; </span><span> 8</span><span>$uid</span> = <span>$_REQUEST</span>['uid'<span>]; </span><span> 9</span><span>$url_dir</span> = STATISTIC_EXPORT_FILE_DIR.<span>$uid</span> .'/';<span>//</span><span>@todo</span><span>10</span><span>if</span>(!<span>is_dir</span>(<span>$url_dir</span><span>)){ </span><span>11</span> @<span>mkdir</span>(<span>$url_dir</span>,0777<span>); </span><span>12</span><span> } </span><span>13</span><span>$files</span> = <span>scandir</span>(<span>$url_dir</span><span>); </span><span>14</span><span>15</span><span>if</span>(!<span>empty</span>(<span>$files</span><span>)){ </span><span>16</span><span>foreach</span> (<span>$files</span><span>as</span><span>$key</span> => <span>$value</span><span>) { </span><span>17</span><span>if</span>(<span>$value</span>!='.' && <span>$value</span>!='..'<span>){ </span><span>18</span><span>if</span>(<span>substr</span>(<span>$value</span>, 0 , 5)=="flag_"<span>){ </span><span>19</span><span>$file_size</span> = <span>filesize</span>(<span>$url_dir</span> . <span>$value</span><span>); </span><span>20</span><span>if</span>(!<span>empty</span>(<span>$file_size</span><span>)){ </span><span>21</span><span>$fhandle</span> = <span>fopen</span>(<span>$url_dir</span> . <span>$value</span>, 'rb+'<span>); </span><span>22</span><span>fseek</span>(<span>$fhandle</span>, -1,<span> SEEK_END); </span><span>23</span><span>$fstr</span> = ''<span>; </span><span>24</span><span>while</span>((<span>$c</span> = <span>fgetc</span>(<span>$fhandle</span>)) !== <span>false</span><span>) { </span><span>25</span><span>if</span>(<span>$c</span> == "\n" && <span>$fstr</span>) <span>break</span><span>; </span><span>26</span><span>$fstr</span> = <span>$c</span> . <span>$fstr</span><span>; </span><span>27</span><span>fseek</span>(<span>$fhandle</span>, -2,<span> SEEK_CUR); </span><span>28</span><span> } </span><span>29</span><span>fclose</span>(<span>$fhandle</span><span>); </span><span>30</span><span>$fstr</span> = <span>trim</span>(<span>$fstr</span><span>); </span><span>31</span><span>$fstr_arr_str</span> = <span>explode</span>(',', <span>$fstr</span><span>); </span><span>32</span><span>$file_arr_process</span>[] = 100 * <span>number_format</span>(<span>$fstr_arr_str</span>[0]/<span>$fstr_arr_str</span>[1],2).'%'<span>; </span><span>33</span><span>$file_arr_name</span>[] = <span>substr</span>(<span>$value</span>,5<span>); </span><span>34</span><span> } </span><span>35</span><span> } </span><span>36</span><span> } </span><span>37</span><span> } </span><span>38</span><span>39</span><span>foreach</span> (<span>$file_arr_process</span><span>as</span><span>$key</span> => <span>$value</span><span>) { </span><span>40</span><span>if</span>(<span>$value</span> != '100%'<span>){ </span><span>41</span><span>$refresh_flag</span> = 'no'<span>; </span><span>42</span><span>break</span><span>; </span><span>43</span><span> } </span><span>44</span><span> } </span><span>45</span><span> } </span><span>46</span><span>47</span><span>$file_arr</span> = <span>array</span><span>( </span><span>48</span> 'process' => <span>$file_arr_process</span>, <span>49</span> 'name' => <span>$file_arr_name</span>, <span>50</span> 'refresh_flag' => <span>$refresh_flag</span><span>51</span><span> ); </span><span>52</span><span>$file_arr_json</span> = json_encode(<span>$file_arr</span><span>); </span><span>53</span><span>echo</span><span>$file_arr_json</span><span>; </span><span>54</span> }</spanmicrosoft>
<spanmicrosoft yahei><span> 1</span><span>public</span><span>function</span><span> execscript_download(){ </span><span> 2</span><span>$filename</span> = <span>$_REQUEST</span>['filename'<span>]; </span><span> 3</span><span>$uid</span> = <span>$_REQUEST</span>['uid'<span>]; </span><span> 4</span><span>$file_dir</span> = STATISTIC_EXPORT_FILE_DIR.<span>$uid</span>.'/'.<span>$filename</span><span>; </span><span> 5</span><span>if</span> (!<span>file_exists</span>(<span>$file_dir</span><span>)){ </span><span> 6</span><span>header</span>("Content-type: text/html; charset=utf-8"<span>); </span><span> 7</span><span>echo</span> "File not found!"<span>; </span><span> 8</span><span>exit</span><span>; </span><span> 9</span> } <span>else</span><span> { </span><span>10</span><span>ini_set</span>("memory_limit","500M"<span>); </span><span>11</span><span>header</span>('Content-Description: File Transfer'<span>); </span><span>12</span><span>header</span>('Content-Type: application/octet-stream'<span>); </span><span>13</span><span>header</span>('Content-Disposition: attachment; filename='.<span>basename</span>(<span>$file_dir</span><span>)); </span><span>14</span><span>header</span>('Content-Transfer-Encoding: binary'<span>); </span><span>15</span><span>header</span>('Expires: ' . <span>gmdate</span>('D, d M Y H:i:s') . ' GMT'<span>); </span><span>16</span><span>header</span>('Cache-Control: must-revalidate,post-check=0, pre-check=0'<span>); </span><span>17</span><span>header</span>('Pragma: public'<span>); </span><span>18</span><span>header</span>('Content-Length: ' . <span>filesize</span>(<span>$file_dir</span><span>)); </span><span>19</span><span>readfile</span>(<span>$file_dir</span><span>); </span><span>20</span><span> } </span><span>21</span><span>22</span> }</spanmicrosoft>
现象描述:
当在后台点击生成文件,跳转到下载页的时候,因为下载页是显示文件进度的页面, 竟然出现有时候有刚刚点击的文件进度,有时候没有,就感觉没有生成相应的文件一样;
解决方法:
因为数据文件和进度文件都是生成在程序的某个文件夹file中,所以读取的时候都是读取的文件夹下的文件,从而判断显示进度;
后面才知道,由于后台程序有两台服务器,导致读取以及下载的时候找不到相应的文件夹,两个服务器相应的文件夹弄个共享目录就可以了
<spanmicrosoft yahei><span> 1</span><span>public</span><span>function</span><span> execscript_process_show(){ </span><span> 2</span><span>$this</span>->load->library('smarty'<span>); </span><span> 3</span><span>$uid</span> = <span>$_REQUEST</span>['uid'<span>]; </span><span> 4</span><span>$url_dir</span> = STATISTIC_EXPORT_FILE_DIR.<span>$uid</span> .'/';<span>//</span><span>@todo</span><span> 5</span><span>if</span>(!<span>is_dir</span>(<span>$url_dir</span><span>)){ </span><span> 6</span> @<span>mkdir</span>(<span>$url_dir</span>,0777<span>); </span><span> 7</span><span> } </span><span> 8</span><span>$files</span> = <span>scandir</span>(<span>$url_dir</span><span>); </span><span> 9</span><span>if</span>(!<span>empty</span>(<span>$files</span><span>)){ </span><span>10</span><span>foreach</span> (<span>$files</span><span>as</span><span>$key</span> => <span>$value</span><span>) { </span><span>11</span><span>if</span>(<span>$value</span>!='.' && <span>$value</span>!='..'<span>){ </span><span>12</span><span>foreach</span> (<span>$files</span><span>as</span><span>$key</span> => <span>$value</span><span>) { </span><span>13</span><span>if</span>(<span>$value</span>!='.' && <span>$value</span>!='..'<span>){ </span><span>14</span><span>if</span>(<span>substr</span>(<span>$value</span>, 0 , 5)!="flag_"<span>){ </span><span>15</span><span>$filenamedate</span> = <span>substr</span>(<span>$value</span>, 0,10<span>); </span><span>16</span><span>$today</span> = <span>date</span>('Y-m-d',<span>time</span><span>()); </span><span>17</span><span>$filenamedate</span> = <span>date</span>('Y-m-d',<span>strtotime</span>(<span>$filenamedate</span>)+(STATISTIC_FILE_EXPIRE_DAY-1)*24*3600<span>); </span><span>18</span><span>if</span>(<span>$today</span>><span>$filenamedate</span>){<span>//</span><span>文件过期</span><span>19</span> @<span>unlink</span>(<span>$url_dir</span> . <span>$value</span><span>); </span><span>20</span> @<span>unlink</span>(<span>$url_dir</span> . 'flag_' . <span>$value</span><span>); </span><span>21</span><span> } </span><span>22</span><span> } </span><span>23</span><span> } </span><span>24</span><span> } </span><span>25</span><span> } </span><span>26</span><span> } </span><span>27</span><span> } </span><span>28</span><span>29</span><span>$this</span>->smarty->assign('uid',<span>$uid</span><span>); </span><span>30</span><span>$this</span>->smarty->display('interact/statistic/execscript.tpl'<span>); </span><span>31</span> }</spanmicrosoft>
<spanmicrosoft yahei>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</spanmicrosoft>
以上就介绍了我所经历的大文件数据导出(后台执行,自动生成),包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。