我所经历的大文件数据导出(后台执行,自动生成),数据导出自动生成
一、前言
记录一下以前做的后台excel格式导出统计信息的功能,也是最近同事问到了相关东西,一时之间竟忘了具体的细节,因此记录一下;
大家知道,excel导出数据的功能,后台几乎是必须功能,一般都是点击后,生成文件然后自动下载,
如果是数据量小的话,一下子便可请求完成,从而下载到本地;
但是,如果数据量特别大的时候,页面就必须一直在等待,直到写入excel成功,
这样便影响了后台使用者无法操作其他页面,为此,对excel导出做了以下功能优化:
二、生成excel文件
生成excel文件的方法有很多,暂不一一记录,只是记录本次的方法;
这里用到了table的html格式,以及相应的excel的声明
(隐约记得其他的方法用office07打开的时候好像是乱码,后面尝试用csv格式文件,可还是乱码,所以用了table的形式)
文件的开头:

当然,文件中间就是一些tr td 标签了。
三、让程序在后台执行
<p><span> 场景:</span></p> <p><span> 用户点击 生成excel后,跳转到下载页面,程序在后台执行,用户可不必等待生成完成,可执行其他操作;</span></p> <p><span> 下载页面可看到文件生成的进度以及是否可下载状态</span></p> <p><span> 思路:</span></p> <p><span> 点击 生成excel,显示下载页面 ---> show_download方法</span></p> <p><span> 生成excel ---> create_excel 方法</span></p>
show_download方法中调用 create_excel方法,而show_download 方法中,自己用了一下命令行执行程序的方式,
利用php命令行的方式,把参数传递给 create_excel方法
<span><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;</span>
而在create_excel方法中:
需填写以下代码:
<span><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></span>
调用相关的api得到数据:
<span><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> }</span>
四、显示文件生成进度
但是怎么显示相应的文件生成进度呢,怎么知道文件到底生成好了没有呢?
这里,我用到的方法是,在写入数据文件的时候data.xsl,每个数据文件都生成一个对应的文件进度文件,暂且称为flag_data.xsl;
思路:
查看文件的进度方法:

五、下载文件
文件的下载就好说了,既然已经都生成成功,下载的方法如下:
<span><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> }</span>
六、上线后出现的问题
本地本来已经测试完毕,可上线后,却出现了奇怪的问题;
<p><span> 现象描述:</span></p> <p><span> 当在后台点击生成文件,跳转到下载页的时候,因为下载页是显示文件进度的页面,</span><br /><span> 竟然出现有时候有刚刚点击的文件进度,有时候没有,就感觉没有生成相应的文件一样;</span></p> <p><span> 解决方法:</span></p> <p><span> 因为数据文件和进度文件都是生成在程序的某个文件夹file中,所以读取的时候都是读取的文件夹下的文件,从而判断显示进度;</span></p> <p><span> 后面才知道,由于后台程序有两台服务器,导致读取以及下载的时候找不到相应的文件夹,两个服务器相应的文件夹弄个共享目录就可以了</span></p>
七、相应的后续优化
由于下载的文件多了,导致文件夹下的文件越来越多,而原来生成的文件是没有价值的,所以加了个定期删除文件的功能,只保留近七天的文件
当然可以用crontab,只不过我比较懒,是在点击生成文件的时候,判断了一下文件夹中的过期文件,从而删除
<span><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> }</span>
八、后记
大文件的导出大体就是这个样子,欢迎大家吐槽,共同交流;
当时在用命令行执行方法的时候,也参考了一下相应的资料,记录一下;
<span>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</span>

PHPは動的なWebサイトを構築するために使用され、そのコア関数には次のものが含まれます。1。データベースに接続することにより、動的コンテンツを生成し、リアルタイムでWebページを生成します。 2。ユーザーのインタラクションを処理し、提出をフォームし、入力を確認し、操作に応答します。 3.セッションとユーザー認証を管理して、パーソナライズされたエクスペリエンスを提供します。 4.パフォーマンスを最適化し、ベストプラクティスに従って、ウェブサイトの効率とセキュリティを改善します。

PHPはMySQLIおよびPDO拡張機能を使用して、データベース操作とサーバー側のロジック処理で対話し、セッション管理などの関数を介してサーバー側のロジックを処理します。 1)MySQLIまたはPDOを使用してデータベースに接続し、SQLクエリを実行します。 2)セッション管理およびその他の機能を通じて、HTTPリクエストとユーザーステータスを処理します。 3)トランザクションを使用して、データベース操作の原子性を確保します。 4)SQLインジェクションを防ぎ、例外処理とデバッグの閉鎖接続を使用します。 5)インデックスとキャッシュを通じてパフォーマンスを最適化し、読みやすいコードを書き、エラー処理を実行します。

PHPで前処理ステートメントとPDOを使用すると、SQL注入攻撃を効果的に防ぐことができます。 1)PDOを使用してデータベースに接続し、エラーモードを設定します。 2)準備方法を使用して前処理ステートメントを作成し、プレースホルダーを使用してデータを渡し、メソッドを実行します。 3)結果のクエリを処理し、コードのセキュリティとパフォーマンスを確保します。

PHPとPythonには独自の利点と短所があり、選択はプロジェクトのニーズと個人的な好みに依存します。 1.PHPは、大規模なWebアプリケーションの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンスと機械学習の分野を支配しています。

PHPは、電子商取引、コンテンツ管理システム、API開発で広く使用されています。 1)eコマース:ショッピングカート機能と支払い処理に使用。 2)コンテンツ管理システム:動的コンテンツの生成とユーザー管理に使用されます。 3)API開発:RESTFUL API開発とAPIセキュリティに使用されます。パフォーマンスの最適化とベストプラクティスを通じて、PHPアプリケーションの効率と保守性が向上します。

PHPにより、インタラクティブなWebコンテンツを簡単に作成できます。 1)HTMLを埋め込んでコンテンツを動的に生成し、ユーザー入力またはデータベースデータに基づいてリアルタイムで表示します。 2)プロセスフォームの提出と動的出力を生成して、XSSを防ぐためにHTMLSPECIALCHARSを使用していることを確認します。 3)MySQLを使用してユーザー登録システムを作成し、Password_HashおよびPreprocessingステートメントを使用してセキュリティを強化します。これらの手法を習得すると、Web開発の効率が向上します。

PHPとPythonにはそれぞれ独自の利点があり、プロジェクトの要件に従って選択します。 1.PHPは、特にWebサイトの迅速な開発とメンテナンスに適しています。 2。Pythonは、データサイエンス、機械学習、人工知能に適しており、簡潔な構文を備えており、初心者に適しています。

PHPは依然として動的であり、現代のプログラミングの分野で重要な位置を占めています。 1)PHPのシンプルさと強力なコミュニティサポートにより、Web開発で広く使用されています。 2)その柔軟性と安定性により、Webフォーム、データベース操作、ファイル処理の処理において顕著になります。 3)PHPは、初心者や経験豊富な開発者に適した、常に進化し、最適化しています。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

ドリームウィーバー CS6
ビジュアル Web 開発ツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません
